The blog application for django CMS providing multilingual blog functionality with advanced content management features
—
Full django CMS integration including CMS app configuration, plugins for embedding blog content, wizards for content creation, toolbar integration, and menu system.
from typing import Dict, Any, List, Type, Optional
from django.db.models import QuerySet
from django.http import HttpRequest
from django.contrib.auth.models import AbstractUser
from cms.app_base import CMSConfigApp
from cms.plugin_base import CMSPluginBase
from cms.models import CMSPlugin, Placeholder
from cms.wizards.wizard_base import Wizard
from cms.menu_bases import CMSAttachMenu
from cms.menus import NavigationNode
from cms.middleware.utils import get_language_from_request
from djangocms_blog.models import Post, BlogCategory
from djangocms_blog.cms_apps import BlogApp
from djangocms_blog.cms_plugins import (
BlogLatestEntriesPlugin, BlogFeaturedPostsPlugin,
BlogAuthorPostsPlugin, BlogTagsPlugin, BlogCategoryPlugin
)
from djangocms_blog.cms_wizards import PostWizard, PostWizardForm
from djangocms_blog.cms_menus import BlogCategoryMenu, BlogNavModifierMain CMS application class providing blog functionality as a django CMS apphook.
class BlogApp(AutoCMSAppMixin, CMSConfigApp):
"""
Main CMS application for blog functionality.
Features:
- Apphook integration with django CMS
- URL namespace support
- App configuration support
- Auto-setup functionality
"""
name: str = 'Blog'
app_name: str = 'djangocms_blog'
app_config: Type[BlogConfig] = BlogConfig
def get_urls(self, page=None, language=None, **kwargs) -> List[URLPattern]:
"""Return URL patterns for blog app."""
def get_configs(self) -> QuerySet:
"""Return available blog configurations."""Complete set of CMS plugins for embedding blog content in CMS pages.
class BlogPlugin(CMSPluginBase):
"""
Base plugin for blog-related functionality.
Features:
- Template selection
- Cache support
- App configuration filtering
"""
module: str = 'Blog'
cache: bool = True
def render(self, context: Dict[str, Any], instance: CMSPlugin, placeholder: Placeholder) -> Dict[str, Any]:
"""Render plugin with context."""
class BlogLatestEntriesPlugin(BlogPlugin):
"""
Plugin for displaying latest blog entries.
Configuration options:
- Number of posts to display
- Tag filtering
- Category filtering
- Template selection
"""
name: str = 'Latest Blog Articles'
model: Type[LatestPostsPlugin] = LatestPostsPlugin
form: Type[LatestEntriesForm] = LatestEntriesForm
render_template: str = 'djangocms_blog/plugins/latest_entries.html'
def render(self, context: Dict[str, Any], instance: LatestPostsPlugin, placeholder: Placeholder) -> Dict[str, Any]:
"""Add latest posts to context."""
class BlogLatestEntriesPluginCached(BlogLatestEntriesPlugin):
"""Cached version of latest entries plugin."""
cache: bool = True
ttl: int = 3600 # 1 hour cache
class BlogFeaturedPostsPlugin(BlogPlugin):
"""
Plugin for displaying featured posts.
Configuration options:
- Number of featured posts
- Template selection
"""
name: str = 'Featured Blog Articles'
model: Type[FeaturedPostsPlugin] = FeaturedPostsPlugin
render_template: str = 'djangocms_blog/plugins/featured_posts.html'
class BlogFeaturedPostsPluginCached(BlogFeaturedPostsPlugin):
"""Cached version of featured posts plugin."""
cache: bool = True
ttl: int = 3600
class BlogAuthorPostsPlugin(BlogPlugin):
"""
Plugin for displaying posts by author.
Configuration options:
- Author selection
- Number of posts
- Template selection
"""
name: str = 'Author Blog Articles'
model: Type[AuthorEntriesPlugin] = AuthorEntriesPlugin
form: Type[AuthorPostsForm] = AuthorPostsForm
render_template: str = 'djangocms_blog/plugins/authors_posts.html'
class BlogAuthorPostsListPlugin(BlogAuthorPostsPlugin):
"""List version of author posts plugin."""
name: str = 'Author Blog Articles List'
render_template: str = 'djangocms_blog/plugins/authors_posts_list.html'
class BlogTagsPlugin(BlogPlugin):
"""
Plugin for displaying blog tags.
Features:
- Tag cloud display
- Popular tags
- Template customization
"""
name: str = 'Tags'
model: Type[GenericBlogPlugin] = GenericBlogPlugin
render_template: str = 'djangocms_blog/plugins/tags.html'
class BlogCategoryPlugin(BlogPlugin):
"""
Plugin for displaying blog categories.
Features:
- Category list display
- Hierarchical categories
- Post counts
"""
name: str = 'Categories'
model: Type[GenericBlogPlugin] = GenericBlogPlugin
render_template: str = 'djangocms_blog/plugins/categories.html'
class BlogArchivePlugin(BlogPlugin):
"""
Plugin for blog archive.
Features:
- Date-based archive
- Post counts by date
- Archive navigation
"""
name: str = 'Archive'
model: Type[GenericBlogPlugin] = GenericBlogPlugin
render_template: str = 'djangocms_blog/plugins/archive.html'CMS wizards for creating blog content directly from the django CMS interface.
class PostWizardForm(PostAdminFormBase):
"""
Form for post creation wizard.
Fields:
- title: CharField
- abstract: CharField (optional)
- categories: ModelMultipleChoiceField
- tags: CharField (optional)
- publish: BooleanField
"""
class Meta:
model: Type[Post] = Post
fields: List[str] = ['title', 'abstract', 'categories', 'tags']
class PostWizard(Wizard):
"""
Wizard for creating blog posts.
Features:
- Step-by-step post creation
- Category and tag assignment
- Automatic slug generation
- Publication options
"""
title: str = 'New Blog Post'
weight: int = 200
form: Type[PostWizardForm] = PostWizardForm
model: Type[Post] = Post
template_name: str = 'cms/wizards/post.html'
def user_has_add_permission(self, user: AbstractUser, **kwargs) -> bool:
"""Check if user can create posts."""
def get_success_url(self, obj: Post, **kwargs) -> str:
"""Return success URL after post creation."""CMS menu integration for blog navigation.
class BlogCategoryMenu(CMSAttachMenu):
"""
CMS menu for blog categories.
Features:
- Automatic category menu generation
- Hierarchical category display
- Multi-language support
"""
name: str = 'Blog Categories Menu'
def get_nodes(self, request: HttpRequest) -> List[NavigationNode]:
"""Generate menu nodes for categories."""
class BlogNavModifier(Modifier):
"""
Navigation modifier for blog functionality.
Features:
- Breadcrumb modification
- Active state handling
- Category navigation enhancement
"""
def modify(self, request: HttpRequest, nodes: List[NavigationNode], namespace: str, root_id: str, post_cut: bool, breadcrumb: bool) -> List[NavigationNode]:
"""Modify navigation nodes for blog integration."""Django CMS toolbar integration for blog management.
# Toolbar functionality is automatically integrated
# and provides:
# - "Create Post" button in toolbar
# - "Edit Post" button when viewing posts
# - Blog configuration access
# - Category management shortcuts# Using blog as CMS apphook
# 1. Create a CMS page
# 2. In Advanced Settings, set Application to "Blog"
# 3. Choose blog configuration
# 4. The page will display blog content
# Adding plugins to CMS pages
from cms.api import add_plugin
from cms.models import Placeholder
# Add latest posts plugin
plugin = add_plugin(
placeholder=placeholder,
plugin_type='BlogLatestEntriesPlugin',
language='en',
latest_posts=5,
template='djangocms_blog/plugins/latest_entries.html'
)
# Add featured posts plugin
featured_plugin = add_plugin(
placeholder=placeholder,
plugin_type='BlogFeaturedPostsPlugin',
language='en',
featured_posts=3
)
# Custom plugin templates
# Create custom templates in:
# templates/djangocms_blog/plugins/custom_latest_entries.html
# Using wizards programmatically
from cms.wizards.helpers import WizardStep
from djangocms_blog.cms_wizards import PostWizard
# Customize wizard
class CustomPostWizard(PostWizard):
title = 'Create Custom Blog Post'
def user_has_add_permission(self, user, **kwargs):
return user.has_perm('djangocms_blog.add_post')
# Menu integration usage
# In CMS page advanced settings:
# - Set "Attached menu" to "Blog Categories Menu"
# - Categories will appear as sub-navigation
# Toolbar customization
from cms.toolbar_base import CMSToolbar
from cms.toolbar_pool import toolbar_pool
@toolbar_pool.register
class CustomBlogToolbar(CMSToolbar):
def populate(self):
if self.request.user.has_perm('djangocms_blog.add_post'):
menu = self.toolbar.get_or_create_menu('blog-menu', 'Blog')
menu.add_sideframe_item('Create Post', url='/admin/djangocms_blog/post/add/')
menu.add_break()
menu.add_sideframe_item('Manage Categories', url='/admin/djangocms_blog/blogcategory/')Install with Tessl CLI
npx tessl i tessl/pypi-djangocms-blog