pythondjangodjango-1.6django-flatpages

Django flatpages template tag doesn't work with template inheritance


I have a Django (1.6) application that inherits a base template. I would like to include one of my (currently working) flatpages into the application landing page, something that the Django docs say is possible.

Here is my template:

{% extends "path/to/base.html" %}
{% load flatpages %}
{% get_flatpages as fp %}

{% block content %}
  <h3>Flatpage inclusion</h3>
  <p>Number of flatpages: {{ fp|length }}
  <ul>
    {% for page in fp %}
      <li><a href="{{ page.url }}">{{ page.title }}</a></li>
    {% endfor %}       
  </ul> 
{% endblock content %}

This does not list any of the flatpages. However, if I remove the {% extends %} signal, so my code looks like this:

{% load flatpages %}
{% get_flatpages as fp %}

<h3>Flatpage inclusion</h3>
<p>Number of flatpages: {{ fp|length }}
<ul>
  {% for page in fp %}
    <li><a href="{{ page.url }}">{{ page.title }}</a></li>
  {% endfor %}       
</ul> 

Everything works. I see the number of flatpages in my fp object (9) and my unordered list shows all the flatpage urls and titles.

This seems to me to be a bug in either how flatpages work, or how Django does template inheritance.

The base template (/path/to/base.html) doesn't have anything complex in it.

Django categorically says that this is possible:

When you load a custom tag or filter library, the tags/filters are only made available to the current template – not any parent or child templates along the template-inheritance path.

For example, if a template foo.html has {% load humanize %}, a child template (e.g., one that has {% extends "foo.html" %}) will not have access to the humanize template tags and filters. The child template is responsible for its own {% load humanize %}.

This is a feature for the sake of maintainability and sanity.

Has anyone else noticed this bug? Is it an exception for just the built-in flatpages app?

EDIT 1:

Daniels answer is correct. The example code from the Django docs doesn't show including flatpage content within a {% block %}, so I didn't expect that it needed to be done:

{% load flatpages %}
{% get_flatpages as flatpages %}
<ul>
  {% for page in flatpages %}
    <li><a href="{{ page.url }}">{{ page.title }}</a></li>
  {% endfor %}
</ul>

My fault I guess. Live and learn.


Solution

  • The problem is that your get_flatpages tag is outside any blocks from the parent template. That means it simply won't be called.

    Move it into the content block and it should work.