2

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.

Kevin Brown-Silva
  • 40,873
  • 40
  • 203
  • 237
tatlar
  • 3,080
  • 2
  • 29
  • 40

2 Answers2

3

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.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • 1
    Hi Daniel - Thanks! This worked. Odd that the Django documentation doesn't explicitly say this, or maybe I am just being dense.... – tatlar Sep 25 '14 at 21:17
0

Just to reiterate the correct solution- get_flatpages needs to be placed inside the block where it's going to be referenced. So this will work:

{% extends "index.html" %}
{% load flatpages %}

{% block footer %}
    {% get_flatpages as flatpages %}
    {% for page in flatpages %}
    ...
    {% endfor %}

And this will not work:

{% extends "index.html" %}
{% load flatpages %}
{% get_flatpages as flatpages %}

{% block footer %}        
    {% for page in flatpages %}
    ...
    {% endfor %}

And yes, Django documentation isn't very clear on that.

kravietz
  • 10,667
  • 2
  • 35
  • 27