Posts¶
A post is like a page but while a page may exist by itself a post is always assigned to a page and cannot exist by itself without a page as its parent.
Usually many posts are assigned to the same page.
This pattern can be found in many different scenarios such as blog posts, services, case studies, news articles etc.
In order to use posts, a new type of post must be declared first. We will create a new class describing news articles. The idea is that we can then assign all news articles to a particular News page that is dedicated to list all news – although there is no reason why you could not have multiple pages that are hosting news posts.
from cubane.cms.models import Post
class NewsArticle(Post):
class Meta:
ordering = ['-published_on']
@classmethod
def get_form(cls):
from myapp.forms import NewsArticleForm
return NewsArticleForm
The model is declared like a page but derived from
cubane.cms.models.Post
instead of
cubane.cms.models.BaseAbstract
. The default ordering is based on
published_on
, so that newest articles are naturally presented first.
Like a page, the news article model also requires the declaration of a corresponding form:
from cubane.cms.forms import PostForm
class NewsArticleForm(PostForm):
class Meta:
model = NewsArticle
fields = '__all__'
And that’s it. The content management system will automatically generate the corresponding sections in the backend system to manage news articles.
In order to use them, at least one page needs to be created and configured to host news articles. Once this has been done, any number of news articles can be assigned to such page.
See also
Posts share most properties of regular pages. Please refer to section Pages for more information about pages.
Post Listing¶
When rendering a page, a number of additional template variables will be made available automatically if the page has one or more posts assigned to it:
posts
A queryset describing a list of all posts that are assigned to the current page and are not disabled.
paged_posts
A default pagination object that provides a paged view onto all posts that are assigned to the current page. Pagination options such as page size can be configured through the backend system by content editors.
post_slug
The name of the underlying post class as a slug value. This may be used in combination with the{% posts %}
template tag as part of thecms_tags
template library as described in this section.
The template tag {% posts %}
can render a list of all posts (if any) as a
paginated list of records. If the {% posts %}
template tag is used then a
new template file must be created that matches the name of the corresponding
post class (as a slug):
cubane/cms/posts/<post_slug>.html
Replace the term <post_slug>
with the slug of the name of the class that
represents a post. Then the template should render a paginated list of items.
For example, if slug for our class NewsArticle
is newsarticle
,
therefore we would need to create the following template file:
cubane/cms/posts/newsarticle.html
The base template cubane/cms/posts/base.html can be extended to simplify the structure:
{% extends 'cubane/cms/posts/base.html' %}
{% load media_tags %}
{% block listing %}
{% if posts %}
<div class="posts">
{% for post in posts %}
<a class="post" href="{{ post.url }}" title="{{ post.title }}">
<div class="post-title">{{ post.title }}</div>
<div class="post-excerpt">{{ child_page.excerpt }}</div>
</a>
{% endfor %}
</div>
{% endif %}
{% endblock %}
The base template renders markup related to pagination while the listing
block can be overridden in order to customise the structure of each post.
Usually, a link is rendered for each post, containing the title and a short excerpt text.
Note
You do not necessarily have to follow this pattern, but keep in mind that content editors can configure via the CMS settings if and how the listing for a particular type of posts is paginated and your solution should respect such configuration.
Post URLs¶
The URL of a post is the combination of the slug of the corresponding page and
the post itself. For example, if the page has the slug news
and a
particular post has the slug my-first-post
then the resulting URL for the
post is:
/news/my-first-post/
Please note that changing page ownership for a post consequently changes the URL of the post.
The URL pattern is different if the hosting page is the homepage: Then the
resulting URL for the post with the slug my-first-post
is:
/my-first-post/
You cannot create two posts with the same slug that are assigned to the same page. Also, if the assigned page is the homepage, the slug cannot match any existing page either.