0
# CMS Integration
1
2
Full django CMS integration including CMS app configuration, plugins for embedding blog content, wizards for content creation, toolbar integration, and menu system.
3
4
## Imports
5
6
```python
7
from typing import Dict, Any, List, Type, Optional
8
from django.db.models import QuerySet
9
from django.http import HttpRequest
10
from django.contrib.auth.models import AbstractUser
11
from cms.app_base import CMSConfigApp
12
from cms.plugin_base import CMSPluginBase
13
from cms.models import CMSPlugin, Placeholder
14
from cms.wizards.wizard_base import Wizard
15
from cms.menu_bases import CMSAttachMenu
16
from cms.menus import NavigationNode
17
from cms.middleware.utils import get_language_from_request
18
from djangocms_blog.models import Post, BlogCategory
19
from djangocms_blog.cms_apps import BlogApp
20
from djangocms_blog.cms_plugins import (
21
BlogLatestEntriesPlugin, BlogFeaturedPostsPlugin,
22
BlogAuthorPostsPlugin, BlogTagsPlugin, BlogCategoryPlugin
23
)
24
from djangocms_blog.cms_wizards import PostWizard, PostWizardForm
25
from djangocms_blog.cms_menus import BlogCategoryMenu, BlogNavModifier
26
```
27
28
## Capabilities
29
30
### CMS Application
31
32
Main CMS application class providing blog functionality as a django CMS apphook.
33
34
```python { .api }
35
class BlogApp(AutoCMSAppMixin, CMSConfigApp):
36
"""
37
Main CMS application for blog functionality.
38
39
Features:
40
- Apphook integration with django CMS
41
- URL namespace support
42
- App configuration support
43
- Auto-setup functionality
44
"""
45
46
name: str = 'Blog'
47
app_name: str = 'djangocms_blog'
48
app_config: Type[BlogConfig] = BlogConfig
49
50
def get_urls(self, page=None, language=None, **kwargs) -> List[URLPattern]:
51
"""Return URL patterns for blog app."""
52
53
def get_configs(self) -> QuerySet:
54
"""Return available blog configurations."""
55
```
56
57
### CMS Plugins
58
59
Complete set of CMS plugins for embedding blog content in CMS pages.
60
61
```python { .api }
62
class BlogPlugin(CMSPluginBase):
63
"""
64
Base plugin for blog-related functionality.
65
66
Features:
67
- Template selection
68
- Cache support
69
- App configuration filtering
70
"""
71
72
module: str = 'Blog'
73
cache: bool = True
74
75
def render(self, context: Dict[str, Any], instance: CMSPlugin, placeholder: Placeholder) -> Dict[str, Any]:
76
"""Render plugin with context."""
77
78
class BlogLatestEntriesPlugin(BlogPlugin):
79
"""
80
Plugin for displaying latest blog entries.
81
82
Configuration options:
83
- Number of posts to display
84
- Tag filtering
85
- Category filtering
86
- Template selection
87
"""
88
89
name: str = 'Latest Blog Articles'
90
model: Type[LatestPostsPlugin] = LatestPostsPlugin
91
form: Type[LatestEntriesForm] = LatestEntriesForm
92
render_template: str = 'djangocms_blog/plugins/latest_entries.html'
93
94
def render(self, context: Dict[str, Any], instance: LatestPostsPlugin, placeholder: Placeholder) -> Dict[str, Any]:
95
"""Add latest posts to context."""
96
97
class BlogLatestEntriesPluginCached(BlogLatestEntriesPlugin):
98
"""Cached version of latest entries plugin."""
99
100
cache: bool = True
101
ttl: int = 3600 # 1 hour cache
102
103
class BlogFeaturedPostsPlugin(BlogPlugin):
104
"""
105
Plugin for displaying featured posts.
106
107
Configuration options:
108
- Number of featured posts
109
- Template selection
110
"""
111
112
name: str = 'Featured Blog Articles'
113
model: Type[FeaturedPostsPlugin] = FeaturedPostsPlugin
114
render_template: str = 'djangocms_blog/plugins/featured_posts.html'
115
116
class BlogFeaturedPostsPluginCached(BlogFeaturedPostsPlugin):
117
"""Cached version of featured posts plugin."""
118
119
cache: bool = True
120
ttl: int = 3600
121
122
class BlogAuthorPostsPlugin(BlogPlugin):
123
"""
124
Plugin for displaying posts by author.
125
126
Configuration options:
127
- Author selection
128
- Number of posts
129
- Template selection
130
"""
131
132
name: str = 'Author Blog Articles'
133
model: Type[AuthorEntriesPlugin] = AuthorEntriesPlugin
134
form: Type[AuthorPostsForm] = AuthorPostsForm
135
render_template: str = 'djangocms_blog/plugins/authors_posts.html'
136
137
class BlogAuthorPostsListPlugin(BlogAuthorPostsPlugin):
138
"""List version of author posts plugin."""
139
140
name: str = 'Author Blog Articles List'
141
render_template: str = 'djangocms_blog/plugins/authors_posts_list.html'
142
143
class BlogTagsPlugin(BlogPlugin):
144
"""
145
Plugin for displaying blog tags.
146
147
Features:
148
- Tag cloud display
149
- Popular tags
150
- Template customization
151
"""
152
153
name: str = 'Tags'
154
model: Type[GenericBlogPlugin] = GenericBlogPlugin
155
render_template: str = 'djangocms_blog/plugins/tags.html'
156
157
class BlogCategoryPlugin(BlogPlugin):
158
"""
159
Plugin for displaying blog categories.
160
161
Features:
162
- Category list display
163
- Hierarchical categories
164
- Post counts
165
"""
166
167
name: str = 'Categories'
168
model: Type[GenericBlogPlugin] = GenericBlogPlugin
169
render_template: str = 'djangocms_blog/plugins/categories.html'
170
171
class BlogArchivePlugin(BlogPlugin):
172
"""
173
Plugin for blog archive.
174
175
Features:
176
- Date-based archive
177
- Post counts by date
178
- Archive navigation
179
"""
180
181
name: str = 'Archive'
182
model: Type[GenericBlogPlugin] = GenericBlogPlugin
183
render_template: str = 'djangocms_blog/plugins/archive.html'
184
```
185
186
### Content Creation Wizards
187
188
CMS wizards for creating blog content directly from the django CMS interface.
189
190
```python { .api }
191
class PostWizardForm(PostAdminFormBase):
192
"""
193
Form for post creation wizard.
194
195
Fields:
196
- title: CharField
197
- abstract: CharField (optional)
198
- categories: ModelMultipleChoiceField
199
- tags: CharField (optional)
200
- publish: BooleanField
201
"""
202
203
class Meta:
204
model: Type[Post] = Post
205
fields: List[str] = ['title', 'abstract', 'categories', 'tags']
206
207
class PostWizard(Wizard):
208
"""
209
Wizard for creating blog posts.
210
211
Features:
212
- Step-by-step post creation
213
- Category and tag assignment
214
- Automatic slug generation
215
- Publication options
216
"""
217
218
title: str = 'New Blog Post'
219
weight: int = 200
220
form: Type[PostWizardForm] = PostWizardForm
221
model: Type[Post] = Post
222
template_name: str = 'cms/wizards/post.html'
223
224
def user_has_add_permission(self, user: AbstractUser, **kwargs) -> bool:
225
"""Check if user can create posts."""
226
227
def get_success_url(self, obj: Post, **kwargs) -> str:
228
"""Return success URL after post creation."""
229
```
230
231
### Menu Integration
232
233
CMS menu integration for blog navigation.
234
235
```python { .api }
236
class BlogCategoryMenu(CMSAttachMenu):
237
"""
238
CMS menu for blog categories.
239
240
Features:
241
- Automatic category menu generation
242
- Hierarchical category display
243
- Multi-language support
244
"""
245
246
name: str = 'Blog Categories Menu'
247
248
def get_nodes(self, request: HttpRequest) -> List[NavigationNode]:
249
"""Generate menu nodes for categories."""
250
251
class BlogNavModifier(Modifier):
252
"""
253
Navigation modifier for blog functionality.
254
255
Features:
256
- Breadcrumb modification
257
- Active state handling
258
- Category navigation enhancement
259
"""
260
261
def modify(self, request: HttpRequest, nodes: List[NavigationNode], namespace: str, root_id: str, post_cut: bool, breadcrumb: bool) -> List[NavigationNode]:
262
"""Modify navigation nodes for blog integration."""
263
```
264
265
### Toolbar Integration
266
267
Django CMS toolbar integration for blog management.
268
269
```python { .api }
270
# Toolbar functionality is automatically integrated
271
# and provides:
272
# - "Create Post" button in toolbar
273
# - "Edit Post" button when viewing posts
274
# - Blog configuration access
275
# - Category management shortcuts
276
```
277
278
## CMS Integration Examples
279
280
```python
281
# Using blog as CMS apphook
282
# 1. Create a CMS page
283
# 2. In Advanced Settings, set Application to "Blog"
284
# 3. Choose blog configuration
285
# 4. The page will display blog content
286
287
# Adding plugins to CMS pages
288
from cms.api import add_plugin
289
from cms.models import Placeholder
290
291
# Add latest posts plugin
292
plugin = add_plugin(
293
placeholder=placeholder,
294
plugin_type='BlogLatestEntriesPlugin',
295
language='en',
296
latest_posts=5,
297
template='djangocms_blog/plugins/latest_entries.html'
298
)
299
300
# Add featured posts plugin
301
featured_plugin = add_plugin(
302
placeholder=placeholder,
303
plugin_type='BlogFeaturedPostsPlugin',
304
language='en',
305
featured_posts=3
306
)
307
308
# Custom plugin templates
309
# Create custom templates in:
310
# templates/djangocms_blog/plugins/custom_latest_entries.html
311
312
# Using wizards programmatically
313
from cms.wizards.helpers import WizardStep
314
from djangocms_blog.cms_wizards import PostWizard
315
316
# Customize wizard
317
class CustomPostWizard(PostWizard):
318
title = 'Create Custom Blog Post'
319
320
def user_has_add_permission(self, user, **kwargs):
321
return user.has_perm('djangocms_blog.add_post')
322
323
# Menu integration usage
324
# In CMS page advanced settings:
325
# - Set "Attached menu" to "Blog Categories Menu"
326
# - Categories will appear as sub-navigation
327
328
# Toolbar customization
329
from cms.toolbar_base import CMSToolbar
330
from cms.toolbar_pool import toolbar_pool
331
332
@toolbar_pool.register
333
class CustomBlogToolbar(CMSToolbar):
334
def populate(self):
335
if self.request.user.has_perm('djangocms_blog.add_post'):
336
menu = self.toolbar.get_or_create_menu('blog-menu', 'Blog')
337
menu.add_sideframe_item('Create Post', url='/admin/djangocms_blog/post/add/')
338
menu.add_break()
339
menu.add_sideframe_item('Manage Categories', url='/admin/djangocms_blog/blogcategory/')
340
```