Frontend development with django CMS - best practices
Building a frontend these days is more than simply creating some markup and styling.
New tools such as Node, NPM and Gulp are just a few of the vast array of components at the modern frontend developer’s disposal. We recently published an article describing modern JavaScript management here at Divio.
The way we do things at Divio is just one of many possible ways to set up a project.The CMS itself needs to be flexible enough to make it possible to do it all the other ways too, whatever the tools you want to use.
In fact, django CMS has been designed not to get in your way. It allows for almost any combination of tools or custom project set-up. If you are unhappy with the name “static”, just rename it to whatever fits your needs. If you want to have a separate folder for your distribution files, just add “dist” to your settings. Even if you’re unhappy with “templates”, you can change that too. Nothing is off-limits.
There are however some best practices we would like to recommend, based on the experience of developing - and maintaining - a vast number of django CMS sites over the years. These rules - which you’re free to break, ignore or improve upon - make our lives easier and will help you too.
The Toolbar - Sticky Headers
The toolbar appears at on top of your site’s pages. It can be distracting, especially if it obscures the menu or the disclosure control on the right overlaps an important element in your user interface. We provide a helper class, attached to the <html>
element, to help you control the way the toolbar is displayed:
cms-toolbar-expanded
is added when the toolbar is visible (expanded). This allows you to move any sticky element of your website down according to the size of the toolbar (46px). It is removed again once you hide it.
Edit View - Content Oddities
In order to make content editable in edit view (double-click to edit), we wrap every plugin into separate <div>
containers. This can be a problem if you have a structure using a <ul>
plugin followed by separate <li>
plugins:
<ul>
<li> … </li>
<li> … </li>
</ul>
This would be rendered in the edit view as:
<div class="cms-plugin">
<ul>
<div class="cms-plugin">
<li> … </li>
</div>
<div class="cms-plugin">
<li> … </li>
</div>
</ul>
</div>
This can have some awkward effects when viewing the page. For example, if your CSS styles refer to your list items as ul > li, then in edit view they will be missed (they are now ul > div > li). So, we avoid specificity of this kind, and use classes instead:
<ul class="list">
<li class="list-item"> … </li>
<li class="list-item"> … </li>
</ul>
(This is of course best practice for CSS architecture in general anyway - but all the same, we’re working towards a way of removing this kind of element intrusion in the future.)
Managing Content - Templates, Placeholders and Page Types
The CMS provides various mechanics for managing content.
The first one is “Templates”. These are traditionally created by frontend developers and added to the settings, for a user to select from the toolbar or in Page settings. Templates provide a basic structure with predefined placeholder areas. This is one way of limiting the structural capabilities when adding plugins. A simple template could contain only one page-wide placeholder; a complex one could define several, that divide the page into multiple rows and columns.
Placeholders come in two flavours, regular ones:
and static placeholders:
Static placeholders are indicated by the pin icon shown to the right of the name.
Regular placeholders hold unique content - content that is unique to each page that contains the placeholder. The content in static placeholders in the other hand, is displayed in every page that contains the placeholder.
Another one is “Page Types”. Creating different pages can be tedious, especially when you need to creating the same structure from scratch, repeatedly. For this you can create a preset called “Page Type” within the toolbar menu from “Page” > “Save as Page Type...”. This creates a new hidden page in the pagetree:
(The pagetree as shown above, will be featured in 3.3 – stay tuned for the release)
You have the option to select these pages when creating a new page:
These pages can also still be edited / adapted as a “Page Type” behaves the same way as a regular page, except for that it is not shown within the menu.
WYSIWYG - CKEditor
At the heart of using your CMS is the business of actually writing content. If your WYSIWYG (What You See Is What You Get) editor is not set up well, this can be more awkward than it needs to be.
To improve matters, add your site’s CSS into the editor using the CKEDITOR_SETTINGS. This allows for a much more representative WYSIWYG experience.
Adding styles to the CKEditor wholesale can have side-effects. For example if your CSS defines body { background: #000; }
the CKEditor background will then also turn black. If this is an issue, styles can be reset manually.
You can also modify the styles output in the CKEditor dropdown to match your needs. Simply reference a JavaScript settings file and add your own styles.
Managing Assets
In the old days, we had one index.html file that loaded JavaScript and stylesheets all at once. Today we can easily separate and bundle those files; Require.js and webpack make this easier still. Sometimes though you still need to load assets on a for particular cases.. For this, we use sekizai tags. The CMS requires you to define two specific markup tags:
{% render_block "css" %}
and
{% render_block "js" %}
They both render either JavaScript or stylesheets wherever they are placed. You can register code with those placeholders by using addtoblock:
{% addtoblock "js" %}
<script>alert('hello world');</script>
{% endaddtoblock %}
- and they will be automatically added to the render_block area. This allows you to have different assets loaded on different pages alongside the standard bundle. You can even create new “render_block” names, for example {% render_block "js_footer" %}
together with the appropriate addtoblock identifier.
Sekizai is very powerful and allows for a variety of structure and asset placements.
Conclusion
While django CMS offers a lot of freedom, some best practices are worth knowing about. Giving users the absolute freedom on content creation can lead to too many varieties of pages and layouts. Giving structure through templates and page types can help a great deal. It is sometimes better to provide appropriate editing tools and classes within the WYSIWYG than yet another class that you have to wrap into another plugin.
A structural and modular setup of your frontend can also help you. Make use of your CSS frameworks standards and also follow best practices there. If you have a grid available to you use it rather than creating your own - while still implementing the default. Reuse classes, keep markup simple and DRY (don’t repeat yourself).