0
# Configuration
1
2
Per-apphook configuration system enabling multiple blog instances with different settings, plus global settings management and customization options.
3
4
## Capabilities
5
6
### Blog Configuration Model
7
8
Translatable configuration model for individual blog instances with per-apphook settings.
9
10
```python { .api }
11
class BlogConfig(TranslatableModel, AppHookConfig):
12
"""
13
Translatable configuration model for blog app instances.
14
15
Translated fields:
16
- app_title: CharField(max_length=234) - Application title
17
- object_name: CharField(max_length=234) - Object name for wizards
18
19
Features:
20
- Per-apphook configuration
21
- Multilingual configuration options
22
- Template and permalink customization
23
- SEO and social media settings
24
"""
25
26
translations: TranslatedFields = TranslatedFields(
27
app_title=models.CharField(_("application title"), max_length=234),
28
object_name=models.CharField(
29
_("object name"),
30
max_length=234,
31
default=get_setting("DEFAULT_OBJECT_NAME")
32
),
33
)
34
35
def get_app_title(self) -> str:
36
"""Return the application title."""
37
38
@property
39
def schemaorg_type(self) -> str:
40
"""Return schema.org type for structured data."""
41
```
42
43
### Configuration Form
44
45
Comprehensive form for blog configuration with all available settings.
46
47
```python { .api }
48
class BlogConfigForm(AppDataForm):
49
"""
50
Settings that can be changed per-apphook.
51
52
Configuration options include:
53
- Template settings
54
- Permalink configuration
55
- SEO and meta tag settings
56
- Social media integration
57
- RSS feed settings
58
- Comment settings
59
- Menu and navigation options
60
"""
61
62
# Basic settings
63
app_title: str = get_setting("AUTO_APP_TITLE")
64
object_name: str = get_setting("DEFAULT_OBJECT_NAME")
65
66
# Template settings
67
template_prefix: str = get_setting("TEMPLATE_PREFIX")
68
menu_structure: str = get_setting("MENU_TYPE")
69
menu_empty_categories: bool = get_setting("MENU_EMPTY_CATEGORIES")
70
71
# Permalink settings
72
permalink_type: str = get_setting("PERMALINK_TYPE")
73
url_patterns: str = get_setting("URL_PATTERNS")
74
75
# SEO settings
76
meta_title: str = get_setting("META_TITLE")
77
meta_description: str = get_setting("META_DESCRIPTION")
78
meta_keywords: str = get_setting("META_KEYWORDS")
79
80
# Social media settings
81
facebook_type: str = get_setting("FB_TYPE")
82
facebook_app_id: str = get_setting("FB_APP_ID")
83
twitter_type: str = get_setting("TWITTER_TYPE")
84
twitter_site: str = get_setting("TWITTER_SITE")
85
twitter_author: str = get_setting("TWITTER_AUTHOR")
86
gplus_type: str = get_setting("GPLUS_TYPE")
87
88
# RSS and feed settings
89
feed_latest_items: int = get_setting("FEED_LATEST_ITEMS")
90
feed_enable: bool = get_setting("FEED_ENABLE")
91
92
# Sitemap settings
93
sitemap_priority_default: float = get_setting("SITEMAP_PRIORITY_DEFAULT")
94
sitemap_changefreq_default: str = get_setting("SITEMAP_CHANGEFREQ_DEFAULT")
95
96
# Display settings
97
pagination: int = get_setting("PAGINATION")
98
latest_posts: int = get_setting("LATEST_POSTS")
99
multisite: bool = get_setting("MULTISITE")
100
101
# Comment settings
102
enable_comments: bool = get_setting("ENABLE_COMMENTS")
103
use_placeholder: bool = get_setting("USE_PLACEHOLDER")
104
```
105
106
### Settings Management
107
108
Global settings system with customizable defaults and runtime configuration.
109
110
```python { .api }
111
def get_setting(name: str) -> Any:
112
"""
113
Get blog setting value with fallback to defaults.
114
115
Parameters:
116
- name: Setting name to retrieve
117
118
Returns:
119
Setting value from Django settings or package default
120
121
Example settings:
122
- BLOG_PAGINATION: Number of posts per page
123
- BLOG_LATEST_POSTS: Number of latest posts to show
124
- BLOG_ENABLE_COMMENTS: Enable comment system
125
- BLOG_USE_PLACEHOLDER: Use placeholder fields
126
- BLOG_MULTISITE: Enable multisite support
127
- BLOG_MENU_TYPE: Menu structure type
128
- BLOG_PERMALINK_TYPE: Permalink pattern type
129
- BLOG_TEMPLATE_PREFIX: Template prefix for customization
130
"""
131
132
# Setting constants and choices
133
MENU_TYPE_COMPLETE: str = "complete"
134
MENU_TYPE_CATEGORIES: str = "categories"
135
MENU_TYPE_POSTS: str = "posts"
136
MENU_TYPE_NONE: str = "none"
137
138
PERMALINK_TYPE_FULL_DATE: str = "full_date"
139
PERMALINK_TYPE_SHORT_DATE: str = "short_date"
140
PERMALINK_TYPE_CATEGORY: str = "category"
141
PERMALINK_TYPE_SLUG: str = "slug"
142
143
PERMALINKS: List[Tuple[str, str]] = [
144
(PERMALINK_TYPE_FULL_DATE, _("Full date")),
145
(PERMALINK_TYPE_SHORT_DATE, _("Year / Month")),
146
(PERMALINK_TYPE_CATEGORY, _("Category")),
147
(PERMALINK_TYPE_SLUG, _("Just slug")),
148
]
149
150
PERMALINKS_URLS: Dict[str, str] = {
151
PERMALINK_TYPE_FULL_DATE: "<int:year>/<int:month>/<int:day>/<str:slug>/",
152
PERMALINK_TYPE_SHORT_DATE: "<int:year>/<int:month>/<str:slug>/",
153
PERMALINK_TYPE_CATEGORY: "<str:category>/<str:slug>/",
154
PERMALINK_TYPE_SLUG: "<str:slug>/",
155
}
156
```
157
158
### Default Settings
159
160
Complete list of configurable settings with their default values.
161
162
```python { .api }
163
# Blog behavior settings
164
BLOG_DEFAULT_PUBLISHED: bool = False
165
BLOG_UNICODE_SLUGS: bool = True
166
BLOG_MULTISITE: bool = True
167
BLOG_USE_PLACEHOLDER: bool = True
168
BLOG_USE_ABSTRACT: bool = True
169
BLOG_USE_LIVEBLOG: bool = False
170
171
# Display settings
172
BLOG_PAGINATION: int = 10
173
BLOG_LATEST_POSTS: int = 5
174
BLOG_MENU_TYPE: str = MENU_TYPE_COMPLETE
175
BLOG_MENU_EMPTY_CATEGORIES: bool = False
176
177
# Template settings
178
BLOG_TEMPLATE_PREFIX: str = 'djangocms_blog'
179
BLOG_PLUGIN_TEMPLATE_FOLDERS: List[str] = ['plugins']
180
181
# URL and permalink settings
182
BLOG_PERMALINK_TYPE: str = PERMALINK_TYPE_SLUG
183
BLOG_URL_PATTERNS: str = 'djangocms_blog.urls'
184
185
# SEO and meta settings
186
BLOG_META_TITLE: str = ''
187
BLOG_META_DESCRIPTION: str = ''
188
BLOG_META_KEYWORDS: str = ''
189
BLOG_AUTO_APP_TITLE: bool = True
190
BLOG_DEFAULT_OBJECT_NAME: str = _('Article')
191
192
# Social media settings
193
BLOG_FB_TYPE: str = 'article'
194
BLOG_FB_APP_ID: str = ''
195
BLOG_TWITTER_TYPE: str = 'summary'
196
BLOG_TWITTER_SITE: str = ''
197
BLOG_TWITTER_AUTHOR: str = ''
198
BLOG_GPLUS_TYPE: str = 'Article'
199
200
# Feed settings
201
BLOG_FEED_ENABLE: bool = True
202
BLOG_FEED_LATEST_ITEMS: int = 10
203
204
# Sitemap settings
205
BLOG_SITEMAP_PRIORITY_DEFAULT: float = 0.5
206
BLOG_SITEMAP_CHANGEFREQ_DEFAULT: str = 'monthly'
207
208
# Comment settings
209
BLOG_ENABLE_COMMENTS: bool = True
210
BLOG_CURRENT_POST_IDENTIFIER: str = 'CURRENT_POST'
211
BLOG_CURRENT_NAMESPACE: str = 'CURRENT_NAMESPACE'
212
```
213
214
## Configuration Usage Examples
215
216
```python
217
# Django settings.py configuration
218
# Override default blog settings
219
BLOG_PAGINATION = 20
220
BLOG_LATEST_POSTS = 10
221
BLOG_MENU_TYPE = 'categories'
222
BLOG_PERMALINK_TYPE = 'full_date'
223
BLOG_USE_PLACEHOLDER = True
224
BLOG_MULTISITE = True
225
BLOG_ENABLE_COMMENTS = False
226
227
# SEO configuration
228
BLOG_META_TITLE = 'My Blog - Latest News and Articles'
229
BLOG_META_DESCRIPTION = 'Stay updated with our latest blog posts'
230
BLOG_META_KEYWORDS = 'blog, news, articles, updates'
231
232
# Social media configuration
233
BLOG_FB_APP_ID = '1234567890123456'
234
BLOG_TWITTER_SITE = '@myblog'
235
BLOG_TWITTER_AUTHOR = '@author'
236
237
# Template customization
238
BLOG_TEMPLATE_PREFIX = 'custom_blog'
239
BLOG_PLUGIN_TEMPLATE_FOLDERS = ['custom_plugins', 'blog_plugins']
240
241
# Creating blog configurations programmatically
242
from djangocms_blog.cms_appconfig import BlogConfig
243
244
# Create a new blog configuration
245
config = BlogConfig.objects.create(
246
namespace='news-blog',
247
app_title='News Blog',
248
object_name='News Article'
249
)
250
251
# Set translated fields
252
config.set_current_language('en')
253
config.app_title = 'Company News'
254
config.object_name = 'News Article'
255
config.save()
256
257
config.set_current_language('es')
258
config.app_title = 'Noticias de la Empresa'
259
config.object_name = 'Artículo de Noticias'
260
config.save()
261
262
# Configure per-apphook settings
263
config.app_data.config.permalink_type = 'full_date'
264
config.app_data.config.pagination = 15
265
config.app_data.config.enable_comments = False
266
config.app_data.config.meta_title = 'Company News - Latest Updates'
267
config.save()
268
269
# Access configuration in views/templates
270
from aldryn_apphooks_config.utils import get_app_instance
271
272
def my_view(request):
273
namespace, config = get_app_instance(request)
274
275
# Access configuration settings
276
pagination = config.app_data.config.pagination or get_setting('PAGINATION')
277
enable_comments = config.app_data.config.enable_comments
278
meta_title = config.app_data.config.meta_title
279
280
# Use in queryset
281
posts = Post.objects.published().filter(app_config=config)
282
283
return render(request, 'blog/posts.html', {
284
'posts': posts,
285
'config': config,
286
'pagination': pagination
287
})
288
289
# Template usage
290
# {% load cms_tags %}
291
# {% page_attribute "app_config" as config %}
292
#
293
# <h1>{{ config.app_title }}</h1>
294
# <meta name="description" content="{{ config.app_data.config.meta_description }}">
295
#
296
# {% if config.app_data.config.enable_comments %}
297
# <!-- Comment system -->
298
# {% endif %}
299
300
# Custom configuration validation
301
from djangocms_blog.cms_appconfig import BlogConfigForm
302
303
class CustomBlogConfigForm(BlogConfigForm):
304
"""Custom configuration form with additional validation."""
305
306
custom_setting = forms.CharField(
307
label='Custom Setting',
308
required=False,
309
help_text='Enter a custom value for this blog instance'
310
)
311
312
def clean_pagination(self):
313
"""Validate pagination setting."""
314
pagination = self.cleaned_data.get('pagination')
315
if pagination and pagination > 50:
316
raise forms.ValidationError('Pagination cannot exceed 50 posts per page.')
317
return pagination
318
319
# Using settings in custom code
320
from djangocms_blog.settings import get_setting
321
322
# Get setting with fallback
323
pagination = get_setting('PAGINATION') # Returns 10 by default
324
custom_setting = get_setting('CUSTOM_SETTING') # Returns None if not defined
325
326
# Override settings per request/context
327
class CustomPostListView(PostListView):
328
def get_paginate_by(self, queryset):
329
"""Custom pagination based on configuration."""
330
if hasattr(self, 'config') and self.config:
331
return self.config.app_data.config.pagination or get_setting('PAGINATION')
332
return get_setting('PAGINATION')
333
```