Panes are content-containers. Every pane refers to a page, multiple panes can refer to the same or to different pages.


The above image show three panes (the smaller rectangles to the right). Two of them refering to the root-page and the other one refering to a child-page. The content of the first two panes will be rendered on the root-page, the content of the other one will get rendered at the child-page.

Panes can be added from the admin backend and have the following attributes:

Add a pane

The name of the pane. This is only used in the administration backend.
Page-list to choose from. The content of the pane will get rendered on this page. By changing these relation panes can easily moved around between pages.
Section-list to choose from. At least one section have to be defined to render content on pages. (Refer to Templates to read more about sections.)
Only active panes will be published. Default value is False.
Start publishing:
This value is optional. If given the pane will not get published before this date.
Stop publishing:
This value is optional. If given the pane will not get published after this date.
Sort order:
Integer used for sorting. If more than one pane refers to a page, the content of the panes get rendered in descending order: panes with higher id are rendered first.
A text-field containing text to be processed. Processing is done when the pane is saved. The result is the content of the pane to be viewed on the related page. How the text is processed depends on the Markup.
Option-list of available processing methods. Defaults to Plain and dynamic.
If internationalisation is activated (USE_I18N = True in the settings) then this field shows an option-list of available languages.
Use MediaDB:
Flag indicating the content should also processed for references to the Media Database
This is a text-field like the content but should hold an optional abstract of the content. The abstract is rendered with the same markup as the content. If a template requests for an abstract of this pane but no abstract is given, the first two paragraphs of the content will get rendered with the chosen markup and used as abstract. See Templates for an example for using abstracts.


The content in django-neon is based on lightweight markup. These Markup-Languages have several advantages:

  • The author only has to care about structure, not the formatting
  • The formatting of the content is consistent
  • The text is easy to read with all editors
  • No HTML is used, which is error-prone if done manually

Note: Strictly speaking HTML is also a kind of markup, but not one of the user friendly lightweight ones. There is also a disadvantage about using markup: it's not WYSIWYG. Users just knowing Word will miss this. However: rich text editors work with HTML on the client side which may cause trouble (sooner or later).


With plain the pane does not process the content. The content will get published as is. HTML-formatting is not possible.


To use reStructuredText run pip install docutils or conda install docutils depending on the used environment. reStructuredText will get activated without any further configuration. The content will now get processed according to docutils.

Accessing the Media Database

django-neon comes with some preprocessing for docutils to get access to the Media Database.

For referring to an image the docutils-directive is followed by a path to the image-file. In django-neon the directive can written as

.. image:: [image-name]
   :class: right;

where image-name is the name of an image from the Media Database and right may be defined in the according css for the corresponding positioning.

References to documents from the Media Database or links to other pages from a django-neon application can be made by the syntax of embedded URIs:

`link text <doc:documentname>`_ -> `link text <url/to/document>`_
`link text <page:pagename>`_ -> `link text <url>`_

If the source of a document is prepended by 'doc:' then the documentname is searched in the Media Database. On success the URI of the document is used. Same works for references to other pages by using the page-name prepended by 'page:'.

Pygments support

To use pygments run pip install pygments or conda install pygments. Once pygments is installed it can be used with reStructuredText:

.. sourcecode:: Language

    The source code here

Language is the name of the language to format (like Python, Haskell etc.). For a full list refer to


To use Markdown run pip install markdown or conda install markdown depending on the used environment. Markdown will get activated without any further configuration. The content will now get processed by the rules of markdown. django-neon has some extensions added and some existing ones enabled for Markdown:

Accessing the Media Database

Links to files from the Media Database or to other pages use a slightly modified Markdown url inline syntax:

[!][alt text](img:imagename)
[link text](doc:documentname)
[link text](page:pagename)

If the corresponding image-, document- or page-names could be found, then the images and files from the Media Database are used. In case of 'page' a link to the mentioned page is inserted. All names are case-sensitive.

Attribute list extension

The Attribute Lists extension adds a syntax to define attributes on the various HTML elements in markdown’s output, as is described by the Attribute Lists Documentation.

Definition list extension

Add definition lists according to the documentation.

Div wrapper extension

In addition to the attribute list extension this one enables the wrapping of multiple elements in an enclosing div-element:

[class: class1 class2 ...]
    here comes enclosed content

will produce

<div class="class1 class2">
    <p>here comes enclosed content</p>

All indented lines following the [class:] statement will get wrapped.

Table extension

django-neon comes with an enhanced table extension as the standard Table Extension does not allow adding attributes to the <table>-tag. django-neon allows this with a preceeding class statement:

| First Header  | Second Header |
| ------------- | ------------- |
| Content Cell  | Content Cell  |
| Content Cell  | Content Cell  |

This will generate a class-attribute <table class="table"> which can get handy when using a CSS-Framework like bootstrap or Foundation.

Pygments support

To use pygments run pip install pygments or conda install pygments. Once pygments is installed it can be used with markdown:

The source code here

Language is the name of the language to format (like Python, Haskell etc.). For a full list refer to


Panes can publish dynamic content. For this chose dynamic as Markup. In this case a pane does not return it's content on rendering. Instead the pane sends a special signal get_dynamic_pane_content. Functions in other application of the project can be registered for this signal: every function decorated by

@receiver(get_dynamic_pane_content, sender=Pane)

will get called when a pane with the markup-attribute 'dynamic' should return it's content as a valid html-fragment.

Here is a code example for a function returning dynamic content:

from django_neon.processing.plugin import receiver, get_dynamic_pane_content, Pane
@receiver(get_dynamic_pane_content, sender=Pane)
def make_pane_content(sender, pane, request, **kwargs):
content = 'test content'
if == 'dynamic':
# ignore other dynamic panes
content = str(request.META)
return content

The function gets three arguments: sender, pane and request. The 'sender' is of type 'Pane' as filtered by the decorator. The 'pane' is an instance of the pane-object that gets rendered and the 'request' is the request-object.

The function has access to all attributes of the pane-instance. In this example the function tests for the panes name to be set to 'dynamic' to return some special content (in this example just the request META informations). The function may also inspect the content field of the pane to do some special handling. This is important because every function registered for receiving get_dynamic_pane_content signals will get called from every dynamic pane that gets rendered. This way functions can decide whether to return some kind of result or no result at all, depending on the pane-instance sending the signal.

Note: The return value of such a function gets publish "as is" without any kind of filtering. It is ok to return an HTML fragment. But if this fragment is erroneous it may corrupt the output of the website.


django-neon supports multiple languages. To activate this set USE_I18N to True and adjust the according values in the settings-file. For example:

    # file:
# Internationalization:
('de', _('German')),
('en', _('English')),
('fr', _('French')),
USE_I18N = True
USE_L10N = True

In this case the language options of a pane shows the languages defined by LANGUAGES in the settings:

language choices

If a User visits a page with a given language preference only panes with the according language code will be shown.

Selecting a language is optional, as by choosing the first option ---- will set the pane as language neutral. Language neutral panes will get rendered regardless of the choosen language.

For example consider a page with four panes. Three of the panes with different language codes (i.e. de, en, fr ) and the fourth one language neutral. Depending on the language a user has selected just two panes will get rendered: the one with the according language code and the language neutral one.

For more information how internationalization is handled by django refer to the django documentation.