How to run django CMS in headless mode¶
Added in version 4.2.
Django CMS is headless-ready. This means that you can use django CMS as a backend service to provide content to the frontend technology of your choice.
Traditionally, django CMS serves the content as HTML pages. In headless mode, django CMS does not publish the html page tree. To retrieve content in headless mode you will need an application that serves the content from the CMS via an API, such as djangocms-rest.
To run django CMS in headless mode, you simply remove the catch-all URL pattern
from your projects’ urls.py
file and replace it by an API endpoint:
urlpatterns = [
path('admin/', admin.site.urls),
# path('', include('cms.urls')) # Remove this line
]
Now, django CMS will be fully accessible through the admin interface, but the frontend will not be served. Once, you add an API endpoint, this will be the only way to access the content.
Note
You can also run a hybrid mode where you serve both the HTML pages and the content via an API, say, for an app. In this case, keep the django CMS’ URLS and just add the API to your traditional project.
To add an API endpoint, you can use the djangocms-rest
package, for example.
This package provides a REST API for django CMS. To install it, run:
pip install djangocms-rest
Then, add the following to your urls.py
file:
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('djangocms_rest.urls')),
]
Note
Django CMS does not force you to use the djangocms-rest
package. You can
use any other package that provides an API for django CMS, with
a different API such as GraphQL, for example.
If you are using a different API package, you will need to follow the instructions provided by that package.
Headless using templates¶
In traditional Django CMS, placeholders are defined in the templates and they
represent the regions where your plugins (the content) will be rendered. This
is easily done via using {% placeholder "placeholder_name" %}
in your
Django templates.
If you keep the CMS_TEMPLATES
setting in your project, you still will be
using templates to render the content when editing and previewing in headless
mode. In this case, the templates will be used to identify the placeholders of
a page.
This scenario requires templates to be present in the project for the benefit of the editors only.
Headless without templates¶
However, when running Django CMS headlessly without templates, you fully decouple the front-end presentation layer (which includes templates) from the CMS, and the configuration of placeholders must be handled differently.
First, set the CMS_TEMPLATES
setting to an empty list in your
project’s settings.py
file (or remove it entirely):
CMS_TEMPLATES = []
Then, you can define the placeholders using the CMS_PLACEHOLDERS
setting:
CMS_PLACEHOLDERS = (
('single', ('content',), _('Single placeholder')),
('two_column', ('left', 'right'), _('Two columns')),
)
The CMS_PLACEHOLDERS
setting is a list of tuples. Each tuple
represents a placeholder configuration. Think of each placeholder configuration
replacing a template and providing the information on which placeholders
are available on a page: Like a template can have multiple {% placeholder %}
template tags, a placeholder configuration can contain multiple placeholders.
The first element of the configuration tuple is the name of the placeholder
configuration. It is stored in a page’s template
field. It needs to be
unique. The second element is a tuple of placeholder slots available for the
configuration. The third element is the verbose description of the placeholder
configuration which will be shown in the toolbar. You can select a page’s
placeholder configuration in the Page menu (instead of a template).
Note
CMS_PLACEHOLDERS
is only relevant, if no templates are used.
If you define templates, placeholders are inferred from the templates.
Also, do not confuse the CMS_PLACEHOLDERS
setting with the
CMS_PLACEHOLDER_CONF
setting. The latter is used to configure
individual placeholders, while the former is used to define available
placeholders for a page.
This scenario is useful when you do not want to design templates and focus on
the content structure only. Editors will see a generic representation of the
plugins in a minimally styled template. Note that the css
and js
block
of the plugin templates will be loaded also in this case.
Headless setup and app hooks¶
When running Django CMS in headless mode, you can still use app hooks to integrate your Django apps with the CMS. App hooks allow you to attach Django apps to a CMS page and render the app’s content on that page. Those apps will be served via django CMS’ url patterns.
If the app provides API endpoints itself, they will need to be included explicitly in the REST API. Please check the package you are using to create the REST API on how to do this.
Hybrid setup¶
You can also use django CMS in a hybrid setup, where you serve both the HTML pages and the content via an API. In this case, you keep the django CMS’ URLS and just add the API to your traditional project.
Be careful, however, to have the API endpoints in your project’s urls before django CMS’ catch-all HTML urls. Otherwise you run the risk of pages with the wrong path shaddowing out the API endpoints.