Templates


In templates django renders data from a Context. This is a dictionary-like object mapping keys to values. The rendered page-object can accessed by the 'page'-key as {{ page }} which will return as value the page-object representation which is a string with the page.name attribute. So this is the same as {{ page.name }}. For example the following template

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>{{ page.name }}</title>
</head>
<body>
    <p>{{ page.name }}</p>
    <p>{{ page.url }}</p>
</body>
</html>

will render the page-name as title and as content of the paragraph in the body-part and also the url of this page.

Other keys are root_pages, breadcrumps and sections which allow to build up the navigation and access the content of the related panes.

navigation

The navigation can contructed as a simple ordered list of links:

<ul>
    {% for root_page in root_pages %}
        <li><a href="{{ root_page.url }}">{{ root_page.name }}</a></li>
    {% endfor %}
</ul>

The key root_pages refers to a list of page-objects not having parent-pages. The list is ordered by the siblings_id of the pages in ascending order: pages with lower sibling_id are coming first.

Because every page-object knows about its children, a sub-navigation can created the same way:

<ul>
    {% for sub_page in  page.children %}
        <li><a href="{{ sub_page.url }}">{{ sub_page.name }}</a></li>
    {% endfor %}
</ul>

Breadcrumbs are the path from a page to the parents up to the root-page. Every page-object knows about this path by the breadcrumbs attribute:

{% for item in page.breadcrumbs %}
    <span><a href="{{ item.url }}">{{ item.name }}</a></span>
    {% if not forloop.last %}
        &nbsp;>>&nbsp;
    {% endif %}
{% endfor %}

Every item is not a page-object but an object that holds the name, url and pk of the pages. This is for performance reasons: a call to page.children or page.breadcrumbs and the corresponding attributes of the returned objects will hit the database only at the first call or when the underlying data have changed. On further calls the cached results are returned without any additional request to the database.

Content

The content of a page is stored by panes. Panes are related to pages and sections. Before rendering a page loads the content from all related panes into lists. These lists are ordered by the order_id of the panes in descending order: content from panes with higher order_id are coming first. Also the content of the panes gets stored in different lists depending on the related Section of a pane.

Consider two Sections main and aside and a page with three related panes, two of them related to main and the other one to aside. Then the content of theses panes are stored in two lists which are stored in a dictionary with the Section-names as keys. The dictionary then is stored in the Context with the key sections. Taking the above example the following template will render the content from the panes in different parts of the template depending whether they are related to the sections main or aside:

<section class="main">
    {% for content in sections.main %} {{ content }} {% endfor %}
</section>
<aside>
    {% for content in sections.aside %} {{ content }} {% endfor %}
</aside>

Note: The section- and aside-tags are just HTML 5 and unrelated to the Context.

The following snippet will iterate over all sections:

{% for name, pane_contents in sections.items %}
    <section id="{{ name }}">
        <p>section: {{ name }}</p>
        {% for content in pane_contents %}{{ content }}{% endfor %}
    </section>
{% endfor %}

Abstracts

An abstract is a short summary of some content. In django-neon content is stored by panes. Panes can optionally hold an abstract from their own content or creating one using the first two paragraphs of the content.

This abstract can get accessed from the page holding the pane by using the template variable {{ page.abstract }}. If the content of the page is given by multiple panes, the abstract from the pane with the highest order_id will get rendered.

A usecase for this can be a page with subpages all holding longer articles (the content). The abstracts of these articles should be rendered on the parent-page. Here is an example code for doing this:

{% for subpage in page.subpages %}
<p>
    {{ subpage.name }}<br />
    {{ subpage.abstract }}<br />
    <a href="{{ subpage.url }}">more…</a>
</p>
{% endfor %}

The pageis the current page-object and the call to page.subpages will return a list of page-objects. This call will also make a request to the database, which is different for page.children or page.breadcrumbs returning cached informations about page-objects (like name or url) but not the objects themself.