和最新文章模板标签一样,先写好函数,然后将函数注册为模板标签即可。
@register.inclusion_tag('blog/inclusions/_archives.html', takes_context=True) def show_archives(context): return { 'date_list': Post.objects.dates('created_time', 'month', order='DESC'), }这里 Post.objects.dates 方法会返回一个列表,列表中的元素为每一篇文章(Post)的创建时间(已去重),且是 Python 的 date 对象,精确到月份,降序排列。接受的三个参数值表明了这些含义,一个是 created_time ,即 Post 的创建时间,month 是精度,order='DESC' 表明降序排列(即离当前越近的时间越排在前面)。例如我们写了 3 篇文章,分别发布于 2017 年 2 月 21 日、2017 年 3 月 25 日、2017 年 3 月 28 日,那么 dates 函数将返回 2017 年 3 月 和 2017 年 2 月这样一个时间列表,且降序排列,从而帮助我们实现按月归档的目的。
然后是渲染的模板 _archives.html 的内容:
<div> <h3>归档</h3> <ul> {% for date in date_list %} <li> <a href="#">{{ date.year }} 年 {{ date.month }} 月</a> </li> {% empty %} 暂无归档! {% endfor %} </ul> </div>由于 date_list 中的每个元素都是 Python 的 date 对象,所以可以引用 year 和 month 属性来获取年份和月份。
分类模板标签过程还是一样,先写好函数,然后将函数注册为模板标签。注意分类模板标签函数中使用到了 Category 类,其定义在 blog.models.py 文件中,使用前记得先导入它,否则会报错。
@register.inclusion_tag('blog/inclusions/_categories.html', takes_context=True) def show_categories(context): return { 'category_list': Category.objects.all(), }_categories.html 的内容:
<div> <h3>分类</h3> <ul> {% for category in category_list %} <li> <a href="#">{{ category.name }} <span>(13)</span></a> </li> {% empty %} 暂无分类! {% endfor %} </ul> </div><span>(13)</span> 显示的是该分类下的文章数目,这个特性会在接下来的教程中讲解如何实现,目前暂时用占位数据代替吧。
标签云模板标签标签和分类其实是很类似的,模板标签:
@register.inclusion_tag('blog/inclusions/_tags.html', takes_context=True) def show_tags(context): return { 'tag_list': Tag.objects.all(), }_tags.html:
<div> <h3>标签云</h3> <ul> {% for tag in tag_list %} <li> <a href="#">{{ tag.name }}</a> </li> {% empty %} 暂无标签! {% endfor %} </ul> </div> 使用自定义的模板标签打开 base.html,为了使用刚才定义的模板标签,我们首先需要在模板中导入存放这些模板标签的模块,这里是 blog_extras.py 模块。当时我们为了使用 static 模板标签时曾经导入过 {% load static %},这次在 {% load static %} 下再导入 blog_extras:
templates/base.html {% load static %} {% load blog_extras %} <!DOCTYPE html> <html> ... </html>然后找到侧边栏各项,将他们都替换成对应的模板标签:
templates/base.html <aside> {% block toc %} {% endblock toc %} {% show_recent_posts %} {% show_archives %} {% show_categories %} {% show_tags %} <div> <a href=""><span></span> RSS 订阅</a> </div> </aside>此前侧边栏中各个功能块都替换成了模板标签,其实实际内容还是一样的,只是我们将其挪到了模块化的模板中,并有这些自定义的模板标签负责渲染这些内容。
此外我们定义的 show_recent_posts 标签可以接收参数,默认为 5,即显示 5 篇文章,如果要控制其显示 10 篇文章,可以使用 {% show_recent_posts 10 %} 这种方式传入参数。
现在运行开发服务器,可以看到侧边栏显示的数据已经不再是之前的占位数据,而是我们保存在数据库中的数据了。
注意:
如果你是在开发服务器启动的过程中编写的模板标签代码,那么一定要重启一下开发服务器才能导入 blog_extras,否则会报
TemplateSyntaxError at /
'blog_extras' is not a registered tag library. Must be one of:
类似这样的错误。
注意:如果你按照教程的步骤做完后发现报错,请按以下顺序检查。
检查目录结构是否正确。确保 templatetags 位于 blog 目录下,且目录名必须为 templatetags。具体请对照上文给出的目录结构。
确保 templatetags 目录下有 __init__.py 文件。
确保通过 register = template.Library() 和 @register.inclusion_tag 装饰器将函数装饰为一个模板标签。
确保在使用模板标签以前导入了 blog_extras,即 {% load blog_extras%}。注意要在使用任何 blog_extras下的模板标签以前导入它。
确保模板标签的语法使用正确,即 {% load blog_extras %},注意 { 和 % 以及 % 和 } 之间没有任何空格。