diff --git a/core/context_processors.py b/core/context_processors.py index 3daa80c..420c8ab 100644 --- a/core/context_processors.py +++ b/core/context_processors.py @@ -1,7 +1,10 @@ +import calendar +from collections import Counter + from django.conf import settings from django.contrib.auth.forms import AuthenticationForm -from core.models import Tag +from core.models import Post, Tag from core.views.view_utils import tag_cloud_context def tag_cloud_context_processor(request): @@ -10,11 +13,37 @@ def tag_cloud_context_processor(request): def sidebar_login_form_context_processor(request): return {'sidebar_login_form': AuthenticationForm() } +def monthly_archives_context_processor(request): + month_counts = Counter([(p.year, p.month) + for p in Post.objects.all()]) + month_counts = sorted( + month_counts.items(), + key=lambda k: (int(k[0][0]), int(k[0][1])) + ) + months_info = [ + ( + archive[0], + "{} {} ({})".format( + calendar.month_name[int(archive[0][1])], archive[0][0], + archive[1] + ) + ) for archive in month_counts + ] + return {'months': months_info} + +# [ +# (k, "{} {} ({})".format( +# calendar.month_name[k[1]], k[0], v +# ) +# for k, v in months_info} +# } + def contextual_static_serving_context_processor(request): if settings.SERVE_STATIC_LIBS_LOCALLY: jquery_url = "/static/libs/jquery-2.1.1.min.js" underscore_url = "/static/libs/underscore-min.js" else: jquery_url = "//code.jquery.com/jquery-2.1.1.min.js" - underscore_url = "//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js" + underscore_url = ("//cdnjs.cloudflare.com/ajax/libs/underscore.js/" + "1.7.0/underscore-min.js") return locals() diff --git a/core/views/views.py b/core/views/views.py index 6b178bc..6cd95eb 100644 --- a/core/views/views.py +++ b/core/views/views.py @@ -1,8 +1,10 @@ import json from datetime import datetime +import calendar import bleach +from django.conf import settings from django.shortcuts import render, redirect from django.http import HttpResponse from django.http import HttpResponseForbidden @@ -11,6 +13,7 @@ from django.views.decorators.csrf import csrf_exempt from django.views.decorators.debug import sensitive_post_parameters from django.views.decorators.http import require_POST +from django.views.generic.list import ListView from django.contrib.auth import authenticate, login, logout from django.contrib.auth.decorators import login_required from django.contrib import messages @@ -71,6 +74,28 @@ def show_post(request, year, month, slug): 'top_level_comments': top_level_comments}) ) +class MonthlyArchive(ListView): + context_object_name = 'posts' + template_name = 'monthly_archive.html' + paginate_by = settings.POSTS_PER_PAGE + + def get_queryset(self): + year = int(self.kwargs['year']) + month = int(self.kwargs['month']) + start_of_month = datetime(year=year, month=month, day=1) + end_year = year if month < 12 else (year + 1) + next_month = (month % 12) + 1 + end_of_month = datetime(year=end_year, month=next_month, day=1) + return Post.objects.filter( + published_at__gte=start_of_month, published_at__lt=end_of_month + ) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['year'] = int(self.kwargs['year']) + context['month'] = calendar.month_name[int(self.kwargs['month'])] + return context + @login_required def new_post(request): url = HttpRequest.build_absolute_uri(request, reverse("home")) diff --git a/settings.py b/settings.py index 3c0abe5..615c3fa 100644 --- a/settings.py +++ b/settings.py @@ -87,6 +87,7 @@ 'core.context_processors.tag_cloud_context_processor', 'core.context_processors.contextual_static_serving_context_processor', 'core.context_processors.sidebar_login_form_context_processor', + 'core.context_processors.monthly_archives_context_processor', ) STATIC_ROOT = 'staticfiles' diff --git a/templates/base.html b/templates/base.html index ef7a5a6..64b5815 100644 --- a/templates/base.html +++ b/templates/base.html @@ -54,6 +54,7 @@ {% endif %} {% include "includes/tag_cloud.html" %} + {% include "includes/sidebar_archives_list.html" %} diff --git a/templates/home.html b/templates/home.html index 5278eed..3422ff6 100644 --- a/templates/home.html +++ b/templates/home.html @@ -10,9 +10,6 @@ {% for post in posts %}
{% include "includes/post.html" %} -

- {{ post.comment_set.count }} comments -

{% endfor %} diff --git a/templates/includes/post.html b/templates/includes/post.html index 644ff0f..ab8af39 100644 --- a/templates/includes/post.html +++ b/templates/includes/post.html @@ -28,3 +28,8 @@

{{ post.title ... +

+ + {{ post.comment_set.count }} comments + +

diff --git a/templates/includes/sidebar_archives_list.html b/templates/includes/sidebar_archives_list.html new file mode 100644 index 0000000..3c397f1 --- /dev/null +++ b/templates/includes/sidebar_archives_list.html @@ -0,0 +1,12 @@ + diff --git a/templates/monthly_archive.html b/templates/monthly_archive.html new file mode 100644 index 0000000..90e1898 --- /dev/null +++ b/templates/monthly_archive.html @@ -0,0 +1,18 @@ +{% extends "base.html" %} + +{% block valuation %} + {# TODO #} +{% endblock %} + +{% block subtitle %}posts during {{ month }} {{ year }}{% endblock %} + +{% block content %} +

posts during {{ month }} {{ year }}

+ +{% for post in posts %} +
+ {% include "includes/post.html" %} +
+{% endfor %} + +{% endblock %} diff --git a/templates/tagged.html b/templates/tagged.html index fc1fe06..a55216b 100644 --- a/templates/tagged.html +++ b/templates/tagged.html @@ -8,13 +8,10 @@ {% block content %}

Posts tagged '{{ tag.label }}'

+ {% for post in posts %} -{# XXX: duplication; another fragment, or comment link inside includes/post? #}
{% include "includes/post.html" %} -

- {{ post.comment_set.count }} comments -

{% endfor %} diff --git a/urls.py b/urls.py index db395fd..ce497cc 100644 --- a/urls.py +++ b/urls.py @@ -21,5 +21,8 @@ url(r'^edit_profile/(.+)/$', views.edit_profile, name='edit_profile'), url(r'^add_comment/(\d+)/$', views.add_comment, name='add_comment'), url(r'^check_slug/$', views.check_slug, name='check_slug'), + url(r'^(?P\d{4})/(?P\d{2})/(?:page/(?P\d+)/)?$', + views.MonthlyArchive.as_view(), + name='monthly_archive'), url(r'^(\d{4})/(\d{2})/([a-z\d\-]+)/$', views.show_post, name='show_post') )