.. _template-tag-chapter: .. note:: A newer version of this tutorial using Django 1.9 is available from `Leanpub: https://leanpub.com/tangowithdjango19 `_ Template Tags ============= Providing Categories on Every Page ---------------------------------- It would be nice to show the different categories that users can browse through in the sidebar on each page. Given what we have learnt so far we could do the following: * In the ``base.html`` template we could add some code to display an item list of categories, if the category list has been passed through. * Then in each view, we could access the Category object, get all the categories, and return that in the context dictionary. However, this is a pretty nasty solution. It requires a lot of cutting and pasting of code. Also, we will run into problems, when we want to show the categories on pages serviced by the django-registration-redux package. So we need a different approach, by using ``templatetags`` that are included in the template that request the data required. Using Template Tags -------------------- Create a directory ``rango/templatetags``, and create two files, one called ``__init__.py``, which will be empty, and another called, ``rango_extras.py``, where you can add the following code: .. code-block:: python from django import template from rango.models import Category register = template.Library() @register.inclusion_tag('rango/cats.html') def get_category_list(): return {'cats': Category.objects.all()} As you can see we have made a method called, ``get_category_list()`` which returns the list of categories, and that is assocaited with a template called ``rango/cats.html``. Now create a template called ''rango/cats.html`` in the templates directory with the following code: .. code-block:: html {% if cats %} {% endif %} Now in your ``base.html`` you can access the templatetag by first loading it up with ``{% load rango_extras %}`` and then slotting it into the page with ``{% get_category_list %}``, i.e.: .. code-block:: html .. note:: You will need to restart your server every time you modify the templatetags so that they are registered. Parameterised Template Tags --------------------------- Now lets extend this so that when we visit a category page, it highlights which category we are in. To do this we need to paramterise the templatetag. So update the method in ``rango_extras.py`` to be: .. code-block:: python def get_category_list(cat=None): return {'cats': Category.objects.all(), 'act_cat': cat} This lets us pass through the category we are on. We can now update the ``base.html`` to pass through the category, if it exists. .. code-block:: html Now update the ``cats.html`` template: .. code-block:: html {% for c in cats %} {% if c == act_cat %}
  • {% else %}
  • {% endif %} {{ c.name }}
  • {% endfor %} Here we check to see if the category being displayed is the same as the category being passed through (i.e. ``act_cat``), if so, we assign the ``active`` class to it from Bootstrap (http://getbootstrap.com/components/#nav). Restart the development web server, and now visit the pages. We have passed through the ``category`` variable. When you view a category page, the template has access to the ``category`` variable, and so provides a value to the templatetag ``get_category_list()``. This is then used in the ``cats.html`` template to select which category to highlight as active.