Install the latest stable release

$ pip install djangocms-cascade

or the current development release from github

$ pip install -e git+

Python Package Dependencies

Due to some incompatibilities in the API of Django, django-CMS and djangocms-text-ckeditor, please only use these combinations of Python package dependencies:





other combinations might work, but have not been tested.

Optional packages

If you intend to use Image, Picture, Jumbotron, or FontIcons you will have to install django-filer in addition:

$ pip install django-filer

For a full list of working requirements see the requirements folder in the sources.

Create a database schema

./ migrate cmsplugin_cascade

Install Dependencies not handled by PIP

Since the Bootstrap CSS and other JavaScript files are part of their own repositories, they are not shipped within this package. Furthermore, as they are not part of the PyPI network, they have to be installed through the Node Package Manager, npm.

In your Django projects it is good practice to keep a reference onto external node modules using the file packages.json added to its own version control repository, rather than adding the complete node package.

       cd my-project-dir
       npm init
       npm install bootstrap@3 bootstrap-sass@3 jquery@3 leaflet@1 leaflet-easybutton@2.2 picturefill select2@4 --save

If the Django project contains already a file named ``package.json``, then skip the ``npm init``

in the above command.

The node packages leaflet and leaflet-easybutton are only required if the Leaflet plugin is activated.

The node packages picturefill is a shim to support the srcset and sizes attributes on <img ... /> elements. Please check browser support if that feature is required in your project.

The node packages select2 is required for autofilling the select box in Link plugins. It is optional, but strongly suggested.

Remember to commit the changes in package.json into the projects version control repository.

Since these Javascript and Stylesheet files are located outside of the project’s static folder, we must add them explicitly to our lookup path, using STATICFILES_DIRS in

    os.path.abspath(os.path.join(MY_PROJECT_DIR, 'node_modules')),

Using AngularJS instead of jQuery

If you prefer AngularJS over jQuery, then replace the above install command with:

npm install bootstrap@3 bootstrap-sass@3 angular@1.5 angular-animate@1.5 angular-sanitize@1.5 angular-ui-bootstrap@0.14 leaflet@1 leaflet-easybutton@2.2 picturefill select2@4  --save

Remember to point to the prepared AngularJS templates using this setting:

    'bootstrap3': {
        'template_basedir': 'angular-ui',


Add 'cmsplugin_cascade' to the list of INSTALLED_APPS in the project’s file. Optionally add ‘cmsplugin_cascade.extra_fields’ and/or ‘cmsplugin_cascade.sharable’ to the list of INSTALLED_APPS. Make sure that these entries are located before the entry cms.

Configure the CMS plugin

    'cmsplugin_cascade.clipboard',  # optional
    'cmsplugin_cascade.extra_fields',  # optional
    'cmsplugin_cascade.sharable',  # optional
    'cmsplugin_cascade.segmentation',  # optional

Activate the plugins

By default, no djangocms-cascade plugins is activated. Activate them in the project’s with the directive CMSPLUGIN_CASCADE_PLUGINS.

To activate all available Bootstrap plugins, use:

CMSPLUGIN_CASCADE_PLUGINS = ['cmsplugin_cascade.bootstrap3']

If for some reason, only a subset of the available Bootstrap plugins shall be activated, name each of them. If for example, only the grid system shall be used but no other Bootstrap plugins, then configure:

CMSPLUGIN_CASCADE_PLUGINS = ['cmsplugin_cascade.bootstrap3.container']

A very useful plugin is the LinkPlugin. It superseds the djangocms-link-plugin, normally used together with the CMS.


If this plugin is enabled ensure, that the node package select2 has been installed and findable by the static files finder using these directives in

SELECT2_CSS = 'node_modules/select2/dist/css/select2.min.css'
SELECT2_JS = 'node_modules/select2/dist/js/select2.min.js'

Generic Plugins which are not opinionated towards a specific CSS framework, are kept in a separate folder. It is strongly suggested to always activate them:


Sometimes it is useful to do a Segmentation of the DOM. Activate this by adding its plugin:


When Using Fonts with Icons: on your site, add 'cmsplugin_cascade.icon' to INSTALLED_APPS and add it to the configured Cascade plugins:


Special settings when using the TextPlugin

Since it is possible to add plugins from the Cascade ecosystem as children to the djangocms-text-ckeditor, we must add a special configuration:

from django.core.urlresolvers import reverse_lazy
from cmsplugin_cascade.utils import format_lazy

    'language': '{{ language }}',
    'skin': 'moono',
    'toolbar': 'CMS',
    'stylesSet': format_lazy('default:{}', reverse_lazy('admin:cascade_texticon_wysiwig_config')),

Restrict plugins to a particular placeholder


You must set parent_classes for your placeholder, else you won’t be able to add a container to your placeholder. This means that as an absolute minimum, you must add this to your settings:

    'content': {
        'parent_classes': {'BootstrapContainerPlugin': None,},

Unfortunately djangoCMS does not allow to declare dynamically which plugins are eligible to be added as children of other plugins. This is determined while bootstrapping the Django project and thus remains static. We therefore must somehow trick the CMS to behave as we want.

Say, our Placeholder named “Main Content” shall accept the BootstrapContainerPlugin as its only child, we then must use this CMS settings directive:

    'Main Content Placeholder': {
        'plugins': ['BootstrapContainerPlugin'],
        'text_only_plugins': ['TextLinkPlugin'],
        'parent_classes': {'BootstrapContainerPlugin': None},
        'glossary': {
            'breakpoints': ['xs', 'sm', 'md', 'lg'],
            'container_max_widths': {'xs': 750, 'sm': 750, 'md': 970, 'lg': 1170},
            'fluid': False,
            'media_queries': {
                'xs': ['(max-width: 768px)'],
                'sm': ['(min-width: 768px)', '(max-width: 992px)'],
                'md': ['(min-width: 992px)', '(max-width: 1200px)'],
                'lg': ['(min-width: 1200px)'],

Here we add the BootstrapContainerPlugin to plugins and parent_classes. This is because the Container plugin normally is the root plugin in a placeholder. If this plugin would not restrict its parent plugin classes, we would be allowed to use it as a child of any plugin. This could destroy the page’s grid.

Furthermore, in the above example we must add the TextLinkPlugin to text_only_plugins. This is because the TextPlugin is not part of the Cascade ecosystem and hence does not know which plugins are allowed as its children.

The dictionary named glossary sets the initial parameters of the Bootstrap 3 Grid system.

Define the leaf plugins

Leaf plugins are those, which contain real data, say text or images. Hence the default setting is to allow the TextPlugin and the FilerImagePlugin as leafs. This can be overridden using the configuration directive

    'alien_plugins': ['TextPlugin', 'FilerImagePlugin', 'OtherLeafPlugin'],

Bootstrap 3 with AngularJS

Some Bootstrap3 plugins can be rendered using templates which are suitable for the very popular Angular UI Bootstrap framework. This can be done during runtime; when editing the plugin a select box appears which allows to chose an alternative template for rendering.

Template Customization

Make sure that the style sheets are referenced correctly by the used templates. DjangoCMS requires Django-Sekizai to organize these includes, so a strong recommendation is to use that Django app.

The templates used for a DjangoCMS project shall include a header, footer, the menu bar and optionally a breadcrumb, but should leave out an empty working area. When using HTML5, wrap this area into an <article> or <section> element or just use it unwrapped.

This placeholder then shall be named using a generic identifier, for instance “Main Content” or similar:

{% load cms_tags %}

<!-- wrapping element (optional) -->
    {% placeholder "Main Content" %}
<!-- /wrapping element -->

From now on, the page layout can be adopted inside this placeholder, without having to fiddle with template coding anymore.