--- /dev/null
+from django.conf import settings
+from blog.models import BlogEntry, BlogSection
+import re
+
+def content_breadcrumb(request):
+ path = request.path
+ if path[0:len(settings.BLOG_ROOT)] == settings.BLOG_ROOT:
+ breadcrumb = [{'url': u'/', 'title': u'/'}, {'url': settings.BLOG_ROOT, 'title': u'blog'},]
+
+ path = path[len(settings.BLOG_ROOT):]
+
+ parts = path.split('/')
+
+ if parts[0] == "section":
+ # Just need to add the section title to the breadcrumb
+ section = BlogSection.objects.get(slug__exact=parts[1])
+ breadcrumb.append({'url': section.get_absolute_url(), 'title': section.title})
+
+ if len(parts) == 5 and \
+ parts[0].isdigit() and \
+ parts[1].isdigit() and \
+ parts[2].isdigit():
+ # try getting the blog entry
+ try:
+ entry = BlogEntry.objects.get(publish_date__year=int(parts[0]), publish_date__month=int(parts[1]), publish_date__day=int(parts[2]), slug__exact=parts[3])
+ breadcrumb.append({'url': entry.get_absolute_url(), 'title': entry.title})
+ except:
+ breadcrumb.append({'url': 'nowhere', 'title': 'screwed'})
+ pass
+
+ return {
+ 'content_breadcrumb': breadcrumb,
+ }
+ else:
+ return {}
--- /dev/null
+from django.contrib.syndication.feeds import Feed
+from django.utils.feedgenerator import Atom1Feed
+from blog.models import BlogEntry
+from django.conf import settings
+
+class LatestBlogEntries(Feed):
+ feed_type = Atom1Feed
+ title = settings.BLOG_TITLE
+ description = u'Updates on %s' %(title,)
+ link = settings.BLOG_ROOT
+
+ title_template = 'blog/feeds/title.html'
+ description_template = 'blog/feeds/description.html'
+
+ def items(self):
+ try:
+ return BlogEntry.objects.all().order_by('-publish_date')[:20]
+ except:
+ return BlogEntry.objects.all().order_by('-publish_date')
+
+ def item_pubdate(self, obj):
+ return obj.publish_date
--- /dev/null
+from django.db import models
+from django.conf import settings
+
+FORMAT_CHOICES = (
+ ('rst', 'reStructuredText'),
+ ('html', 'HTML'),
+)
+
+class BlogEntry(models.Model):
+ title = models.CharField(maxlength=150)
+ islive = models.BooleanField()
+ sections = models.ManyToManyField('BlogSection')
+ format = models.CharField(maxlength=10, choices=FORMAT_CHOICES)
+ slug = models.SlugField(prepopulate_from=("title",))
+ publish_date = models.DateTimeField()
+ content = models.TextField()
+
+ def __str__(self):
+ return self.__unicode__()
+
+ def __unicode__(self):
+ return u'%s - %s' %(self.publish_date.strftime('%Y-%m-%d %H:%M'), self.title)
+
+ def get_absolute_url(self):
+ return u'%s%04d/%02d/%02d/%s/' %(settings.BLOG_ROOT, self.publish_date.year, self.publish_date.month, self.publish_date.day, self.slug)
+
+ class Admin:
+ pass
+
+class BlogSection(models.Model):
+ title = models.CharField(maxlength=150)
+ slug = models.SlugField(prepopulate_from=("title",))
+
+ def __str__(self):
+ return self.__unicode__()
+
+ def __unicode__(self):
+ return u'%s' %(self.title,)
+
+ def get_absolute_url(self):
+ return u'%ssection/%s/' %(settings.BLOG_ROOT, self.slug)
+
+ class Admin:
+ pass
--- /dev/null
+{% extends "base.html" %}
+{% load markup %}
+
+{% block content %}
+ {% if entries %}
+ {% for entry in entries %}
+ <h1>{{ entry.title|escape }}</h1>
+ {{ entry.content|restructuredtext }}
+ <p>Posted: {{ entry.publish_date|date:"Y-m-d H:i" }} in
+ {% for section in entry.sections.all %}
+ {% if forloop.first %}
+ <a href="{{ section.get_absolute_url }}">{{ section.title }}</a>{% if not forloop.last %}, {% endif %}
+ {% else %}
+ {% if forloop.last %}
+ and <a href="{{ section.get_absolute_url }}">{{ section.title }}</a>
+ {% else %}
+ <a href="{{ section.get_abolute_url }}">{{ section.title }}</a>
+ {% endif %}
+ {% endif %}
+ {% endfor %}
+ <a href="{{ entry.get_absolute_url }}">permalink</a></p>
+ {% endfor %}
+ {% if paginated %}
+ <p class="paginator">Pages:
+ {% if has_prev %}
+ <a href="?page={{ prev }}">Previous</a> |
+ {% endif %}
+ {% for paginator_page in pages %}
+ {% if forloop.first %}
+ {% else %}
+ |
+ {% endif %}
+ {% ifequal paginator_page page %}
+ {{ page }}
+ {% else %}
+ <a href="?page={{ paginator_page }}">{{ paginator_page }}</a>
+ {% endifequal %}
+ {% endfor %}
+ {% if has_next %}
+ | <a href="?page={{ next }}">Next</a>
+ {% endif %}
+ {% endif %}
+ {% else %}
+ <p>We have no blog entries - that sucks!</p>
+ {% endif %}
+{% endblock %}
--- /dev/null
+{% load markup %}
+
+{{ obj.content|restructuredtext }}
--- /dev/null
+{{ obj.title }}
--- /dev/null
+{% extends "base.html" %}
+
+{% load markup %}
+
+{% block content %}
+<h1>{{ title }}</h1>
+{{ content|restructuredtext }}
+{% endblock %}
--- /dev/null
+from django.conf.urls.defaults import *
+from settings import MEDIA_ROOT, MEDIA_URL
+
+urlpatterns = patterns('',
+ (r'^(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/(?P<slug>[^/]+)(/|)$', 'blog.views.blog_view'),
+ (r'^(?P<year>[0-9]{4})(?P<month>[0-9]{2})(?P<day>[0-9]{2})-(?P<slug>[^/]+)\.html$', 'blog.views.blog_view'),
+ (r'^(?P<year>[0-9]{4})(?P<month>[0-9]{2})(?P<day>[0-9]{2})(?P<hour>[0-9]{2})(?P<minutes>[0-9]{2})-(?P<slug>[^/]+)\.html$', 'blog.views.blog_view'),
+ (r'^section/(?P<section>[^/]*)/$', 'blog.views.blog_index'),
+ (r'^$', 'blog.views.blog_index'),
+)
--- /dev/null
+from blog.models import BlogEntry, BlogSection
+from django.http import Http404, HttpResponse
+from django.template import RequestContext, loader
+from django.core.paginator import ObjectPaginator
+from django.conf import settings
+
+def blog_index(request, section=None):
+ entries = BlogEntry.objects.all()
+ if section:
+ entries = entries.filter(sections__slug__exact=section)
+ entries = entries.order_by('-publish_date')
+ if entries:
+ paginate_by=20
+ paginator = ObjectPaginator(entries, paginate_by)
+ page = int(request.GET.get('page', 0))
+ if page > 0:
+ page = page - 1
+ paginated_entries = paginator.get_page(page)
+ pages = [i for i in range(1, paginator.pages + 1)]
+ t = loader.get_template("blog/blog_index.html")
+ c = RequestContext(request,
+ {
+ "entries": paginated_entries,
+ "title": settings.BLOG_TITLE,
+ "page": page + 1,
+ "pages": pages,
+ "paginated": 1,
+ "has_next": paginator.has_next_page(page),
+ "has_prev": paginator.has_next_page(page),
+ "next": page + 2,
+ "prev": page - 1
+ })
+ return HttpResponse(t.render(c))
+ else:
+ raise Http404
+
+def blog_view(request, year=None, month=None, day=None, hour=None, minutes=None, section=None, slug=None):
+ # work out what we've got roughly
+ if year and month and day and slug:
+ # exact blog entry (woo!)
+ year = int(year)
+ month = int(month)
+ day = int(day)
+ blog_entry = BlogEntry.objects.get(publish_date__year=year, publish_date__month=month, publish_date__day=day, slug__exact=slug)
+ template_name = "blog/single_entry_%s.html" %(blog_entry.format,)
+ t = loader.get_template(template_name)
+ c = RequestContext(request,
+ {
+ "content": blog_entry.content,
+ "title": blog_entry.title,
+ "publish_date": blog_entry.publish_date
+ }
+ )
+ return HttpResponse(t.render(c))
'django.contrib.markup',
'bpcms',
'generic',
+ 'blog',
)
TEMPLATE_CONTEXT_PROCESSORS = (
'bpcms.context_processors.content_menu',
'bpcms.context_processors.content_submenu',
'bpcms.context_processors.content_breadcrumb',
+ 'blog.context_processors.content_breadcrumb',
)
+APPEND_SLASH=False
+
BPCMS_ROOT = '/'
BPCMS_DISALLOWED_ROOT_DOC_NAMES = (
'admin',
'blog',
'photos',
)
+
+BLOG_ROOT = '/blog/'
+BLOG_TITLE = u'The World of SommitRealWeird.'
from django.conf.urls.defaults import *
from settings import MEDIA_ROOT, MEDIA_URL
+from blog.feeds import LatestBlogEntries
handler404 = 'generic.views.render_404'
+feeds_dict = {
+ 'blog': LatestBlogEntries,
+ }
+
urlpatterns = patterns('',
# Example:
# (r'^sommitrealweird/', include('sommitrealweird.foo.urls')),
# Uncomment this for admin:
(r'^$', 'bpcms.views.document_view', {'slug': 'index'}),
+ (r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': MEDIA_ROOT, 'show_indexes': True}),
(r'^admin/', include('django.contrib.admin.urls')),
+ (r'^blog/', include('blog.urls')),
+ (r'^feeds/(?P<url>.*)/', 'django.contrib.syndication.views.feed', {'feed_dict': feeds_dict}),
(r'^(?:content/|)(?P<slug>[^/]+)/$', 'bpcms.views.document_view'),
(r'^(?:content/|)(?P<folders>.*)/(?P<slug>[^/]+)/$', 'bpcms.views.document_view'),
- (r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': MEDIA_ROOT, 'show_indexes': True}),
)
<li><a href="{{ item.url }}">{{ item.title }}</a></li>
{% endfor %}
<li>Photos</li>
- <li>Blog</li>
+ <li><a href="/blog/">Blog</a></li>
</ul>
{% endblock %}
</div>