Contents and Regions
Regions
The included Contents class and its helpers (contents_*) and
the ContentEditor admin class expect a regions attribute or
property (not a method) on their model which returns a list of Region instances.
Regions have the following attributes:
title: Something nice, will be visible in the content editor.key: The region key, used in the content proxy as attribute name for the list of plugins. Must contain a valid Python identifier."regions"and names starting with an underscore cannot be used. The recommendation is to use"main"when you only have a single region and no better idea.inherited: Only has an effect if you are using theinherit_fromargument tocontents_for_item: Model instances inherit content from their other instances if a region withinherited = Trueis empty.
You are free to define additional attributes – simply pass them when instantiating a new region.
Example:
from content_editor.models import Region
class Article(models.Model):
title = models.CharField(max_length=200)
regions = [
Region(key="main", title="Main content"),
Region(key="sidebar", title="Sidebar", inherited=True),
]
Contents class and helpers
The content_editor.contents module offers a few helpers for
fetching content blocks from the database. The Contents class
knows how to group content blocks by region and how to merge
contents from several main models. This is especially useful in
inheritance scenarios, for example when a page in a hierarchical
page tree inherits some aside-content from its ancestors.
Note
Historical note
The Contents class and the helpers replace the monolithic
ContentProxy concept in FeinCMS.
Contents class
Simple usage is as follows:
from content_editor.contents import Contents
article = Article.objects.get(...)
c = Contents(article.regions)
for item in article.app_richtext_set.all():
c.add(item)
for item in article.app_download_set.all():
c.add(item)
# Returns a list of all items, sorted by the definition
# order of article.regions and by item ordering
list(c)
# Returns a list of all items from the given region
c["main"]
# or
c.main
# How many items do I have?
len(c)
# Inherit content from the given contents instance if one of my
# own regions is empty and has its "inherited" flag set.
c.inherit_regions(some_other_contents_instance)
# Plugins from unknown regions end up in _unknown_region_contents:
c._unknown_region_contents
For most use cases you’ll probably want to take a closer look at the
following helper methods instead of instantiating a Contents class
directly:
contents_for_items
Returns a contents instance for a list of main models:
articles = Article.objects.all()[:10]
contents = contents_for_items(
articles,
plugins=[RichText, Download],
)
something = [
(article, contents[article])
for article in articles
]
contents_for_item
Returns the contents instance for a given main model (note that this
helper calls contents_for_items to do the real work):
# ...
contents = contents_for_item(
article,
plugins=[RichText, Download],
)
It is also possible to add additional items for inheriting regions. This is most useful with a page tree where i.e. sidebar contents are inherited from ancestors (this example uses methods added by django-tree-queries as used in feincms3):
page = ...
contents = contents_for_item(
page,
plugins=[RichText, Download],
page.ancestors().reverse(), # Prefer content closer to the
# current page
)