From: Brett Parker Date: Mon, 11 Feb 2008 02:26:04 +0000 (+0000) Subject: Add basic blogging support X-Git-Url: https://git.sommitrealweird.co.uk/sommitrealweird.git/commitdiff_plain/bb8272178c6c35fcb92bc5a08342faf40d3fab1b?ds=sidebyside;hp=-c Add basic blogging support --- bb8272178c6c35fcb92bc5a08342faf40d3fab1b diff --git a/sommitrealweird/blog/__init__.py b/sommitrealweird/blog/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/sommitrealweird/blog/context_processors.py b/sommitrealweird/blog/context_processors.py new file mode 100644 index 0000000..14a9216 --- /dev/null +++ b/sommitrealweird/blog/context_processors.py @@ -0,0 +1,35 @@ +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 {} diff --git a/sommitrealweird/blog/feeds.py b/sommitrealweird/blog/feeds.py new file mode 100644 index 0000000..d08456f --- /dev/null +++ b/sommitrealweird/blog/feeds.py @@ -0,0 +1,22 @@ +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 diff --git a/sommitrealweird/blog/models.py b/sommitrealweird/blog/models.py new file mode 100644 index 0000000..6b0d254 --- /dev/null +++ b/sommitrealweird/blog/models.py @@ -0,0 +1,44 @@ +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 diff --git a/sommitrealweird/blog/templates/blog/blog_index.html b/sommitrealweird/blog/templates/blog/blog_index.html new file mode 100644 index 0000000..8e94748 --- /dev/null +++ b/sommitrealweird/blog/templates/blog/blog_index.html @@ -0,0 +1,46 @@ +{% extends "base.html" %} +{% load markup %} + +{% block content %} + {% if entries %} + {% for entry in entries %} +

{{ entry.title|escape }}

+ {{ entry.content|restructuredtext }} +

Posted: {{ entry.publish_date|date:"Y-m-d H:i" }} in + {% for section in entry.sections.all %} + {% if forloop.first %} + {{ section.title }}{% if not forloop.last %}, {% endif %} + {% else %} + {% if forloop.last %} + and {{ section.title }} + {% else %} + {{ section.title }} + {% endif %} + {% endif %} + {% endfor %} + permalink

+ {% endfor %} + {% if paginated %} +

Pages: + {% if has_prev %} + Previous | + {% endif %} + {% for paginator_page in pages %} + {% if forloop.first %} + {% else %} + | + {% endif %} + {% ifequal paginator_page page %} + {{ page }} + {% else %} + {{ paginator_page }} + {% endifequal %} + {% endfor %} + {% if has_next %} + | Next + {% endif %} + {% endif %} + {% else %} +

We have no blog entries - that sucks!

+ {% endif %} +{% endblock %} diff --git a/sommitrealweird/blog/templates/blog/feeds/description.html b/sommitrealweird/blog/templates/blog/feeds/description.html new file mode 100644 index 0000000..d16eb9b --- /dev/null +++ b/sommitrealweird/blog/templates/blog/feeds/description.html @@ -0,0 +1,3 @@ +{% load markup %} + +{{ obj.content|restructuredtext }} diff --git a/sommitrealweird/blog/templates/blog/feeds/title.html b/sommitrealweird/blog/templates/blog/feeds/title.html new file mode 100644 index 0000000..d355de5 --- /dev/null +++ b/sommitrealweird/blog/templates/blog/feeds/title.html @@ -0,0 +1 @@ +{{ obj.title }} diff --git a/sommitrealweird/blog/templates/blog/single_entry_rst.html b/sommitrealweird/blog/templates/blog/single_entry_rst.html new file mode 100644 index 0000000..5681e14 --- /dev/null +++ b/sommitrealweird/blog/templates/blog/single_entry_rst.html @@ -0,0 +1,8 @@ +{% extends "base.html" %} + +{% load markup %} + +{% block content %} +

{{ title }}

+{{ content|restructuredtext }} +{% endblock %} diff --git a/sommitrealweird/blog/urls.py b/sommitrealweird/blog/urls.py new file mode 100644 index 0000000..f41ed25 --- /dev/null +++ b/sommitrealweird/blog/urls.py @@ -0,0 +1,10 @@ +from django.conf.urls.defaults import * +from settings import MEDIA_ROOT, MEDIA_URL + +urlpatterns = patterns('', + (r'^(?P[0-9]{4})/(?P[0-9]{2})/(?P[0-9]{2})/(?P[^/]+)(/|)$', 'blog.views.blog_view'), + (r'^(?P[0-9]{4})(?P[0-9]{2})(?P[0-9]{2})-(?P[^/]+)\.html$', 'blog.views.blog_view'), + (r'^(?P[0-9]{4})(?P[0-9]{2})(?P[0-9]{2})(?P[0-9]{2})(?P[0-9]{2})-(?P[^/]+)\.html$', 'blog.views.blog_view'), + (r'^section/(?P
[^/]*)/$', 'blog.views.blog_index'), + (r'^$', 'blog.views.blog_index'), +) diff --git a/sommitrealweird/blog/views.py b/sommitrealweird/blog/views.py new file mode 100644 index 0000000..a801cd4 --- /dev/null +++ b/sommitrealweird/blog/views.py @@ -0,0 +1,54 @@ +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)) diff --git a/sommitrealweird/settings.py b/sommitrealweird/settings.py index e198e9b..959a279 100644 --- a/sommitrealweird/settings.py +++ b/sommitrealweird/settings.py @@ -83,6 +83,7 @@ INSTALLED_APPS = ( 'django.contrib.markup', 'bpcms', 'generic', + 'blog', ) TEMPLATE_CONTEXT_PROCESSORS = ( @@ -93,11 +94,17 @@ 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.' diff --git a/sommitrealweird/urls.py b/sommitrealweird/urls.py index 39adc87..b709acc 100644 --- a/sommitrealweird/urls.py +++ b/sommitrealweird/urls.py @@ -1,16 +1,23 @@ 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.*)$', '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.*)/', 'django.contrib.syndication.views.feed', {'feed_dict': feeds_dict}), (r'^(?:content/|)(?P[^/]+)/$', 'bpcms.views.document_view'), (r'^(?:content/|)(?P.*)/(?P[^/]+)/$', 'bpcms.views.document_view'), - (r'^media/(?P.*)$', 'django.views.static.serve', {'document_root': MEDIA_ROOT, 'show_indexes': True}), ) diff --git a/templates/base.html b/templates/base.html index ebd630e..430b8c6 100644 --- a/templates/base.html +++ b/templates/base.html @@ -19,7 +19,7 @@
  • {{ item.title }}
  • {% endfor %}
  • Photos
  • -
  • Blog
  • +
  • Blog
  • {% endblock %}