Added blog/ implementation based on Zinnia

This commit is contained in:
Alexandre `Zopieux` Macabies 2013-09-16 00:10:09 +02:00
parent dc131b901d
commit 17d3694d27
22 changed files with 777 additions and 0 deletions

0
dolweb/blog/__init__.py Normal file
View File

28
dolweb/blog/admin.py Normal file
View File

@ -0,0 +1,28 @@
from django.contrib import admin
from django.utils.translation import ugettext_lazy as _
from zinnia.models.entry import Entry
from zinnia.admin.entry import EntryAdmin
from dolweb.blog.models import BlogSerie, ForumThreadForEntry
class BlogSerieAdmin(admin.ModelAdmin):
pass
class ForumThreadForEntryAdmin(admin.ModelAdmin):
pass
class BlogEntryAdmin(EntryAdmin):
# In our case we put the gallery field
# into the 'Content' fieldset
fieldsets = ((_('Content'), {'fields': (
'title', 'content', 'image', 'status', 'within_serie')}),) + \
EntryAdmin.fieldsets[1:]
# Unregister the default EntryAdmin
admin.site.unregister(Entry)
# then register our own
admin.site.register(Entry, BlogEntryAdmin)
admin.site.register(BlogSerie, BlogSerieAdmin)
admin.site.register(ForumThreadForEntry, ForumThreadForEntryAdmin)

View File

@ -0,0 +1,55 @@
from django.db import models
from zinnia.models.entry import EntryAbstractClass
from django.utils.translation import ugettext as _
from models import BlogSerie
# Why this file?
# "Do not put your abstract model in a file named models.py, it will not work
# for a non obvious reason."
# http://django-blog-zinnia.readthedocs.org/en/v0.12.3/how-to/extending_entry_model.html#writing-model-extension
class BlogEntry(EntryAbstractClass):
"""
Represents a blog entry. Adds an optional `serie` field to the default
Zinnia model.
"""
within_serie = models.ForeignKey(BlogSerie, null=True, blank=True, related_name='entries')
@property
def real_image(self):
"""Priorities the entry image, then the serie image, if any."""
if self.entry_image is not None:
return self.entry_image
if self.within_serie is not None:
# May be None!
return self.within_serie.image
@property
def serie_index(self):
if self.within_serie is None:
return 1
return (self.within_serie.entries
.filter(creation_date__lt=self.creation_date)
.exclude(pk=self.pk)
.count()) + 1
def relative_entry_in_serie(self, offset):
if self.within_serie is None:
return None
return self.within_serie.nth_entry(self.serie_index + offset)
@property
def next_entry_in_serie(self):
return self.relative_entry_in_serie(1)
@property
def previous_entry_in_serie(self):
return self.relative_entry_in_serie(-1)
class Meta(EntryAbstractClass.Meta):
abstract = True

View File

57
dolweb/blog/models.py Normal file
View File

@ -0,0 +1,57 @@
from django.conf import settings
from django.db import models
from django.utils.translation import ugettext as _
from zinnia.settings import UPLOAD_TO
from zinnia.managers import PUBLISHED
# from zinnia.models.entry import Entry
class BlogSerie(models.Model):
"""Represents a date-ordered sequence of blog entries."""
name = models.CharField(max_length=255, db_index=True)
visible = models.BooleanField(default=True)
image = models.ImageField(
_('image'), blank=True, upload_to=UPLOAD_TO,
help_text=_('Used for illustration.'))
@property
def entries_reversed(self):
return self.entries.order_by('creation_date')
def nth_entry(self, nth, allow_hidden=False):
"""Returns the 1-indexed nth article in serie."""
if nth < 1:
return None
qs = self.entries.all()
if not allow_hidden:
qs = qs.filter(status=PUBLISHED)
try:
return qs.order_by('creation_date')[nth - 1]
except IndexError:
return None
def __unicode__(self):
return self.name
def __repr__(self):
return '<BlogSerie "%s" (%d entries)>' % (self.name, self.entries.count())
class ForumThreadForEntry(models.Model):
entry = models.OneToOneField('zinnia.Entry', related_name='forum_thread')
thread_id = models.IntegerField()
def get_absolute_url(self):
return settings.FORUM_URL_FOR_THREAD.format(id=self.thread_id)
def __unicode__(self):
return "%s -> %s" % (self.entry, self.get_absolute_url())
def __repr__(self):
return "<ForumThreadForEntry %s -> thread %d>" % (
self.entry, self.thread_id
)

22
dolweb/blog/signals.py Normal file
View File

@ -0,0 +1,22 @@
from django.db.models.signals import post_save
from zinnia.models import Entry
from zinnia.managers import PUBLISHED
from dolweb.blog.models import ForumThreadForEntry
def create_dolphin_forum_thread(sender, instance, **kwargs):
if instance.status != PUBLISHED:
return
thread, created = ForumThreadForEntry.objects.get_or_create(entry=instance)
if not created:
return
# TODO: call MyBB script to get thread ID
# forum_thread_id = get_shit_done(instance)
forum_thread_id = 1337
thread.thread_id = forum_thread_id
thread.save()
post_save.connect(create_dolphin_forum_thread, sender=Entry)

View File

@ -0,0 +1,6 @@
{% load url from future %}
<ul class="blog-series">
{% for serie in series %}
<li><a href="{% url 'dolweb.blog.views.serie_view' uid=serie.pk %}">{{ serie.name }}</a></li>
{% endfor %}
</ul>

View File

@ -0,0 +1,25 @@
{% load i18n zinnia_tags blog_tags %}
{% load url from future %}
<div style="margin-bottom: 1em">
<form method="get" action="{% url 'zinnia_entry_search' %}" role="search">
<div class="input-group">
<input type="text" placeholder="{% trans "Search articles" %}" name="pattern" class="form-control" />
<span class="input-group-btn">
<button type="submit" class="btn">
<i class="icon-search"></i>
</button>
</span>
</div>
</form>
</div>
<div class="well">
<h4>{% trans "Blog tags" %}</h4>
{% get_tag_cloud %}
</div>
<div class="well">
<h4>{% trans "Blog series" %} <a href="#" title="RSS feed"><i class="icon-rss"></i></h4>
{% get_blog_series 3 %}
<p class="seemore"><a href="{% url 'dolweb.blog.views.series_index' %}">{% trans "See all" %} »</a></p>
</div>

View File

View File

@ -0,0 +1,32 @@
{% extends "zinnia/base.html" %}
{% load i18n comments zinnia_tags %}
{% load url from future %}
{% block "title" %}Blog series{% endblock %}
{% block "metadescr" %}List of blog series{% endblock %}
{% block content %}
{% for serie in page_obj.object_list %}
<div class="well clearfix">
{% if serie.image %}<img src="{{ serie.image.url }}" alt="Serie illustration" class="pull-left thumbnail" />{% endif %}
<h2><a href="{% url 'dolweb.blog.views.serie_view' uid=serie.pk %}">{{ serie.name }}</a>
<small>{% blocktrans count count=serie.entries.count %}
{{ count }} entrie
{% plural %}
{{ count }} entries
{% endblocktrans %}</small></h2>
<ol>
{% for entry in serie.entries_reversed %}
<li><a href="{{ entry.get_absolute_url }}">{{ entry.title }}</a></li>
{% endfor %}
</ol>
</div>
{% empty %}
<p>{% trans "No blog series yet."}</p>
{% endfor %}
{% endblock %}

View File

@ -0,0 +1 @@
{% extends "_base.html" %}

View File

@ -0,0 +1 @@
{% extends "zinnia/_entry_detail_base.html" %}

View File

@ -0,0 +1,170 @@
{% load comments i18n %}
{% load url from future %}
<div id="entry-{{ object.pk }}" class="hentry{% if object.featured %} featured{% endif %}">
{% block entry-header %}
<div class="entry-header">
{% block entry-title %}
<h2 class="entry-title">
<a href="{{ object.get_absolute_url }}" title="{{ object.title }}" rel="bookmark">
{{ object.title }}
</a>
</h2>
{% endblock %}
{% block entry-info %}
<div class="entry-meta-line">
<p class="entry-info">
{% with authors=object.authors.all %}
{% if authors|length %}
{% trans "Written by" %}
{% for author in authors %}
<span class="vcard author">
<a href="{{ author.get_absolute_url }}" class="fn url{% if not author.get_full_name %} nickname{% endif %}" rel="author"
title="{% blocktrans %}Show all {{ author }}'s entries{% endblocktrans %}">{{ author }}</a></span>{% if not forloop.last %}, {% endif %}
{% endfor %}
{% trans "on" %}
{% else %}
{% trans "Written on" %}
{% endif %}
{% endwith %}
<abbr class="published" title="{{ object.creation_date|date:"c" }}">{{ object.creation_date|date:"DATE_FORMAT" }}</abbr>
</p>
{% endblock %}
{% block entry-last-update %}
<p class="entry-last-update">
/ {% trans "Last update on" %} <abbr class="updated" title="{{ object.last_update|date:"c" }}">{{ object.last_update|date:"DATE_FORMAT" }}</abbr>
/ <a href="{{ object.short_url }}"
title="{% blocktrans with object=object.title %}Short URL to {{ object }}{% endblocktrans %}"
rel="shortlink">{% trans "Short link" %}</a>
/ <i class="icon-comments"></i> <a href="{{ object.forum_thread.get_absolute_url }}" title="Visit forum thread for this article">Forum thread</a>
</p>
</div>
{% endblock %}
</div>
{% endblock %}
{% block entry-body %}
<div class="entry-body">
{% block entry-image %}
{% if object.real_image %}
<div class="entry-image">
<p>
{% if continue_reading %}
<a href="{{ object.get_absolute_url }}" title="{{ object.title }}" rel="bookmark">
{% endif %}
<img src="{{ object.real_image.url }}" alt="{{ object.title }}" class="left" />
{% if continue_reading %}
</a>
{% endif %}
</p>
</div>
{% endif %}
{% endblock %}
{% block entry-content %}
<div class="entry-content">
{{ object_content }}
{% block continue-reading %}
{% if continue_reading %}
<p class="continue-reading">
<a href="{{ object.get_absolute_url }}"
title="{% blocktrans with object=object.title %}Continue reading {{ object }}{% endblocktrans %}"
rel="bookmark">
{% trans "Continue reading" %}
</a>
</p>
{% endif %}
{% endblock %}
</div>
{% endblock %}
</div>
{% endblock %}
{% block entry-footer %}
<div class="entry-footer row">
{% block entry-tags %}
<div class="entry-tags col-md-3">
<h4>{% trans "Tags" %}</h4>
{% for tag in object.tags_list %}
<a href="{% url 'zinnia_tag_detail' tag %}"
title="{% blocktrans %}Show all entries tagged by {{ tag }}{% endblocktrans %}"
rel="tag">{{ tag }}</a>
{% empty %}
<span class="empty">{% trans "No tags" %}</span>
{% endfor %}
</div>
{% endblock %}
{% block entry-categories %}
<div class="entry-categories col-md-3">
<h4>{% trans "Categories" %}</h4>
{% with categories=object.categories.all %}
{% for category in categories %}
<a href="{{ category.get_absolute_url }}"
title="{% blocktrans %}Show all entries in {{ category }}{% endblocktrans %}"
rel="tag category">{{ category }}</a>{% if not forloop.last %}, {% endif %}
{% empty %}
<span class="empty">{% trans "None" %}</span>
{% endfor %}{% endwith %}
</div>
{% endblock %}
<div class="col-md-6">
{% block entry-serie %}
{% if object.within_serie %}
<h4>Blog serie</h4>
{% url 'dolweb.blog.views.serie_view' uid=object.within_serie.pk as serie_url %}
<p>{% blocktrans with nth=object.serie_index url=serie_url serie=object.within_serie %}This article is number {{ nth }} within the blog serie
<a href="{{ url }}"><em>{{ serie }}</em></a>.{% endblocktrans %}</p>
{% with previous=object.previous_entry_in_serie next=object.next_entry_in_serie %}
{% if previous or next %}
<p>
{% if previous %}<a href="{{ previous.get_absolute_url }}">{% trans " Previous article in serie" %}</a>{% endif %}
{% if previous and next %}/{% endif %}
{% if next %}<a href="{{ next.get_absolute_url }}">{% trans "Next article in serie " %}</a>{% endif %}
</p>
{% endif %}
{% endwith %}
{% endif %}
{% endblock %}
{% block entry-comments %}
{% comment %}
<p class="entry-comments">
<strong>{% trans "Discussions" %}</strong> :
{% with comment_count=object.comment_count %}
{% if comment_count %}
<a href="{{ object.get_absolute_url }}#comments"
title="{% blocktrans with object=object.title %}Comments on {{ object }}{% endblocktrans %}">
{% blocktrans count comment_count=comment_count %}{{ comment_count }} comment{% plural %}{{ comment_count }} comments{% endblocktrans %}
</a>
{% else %}
{% if object.comments_are_open %}
{% trans "No comments yet." %}
<a href="{{ object.get_absolute_url }}#comment-form"
title="{% blocktrans with object=object.title %}Leave a comment on {{ object }}{% endblocktrans %}">
{% trans "Be first to comment!" %}
</a>
{% else %}
{% trans "Comments are closed." %}
{% endif %}
{% endif %}
{% endwith %}
{% with pingback_count=object.pingback_count %}
{% if pingback_count %}
, <a href="{{ object.get_absolute_url }}#pingbacks" title="{% blocktrans with object=object.title %}Pingbacks on {{ object }}{% endblocktrans %}">
{% blocktrans count pingback_count=pingback_count %}{{ pingback_count }} pingback{% plural %}{{ pingback_count }} pingbacks{% endblocktrans %}
</a>
{% endif %}
{% endwith %}
{% with trackback_count=object.trackback_count %}
{% if trackback_count %}
, <a href="{{ object.get_absolute_url }}#trackbacks" title="{% blocktrans with object=object.title %}Trackbacks on {{ object }}{% endblocktrans %}">
{% blocktrans count trackback_count=trackback_count %}{{ trackback_count }} trackback{% plural %}{{ trackback_count }} trackbacks{% endblocktrans %}
</a>
{% endif %}
{% endwith %}
</p>
{% endcomment %}
{% endblock %}
</div> {# col-md-6 (last column) #}
</div>
{% endblock %}
</div>

View File

@ -0,0 +1 @@
{% extends "zinnia/entry_detail_base.html" %}

View File

@ -0,0 +1,229 @@
{% extends "zinnia/base.html" %}
{% load i18n comments zinnia_tags %}
{% load url from future %}
{% block "title" %}{{ object.title }}{% endblock %}
{% block "metadescr" %}{% if object.excerpt %}{{ object.excerpt|striptags }}{% else %}{{ object.content|striptags|truncatewords:100 }}{% endif %}{% endblock %}
{% block meta-keywords %}{% if object.tags %}{{ object.tags }}{% else %}{{ block.super }}{% endif %}{% endblock %}
{% block link %}
{{ block.super }}
{% with previous_entry=object.previous_entry %}{% if previous_entry %}
<link rel="prev" title="{{ previous_entry.title }}" href="{{ previous_entry.get_absolute_url }}" />
{% endif %}{% endwith %}
{% with next_entry=object.next_entry %}{% if next_entry %}
<link rel="next" title="{{ next_entry.title }}" href="{{ next_entry.get_absolute_url }}" />
{% endif %}{% endwith %}
<link rel="shortlink" href="{{ object.short_url }}" />
<link rel="canonical" href="{{ object.get_absolute_url }}" />
{% with year=object.creation_date|date:"Y" month=object.creation_date|date:"m" day=object.creation_date|date:"d" %}
<link rel="alternate" type="application/rss+xml" title="{% trans "RSS Feed of discussions on" %} '{{ object.title }}'"
href="{% url 'zinnia_entry_discussion_feed' year month day object.slug %}" />
<link rel="alternate" type="application/rss+xml" title="{% trans "RSS Feed of comments on" %} '{{ object.title }}'"
href="{% url 'zinnia_entry_comment_feed' year month day object.slug %}" />
<link rel="alternate" type="application/rss+xml" title="{% trans "RSS Feed of pingbacks on" %} '{{ object.title }}'"
href="{% url 'zinnia_entry_pingback_feed' year month day object.slug %}" />
<link rel="alternate" type="application/rss+xml" title="{% trans "RSS Feed of trackbacks on" %} '{{ object.title }}'"
href="{% url 'zinnia_entry_ trackback_feed' year month day object.slug %}" />
{% endwith %}
{% endblock %}
{% block body-class %}entry entry-{{ object.pk }}{% if object.featured %} featured{% endif %} year-{{ object.creation_date|date:"Y" }} month-{{ object.creation_date|date:"m" }} week-{{ object.creation_date|date:"W" }} day-{{ object.creation_date|date:"d" }}{% endblock %}
{% block content %}
{% block entry-content %}
{% include object.content_template with object_content=object.html_content|safe %}
{% endblock %}
{% block entry-widgets %}
<div class="entry-widgets">
{% with next_entry=object.next_entry %}
{% if next_entry %}
<div class="entry-next">
<h3>{% trans "Next entry" %}</h3>
<p>
<a href="{{ next_entry.get_absolute_url }}" title="{{ next_entry.title }}" rel="next">
{{ next_entry.title }}
</a>
</p>
</div>
{% endif %}
{% endwith %}
{% with previous_entry=object.previous_entry %}
{% if previous_entry %}
<div class="entry-previous">
<h3>{% trans "Previous entry" %}</h3>
<p>
<a href="{{ previous_entry.get_absolute_url }}" title="{{ previous_entry.title }}" rel="prev">
{{ previous_entry.title }}
</a>
</p>
</div>
{% endif %}
{% endwith %}
{% with entry_related=object.related_published %}
{% if entry_related %}
<div class="entry-related">
<h3>{% trans "Related entries" %}</h3>
<ul>
{% for entry in entry_related %}
<li>
<a href="{{ entry.get_absolute_url }}" title="{{ entry.title }}" rel="bookmark">{{ entry.title }}</a>
</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% endwith %}
<div class="entry-similar">
<h3>{% trans "Similar entries" %}</h3>
{% get_similar_entries %}
</div>
</div>
{% endblock %}
{% block entry-comments %}
{% comment %}
<div id="comments">
<h3>{% trans "Comments" %}</h3>
{% if object.comment_count %}
{% with comment_list=object.comments %}
<ol id="comment-list">
{% for comment in comment_list %}
<li id="comment-{{ comment.pk }}-by-{{ comment.user_name|slugify }}"
class="comment vcard {% cycle box1,box2 %}{% if comment.user %} authenticated-comment{% if comment.user.is_staff %} staff-comment{% endif %}{% if comment.user.is_superuser %} superuser-comment{% endif %}{% endif %}">
<img src="{% get_gravatar comment.email 60 "G" %}"
class="gravatar photo" alt="{{ comment.name }}" />
<p class="comment-info">
{% if comment.url %}
<a href="{{ comment.url }}" rel="external nofollow"
class="fn url">{{ comment.name }}</a>
{% else %}
<span class="fn">{{ comment.name }}</span>
{% endif %}
{% trans "on" %}
<abbr class="comment-published" title="{{ comment.submit_date|date:"c" }}">
{{ comment.submit_date|date:"SHORT_DATETIME_FORMAT" }}
</abbr>
<a href="#comment-{{ comment.pk }}-by-{{ comment.user_name|slugify }}"
id="c{{ comment.pk }}" class="anchor-link"
title="{% trans "Direct link to this comment" %}">#</a>
</p>
{{ comment.comment|linebreaks }}
</li>
{% endfor %}
</ol>
{% endwith %}
{% if not object.comments_are_open %}
<p>{% trans "Comments are closed." %}</p>
{% endif %}
{% else %}
{% if object.comments_are_open %}
<p>{% trans "No comments yet." %}</p>
{% else %}
<p>{% trans "Comments are closed." %}</p>
{% endif %}
{% endif %}
</div>
{% endcomment %}
{% endblock %}
{% block entry-pingbacks %}
{% comment %}
<div id="pingbacks">
<h3>{% trans "Pingbacks" %}</h3>
{% if object.pingback_count %}
{% with pingback_list=object.pingbacks %}
<ol id="pingback-list">
{% for pingback in pingback_list %}
<li id="pingback-{{ pingback.pk }}" class="pingback vcard {% cycle box1,box2 %}">
<p class="pingback-info">
<a href="{{ pingback.url }}" rel="external nofollow"
class="fn url org">{{ pingback.name }}</a>
{% trans "on" %}
<abbr class="pingback-published" title="{{ pingback.submit_date|date:"c" }}">
{{ pingback.submit_date|date:"SHORT_DATETIME_FORMAT" }}
</abbr>
<a href="#pingback-{{ pingback.pk }}"
id="c{{ pingback.pk }}" class="anchor-link"
title="{% trans "Direct link to this pingback" %}">#</a>
</p>
<p class="pingback-content">
{{ pingback.comment }}
</p>
</li>
{% endfor %}
</ol>
{% endwith %}
{% endif %}
{% if object.pingbacks_are_open %}
<p>{% trans "Pingbacks are open." %}</p>
{% else %}
<p>{% trans "Pingbacks are closed." %}</p>
{% endif %}
</div>
{% endcomment %}
{% endblock %}
{% block entry-trackbacks %}
{% comment %}
{% if object.trackback_count or object.trackbacks_are_open %}
<div id="trackbacks">
<h3>{% trans "Trackbacks" %}</h3>
{% if object.trackback_count %}
{% with trackback_list=object.trackbacks %}
<ol id="trackback-list">
{% for trackback in trackback_list %}
<li id="trackback-{{ trackback.pk }}" class="trackback vcard {% cycle box1,box2 %}">
<p class="trackback-info">
<a href="{{ trackback.url }}" rel="external nofollow"
class="fn url org">{{ trackback.name }}</a>
{% trans "on" %}
<abbr class="trackback-published" title="{{ trackback.submit_date|date:"c" }}">
{{ trackback.submit_date|date:"SHORT_DATETIME_FORMAT" }}
</abbr>
<a href="#trackback-{{ trackback.pk }}"
id="c{{ trackback.pk }}" class="anchor-link"
title="{% trans "Direct link to this trackback" %}">#</a>
</p>
<p class="trackback-content">
{{ trackback.comment }}
</p>
</li>
{% endfor %}
</ol>
{% endwith %}
{% endif %}
{% if object.trackbacks_are_open %}
<p>
<a href="{% url 'zinnia_entry_trackback' object.pk %}" rel="trackback">
{% trans "Trackback URL" %}</a>
</p>
{% endif %}
</div>
{% endif %}
{% endcomment %}
{% endblock %}
{% block entry-comments-form %}
{% comment %}
{% if object.comments_are_open %}
{% render_comment_form for object %}
{% endif %}
{% endcomment %}
{% endblock %}
{% endblock %}
{% block admin_tools %}
{% if perms.zinnia.change_entry %}
<li>
<a href="{% url 'admin:zinnia_entry_change' object.pk %}" title="{% trans "Edit the entry" %}">
{% trans "Edit the entry" %}
</a>
</li>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,59 @@
{% extends "zinnia/_base_blog.html" %}
{% load i18n staticfiles %}
{% load url from future %}
{% block "metadescr" %}{% trans "Latest news for Dolphin Emulator" %}{% endblock %}
{# Aweful hack to workaround stupid quotes in block name #}
{% block "title" %}{% block title %}{% trans "Articles" %}{% endblock %}{% endblock %}
{% block "body" %}
<div class="page-header">
<h1>{% trans "Articles" %}</h1>
</div>
<div class="row" style="margin-top: 1em">
<div class="col-md-3">
{% include "blog_sidebar.html" %}
</div>
<div class="col-md-9">
{% block breadcrumbs %}{% endblock breadcrumbs %}
{% block slider %}{% endblock slider %}
{% block content %}{% endblock %}
</div>
</div>
{% comment %}
<div id="content" class="hfeed">
{% block content %}
<div class="links">
<h3>{% trans "Useful links" %}</h3>
<ul>
<li>
<a href="{% url 'zinnia_entry_archive_index' %}" title="{% trans "Weblog index" %}">
{% trans "Weblog index" %}
</a>
</li>
<li>
<a href="{% url 'zinnia_sitemap' %}" title="{% trans "Sitemap" %}">
{% trans "Sitemap" %}
</a>
</li>
</ul>
</div>
<div class="search">
<h3>{% trans "Search" %}</h3>
{% include "zinnia/tags/search_form.html" %}
</div>
{% endblock content %}
</div>
<div id="sidebar">
{% block sidebar %}
{% endblock sidebar %}
</div>
{% endcomment %}
{% endblock %}

View File

@ -0,0 +1,11 @@
<ol class="breadcrumb">
{% for crumb in breadcrumbs %}
<li>
{% if crumb.url %}
<a href="{{ crumb.url }}" title="{{ crumb.name }}">{{ crumb.name }}</a>
{% else %}
{{ crumb.name }}
{% endif %}
</li>
{% endfor %}
</ol>

View File

@ -0,0 +1,17 @@
{% load i18n %}
{% load url from future %}
<form method="get" action="{% url 'zinnia_entry_search' %}" role="search">
<div class="input-group">
<input type="text" placeholder="{% trans "Search articles" %}" name="pattern" class="form-control" />
<span class="input-group-btn">
<button type="submit" class="btn">
<i class="icon-search"></i>
</button>
</span>
</div>
</form>
<p class="alert alert-info" style="margin-top: 1em">
<img src="{{ STATIC_URL }}zinnia/img/help.png" alt="?" class="help" width="14" height="14" />
{% trans "You can use - to exclude words or phrases, &quot;double quotes&quot; for exact phrases and the AND/OR boolean operators combined with parenthesis for complex queries." %}
</p>

View File

View File

@ -0,0 +1,12 @@
from django.template import Library
register = Library()
from dolweb.blog.models import BlogSerie
@register.inclusion_tag('blog_chunk_series.html')
def get_blog_series(number=5):
"""Return the most recent visible blog series"""
return {
'series': BlogSerie.objects.filter(visible=True)[:number],
}

12
dolweb/blog/urls.py Normal file
View File

@ -0,0 +1,12 @@
from django.conf.urls import patterns, url, include
urlpatterns = patterns('',
url(r'^', include('zinnia.urls')),
url(r'^comments/', include('django.contrib.comments.urls')),
)
urlpatterns += patterns('dolweb.blog.views',
url(r'^series(/(?P<page>[0-9]+))?$', 'series_index'),
url(r'^series/(?P<slug>[-\w]+)$', 'serie_view'),
url(r'^series/(?P<uid>[0-9]+)$', 'serie_view'),
)

39
dolweb/blog/views.py Normal file
View File

@ -0,0 +1,39 @@
from annoying.decorators import render_to
from django.conf import settings
from django.core.paginator import Paginator, EmptyPage
from django.http import Http404, HttpResponse
from django.shortcuts import get_object_or_404
from django.views.decorators.csrf import csrf_exempt
from dolweb.blog.models import BlogSerie
@render_to('series-index.html')
def series_index(request, page=None):
if page is None:
page = 1
series = BlogSerie.objects.filter(visible=True)
pagi = Paginator(series, 20)
try:
page_obj = pagi.page(page)
except EmptyPage:
raise Http404
return {'page': page, 'page_obj': page_obj, 'pagi': pagi}
@render_to('serie-view.html')
def serie_view(request, uid=None, slug=None):
both = (uid, slug)
if not any(both) or all(both):
raise Http404
if uid is not None:
serie = get_object_or_404(BlogSerie, pk=uid)
else:
serie = get_object_or_404(BlogSerie, slug=slug)
return {'serie': serie}