Placeholders template tag

The placeholder template tag is what make Django Basic CMS special. The workflow is that you design your template first according to the page design. Then you put placeholder tag where you want dynamic content.

For each placeholder you will have a corresponding field appearing automaticaly in the administration interface. You can make as many templates as you want, even use the template inheritance: this CMS administration will still behave as intended.

The syntax for a placeholder tag is the following:

{% placeholder <name> [on <page>] [with <widget>] [parsed] [inherited] [as <varname>] %}

Detailed explanations on placeholder options

the on option

If the on option is omitted the CMS will automatically take the current page (by using the current_page context variable) to get the content of the placeholder.

Template syntax example:

{% placeholder main_menu on root_page %}

the widget option

The widget option is used to change the placeholders widgets in the administration interface.

By default the CMS will use a simple TextInput widget. Otherwise the CMS will use the widget of your choice. Widgets need to be registered before you can use them in the CMS:

from basic_cms.widgets_registry import register_widget
from django.forms import TextInput

class NewWidget(TextInput):


Template syntax example:

{% placeholder body with NewWidget %}


This CMS is shipped with a list of useful widgets .

The as option

If you use the option as the content of the placeholder content will not be displayed: a variable of your choice will be defined within the template’s context.

Template syntax example:

{% placeholder image as image_src %}
<img src="{{ img_src }}" alt=""/>

The parsed keyword

If you add the keyword parsed the content of the placeholder will be evaluated as Django template, within the current context. Each placeholder with the parsed keyword will also have a note in the admin interface noting its ability to be evaluated as template.

Template syntax example:

{% placeholder special-content parsed %}

The inherited keyword

If you add the keyword inherited the placeholder’s content displayed on the frontend will be retrieved from the closest parent. But only if there is no content for the current page.

Template syntax example:

{% placeholder right-column inherited %}

The untranslated keyword

If you add the keyword untranslated the placeholder’s content will be the same whatever language your use. It’s especialy useful for an image placeholder that should remain the same in every language.

Template syntax example:

{% placeholder logo untranslated %}

Examples of other valid syntaxes

This is a list of different possible syntaxes for this template tag:

{% placeholder title with TextIntput %}
{% placeholder logo untranslated on root_page %}
{% placeholder right-column inherited as right_column parsed %}

<div class="my_funky_column">{{ right_column|safe }}</div>

Image placeholder

There is a special placeholder for images:

{% imageplaceholder body-image as imgsrc %}
{% if imgsrc %}
    <img src="{{ MEDIA_URL }}{{ imgsrc }}" alt=""/>
{% endif %}

A file upload field will appears into the page admin interface.

File placeholder

There is also a more general placeholder for files:

{% fileplaceholder uploaded_file as filesrc %}
{% if filesrc %}
    <a href="{{ MEDIA_URL }}{{ filesrc }}">Download file</a>
{% endif %}

A file upload field will appears into the page admin interface.

Contact placeholder

If you want to include a simple contact form in your page, there is a contact placeholder:

{% contactplaceholder contact %}

This placeholder use ´settings.ADMINS´ for recipients email. The template used to render the contact form is ´pages/contact.html´.

Create your own placeholder

If you want to create your own new type of placeholder, you can simply subclass the PlaceholderNode:

from basic_cms.placeholders import PlaceholderNode
from basic_cms.templatetags.page_tags import parse_placeholder
register = template.Library()

class ContactFormPlaceholderNode(PlaceholderNode):

    def __init__(self, name, *args, **kwargs):

    def get_widget(self, page, language, fallback=Textarea):
        """Redefine this to change the widget of the field."""

    def get_field(self, page, language, initial=None):
        """Redefine this to change the field displayed in the admin."""

    def save(self, page, language, data, change):
        """Redefine this to change the way to save the placeholder data."""

    def render(self, context):
        """Output the content of the node in the template."""

def do_contactplaceholder(parser, token):
    name, params = parse_placeholder(parser, token)
    return ContactFormPlaceholderNode(name, **params)
register.tag('contactplaceholder', do_contactplaceholder)

And use it in your templates as a normal placeholder:

{% contactplaceholder contact %}

Changing the widget of the common placeholder

If you want to just redefine the widget of the default PlaceholderNode without subclassing it, you can just you create a valid Django Widget that take an extra language paramater:

from django.forms import Textarea
from django.utils.safestring import mark_safe
from basic_cms.widgets_registry import register_widget

class CustomTextarea(Textarea):
    class Media:
        js = ['path to the widget extra javascript']
        css = {
            'all': ['path to the widget extra javascript']

    def __init__(self, language=None, attrs=None, **kwargs):
        attrs = {'class': 'custom-textarea'}
        super(CustomTextarea, self).__init__(attrs)

    def render(self, name, value, attrs=None):
        rendered = super(CustomTextarea, self).render(name, value, attrs)
        return mark_safe("""Take a look at \
                example.widgets.CustomTextarea<br>""") \
                + rendered


Create a file named widgets (or whathever you want) somewhere in one of your project’s application and then you can simply use the placeholder syntax:

{% placeholder custom_widget_example CustomTextarea parsed  %}

More examples of custom widgets are available in

List of placeholder widgets shipped with the CMS

Placeholder could be rendered with different widgets


A simple line input:

{% placeholder [name] with TextInput %}


A multi line input:

{% placeholder [name] with Textarea %}


A simple line input with Django admin CSS styling (better for larger input fields):

{% placeholder [name] with AdminTextInput %}


A multi line input with Django admin CSS styling:

{% placeholder [name] with AdminTextarea %}


A file browsing widget:

{% placeholder [name] with FileBrowseInput %}


The following django application needs to be installed:


A simple Rich Text Area Editor based on jQuery:

{% placeholder [name] with RichTextarea %}


A complete jQuery Rich Text Editor called wymeditor:

{% placeholder [name] with WYMEditor %}


A complete JavaScript Rich Text Editor called CKEditor:

{% placeholder [name] with CKEditor %}


markdown editor based on markitup:

{% placeholder [name] with markItUpMarkdown %}


A HTML editor based on markitup:

{% placeholder [name] with markItUpHTML %}


HTML editor based on TinyMCE

  1. You should install the django-tinymce application first

  2. Then in your settings you should activate the application:

  3. And add tinymce in your INSTALLED_APPS list.

The basic javascript files required to run TinyMCE are distributed with this CMS.

However if you want to use plugins you need to fully install TinyMCE. To do that follow carefully those install instructions


{% placeholder [name] with TinyMCE %}


Allows to edit raw html code with syntax highlight based on this project:

Basic code (Javascript, CSS) for editarea is included into the codebase. If you want the full version you can get it there:

pages/media/pages/edit_area -r29


{% placeholder [name] with EditArea %}