I would like to produce a list on the side of my blog that shows the year and the months that have entries only, like this:
2011 - Jan, Feb
2010 - Jan, Mar, May, Jun, Jul, Aug, Oct, Nov, Dec
2009 - Sep, Oct, Nov, Dec
I have made custom template tag so that I can place it into the base.html.
Currently it produces a list that looks like this:
2011 - 1, 2
2010 - 1, 3, 5, 6, 7, 8, 10, 11, 12
2009 - 9, 10, 11, 12
I have built a custom template tag that is(thanks to Alasdair and cig212):
from django import template
from blog.models import Post
register = template.Library()
class PostList(template.Node):
def __init__(self, var_name):
self.var_name = var_name
def render(self, context):
my_months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec']
arch = Post.objects.dates('publish', 'month', order='DESC')
archives = {}
for i in arch:
year = i.year
month = i.month
if year not in archives:
archives[year] = []
archives[year].append(month)
else:
if month not in archives[year]:
archives[year].append(month)
context[self.var_name] = archives.items()
return ''
@register.tag
def get_post_list(parser, token):
"""
Generates a list of months that blog posts exist.
Much like the 'year' archive.
Syntax::
{% get_post_list as [var_name] %}
Example usage::
{% get_post_list as posts_list %}
(This 'var_name' is the one inserted into the Node)
"""
try:
tag_name, arg = token.contents.split(None, 1)
except ValueError:
raise template.TemplateSyntaxError, "%s tag requires arguments" % token.contents.split()[0]
m = re.search(r'as (\w+)', arg)
if not m:
raise template.TemplateSyntaxError, "%s tag had invalid arguments" % tag_name
var_name = m.groups()[0]
return PostListNode(var_name)
The template looks like so:
{% load blog %}
{% get_post_list as posts_list %}
{% for years, months in posts_list %}
{{ years }}
{% for month in months %}
<a href="{{ years }}/{{ month }}">{{ month }}</a>
{% endfor %}
<br />
{% endfor %}
So how can I get my my_months
labels that are in the custom tag on to the month numbers produced by the tag. I know that I need to use enumerate()
in the custom tag but I am getting lost somewhere.
Change
if year not in archives:
archives[year] = []
archives[year].append(month)
else:
if month not in archives[year]:
archives[year].append(month)
to
if year not in archives:
archives[year] = {}
archives[year][month] = my_months[month - 1]
else:
if month not in archives[year]:
archives[year][month] = my_months[month - 1]
and then
{% for years, months in posts_list %}
{{ years }}
{% for month in months %}
<a href="{{ years }}/{{ month }}">{{ month }}</a>
{% endfor %}
<br />
{% endfor %}
to
{% for years, months in posts_list %}
{{ years }}
{% for month_number, month_name in months.items %}
<a href="{{ years }}/{{ month_number }}">{{ month_name }}</a>
{% endfor %}
<br />
{% endfor %}
This should do what you need.