Templates and regions¶
The build-your-CMS guide only used one region and one template. However, this isn’t sufficient for many sites. Some sites have a moodboard region and maybe a sidebar region; some sites at least have a different layout on the home page and so on.
More regions¶
django-content-editor requires a regions
attribute or property on
the model containing a list of Region
instances. The
Build your CMS guide presented a page model with only a single
region, "main"
. It is of course possible to specify more regions:
class Page(AbstractPage):
regions = [
Region(key="main", title=_("Main")),
Region(key="sidebar", title=_("Sidebar"), inherited=True),
]
Regions may also be marked as inherited
. This means that pages
deeper down in the tree may inherit content from some other page
(normally the page’s ancestors) in case the page region itself does not
define any content.
The page_detail
view presented in the guide also works with more
than one region. However, for region inheritance to work you have to
provide the pages whose content should be inherited yourself. There
isn’t much to do though, just add the inherit_from
keyword argument:
# Inside a view or middleware:
page = ...
return render(
request,
"pages/standard.html",
{
"page": page,
"page_regions": renderer.regions_from_item(
page,
inherit_from=page.ancestors().reverse(),
),
},
)
page.ancestors().reverse()
returns ancestors ordered from the page’s
parent to the root of the tree. We want pages to inherit content from
their closest possible ancestors.
Making templates selectable¶
As written in the introduction above, sometimes a single template or
layout isn’t enough. Enter the PageTypeMixin
:
from django.utils.translation import gettext_lazy as _
from content_editor.models import Region
from feincms3.applications import PageTypeMixin, TemplateType
from feincms3.pages import AbstractPage
class Page(AbstractPage, PageTypeMixin):
TYPES = [
TemplateType(
key="standard",
title=_("standard"),
template_name="pages/standard.html",
regions=[
Region(key="main", title=_("Main")),
],
),
TemplateType(
key="with-sidebar",
title=_("with sidebar"),
template_name="pages/with-sidebar.html",
regions=[
Region(key="main", title=_("Main")),
Region(key="sidebar", title=_("Sidebar"), inherited=True),
],
),
]
The regions
attribute is provided by the PageTypeMixin
and must be
removed from the Page
definition. Additionally, the PageTypeMixin
provides a type
property returning the currently selected page type.
Instead of hard-coding the template we should now change the page_detail
view to render the selected template, page.type.template_name
:
# Inside a view or middleware:
page = ...
return render(
request,
page.type.template_name,
{
"page": page,
"page_regions": renderer.regions_from_item(
page,
inherit_from=page.ancestors().reverse(),
),
},
)