0
# Configuration
1
2
Settings management, configuration helpers, and utility functions for customizing WagtailMenus behavior across your Django project. This includes Django settings integration, default values, constants, and helper classes for managing menu configuration.
3
4
## Capabilities
5
6
### Settings Helper
7
8
Main settings management class that provides access to configured values and defaults.
9
10
```python { .api }
11
class WagtailmenusSettingsHelper:
12
"""
13
Main settings helper for WagtailMenus configuration.
14
15
Provides centralized access to all WagtailMenus settings with
16
appropriate defaults and validation.
17
"""
18
19
# Model configuration
20
MAIN_MENU_MODEL: str = 'wagtailmenus.MainMenu'
21
FLAT_MENU_MODEL: str = 'wagtailmenus.FlatMenu'
22
MAIN_MENU_ITEMS_RELATED_NAME: str = 'menu_items'
23
FLAT_MENU_ITEMS_RELATED_NAME: str = 'menu_items'
24
25
# Menu class configuration
26
CHILDREN_MENU_CLASS: str = 'wagtailmenus.models.ChildrenMenu'
27
SECTION_MENU_CLASS: str = 'wagtailmenus.models.SectionMenu'
28
29
# Template settings
30
DEFAULT_MAIN_MENU_TEMPLATE: str = 'menus/main_menu.html'
31
DEFAULT_FLAT_MENU_TEMPLATE: str = 'menus/flat_menu.html'
32
DEFAULT_SECTION_MENU_TEMPLATE: str = 'menus/section_menu.html'
33
DEFAULT_CHILDREN_MENU_TEMPLATE: str = 'menus/children_menu.html'
34
DEFAULT_SUB_MENU_TEMPLATE: str = 'menus/sub_menu.html'
35
SITE_SPECIFIC_TEMPLATE_DIRS: bool = False
36
37
# Default behavior settings
38
DEFAULT_SECTION_MENU_MAX_LEVELS: int = 2
39
DEFAULT_CHILDREN_MENU_MAX_LEVELS: int = 1
40
DEFAULT_ADD_SUB_MENUS_INLINE: bool = False
41
42
# Feature flags
43
FLAT_MENUS_FALL_BACK_TO_DEFAULT_SITE_MENUS: bool = False
44
GUESS_TREE_POSITION_FROM_PATH: bool = True
45
46
# Admin/UI settings
47
MAIN_MENUS_EDITABLE_IN_WAGTAILADMIN: bool = True
48
FLAT_MENUS_EDITABLE_IN_WAGTAILADMIN: bool = True
49
MAIN_MENUS_ADMIN_CLASS: str = 'wagtailmenus.menuadmin.MainMenuAdmin'
50
FLAT_MENUS_ADMIN_CLASS: str = 'wagtailmenus.menuadmin.FlatMenuAdmin'
51
MAINMENU_MENU_ICON: str = 'list-ol'
52
FLATMENU_MENU_ICON: str = 'list-ol'
53
USE_CONDENSEDINLINEPANEL: bool = True
54
55
# Content settings
56
ACTIVE_CLASS: str = 'active'
57
ACTIVE_ANCESTOR_CLASS: str = 'ancestor'
58
PAGE_FIELD_FOR_MENU_ITEM_TEXT: str = 'title'
59
SECTION_ROOT_DEPTH: int = 3
60
61
# Model access properties
62
@property
63
def models(self):
64
"""Access to configured model classes."""
65
return ModelAccessor()
66
67
@property
68
def objects(self):
69
"""Access to menu object classes."""
70
return ObjectAccessor()
71
```
72
73
### Configuration Constants
74
75
Constants used throughout WagtailMenus for validation and choices.
76
77
```python { .api }
78
# Maximum menu levels choices for admin forms
79
MAX_LEVELS_CHOICES: tuple[tuple[int, str], ...]
80
"""
81
Tuple of choices for maximum menu levels in admin interface.
82
Format: ((1, '1'), (2, '2'), (3, '3'), (4, '4'), (5, '5'))
83
"""
84
85
# Default menu level limits
86
DEFAULT_MAIN_MENU_MAX_LEVELS: int
87
DEFAULT_FLAT_MENU_MAX_LEVELS: int
88
DEFAULT_SECTION_MENU_MAX_LEVELS: int
89
DEFAULT_CHILDREN_MENU_MAX_LEVELS: int
90
91
# Template name constants
92
DEFAULT_MAIN_MENU_TEMPLATE: str
93
DEFAULT_FLAT_MENU_TEMPLATE: str
94
DEFAULT_SECTION_MENU_TEMPLATE: str
95
DEFAULT_CHILDREN_MENU_TEMPLATE: str
96
DEFAULT_SUB_MENU_TEMPLATE: str
97
```
98
99
### Model and Object Accessors
100
101
Helper classes for accessing configured models and menu objects.
102
103
```python { .api }
104
class ModelAccessor:
105
"""Provides access to configured model classes."""
106
107
@property
108
def MAIN_MENU_MODEL(self):
109
"""Get the configured main menu model class."""
110
111
@property
112
def FLAT_MENU_MODEL(self):
113
"""Get the configured flat menu model class."""
114
115
class ObjectAccessor:
116
"""Provides access to menu object classes."""
117
118
@property
119
def SECTION_MENU_CLASS(self):
120
"""Get the section menu class."""
121
122
@property
123
def CHILDREN_MENU_CLASS(self):
124
"""Get the children menu class."""
125
126
@property
127
def SUB_MENU_CLASS(self):
128
"""Get the sub-menu class."""
129
```
130
131
### Utility Functions
132
133
Utility functions for validation, inspection, and version management.
134
135
```python { .api }
136
def validate_supplied_values(tag_name, **kwargs):
137
"""
138
Validate template tag parameters.
139
140
Args:
141
tag_name (str): Name of the template tag being validated
142
**kwargs: Template tag parameters to validate
143
144
Raises:
145
ValueError: If parameter values are invalid
146
"""
147
148
def accepts_kwarg(func, kwarg_name):
149
"""
150
Check if function accepts a specific keyword argument.
151
152
Args:
153
func: Function to inspect
154
kwarg_name (str): Name of keyword argument to check
155
156
Returns:
157
bool: True if function accepts the keyword argument
158
"""
159
160
def get_version(version_tuple):
161
"""
162
Return PEP 386-compliant version string from version tuple.
163
164
Args:
165
version_tuple (tuple): Version tuple (major, minor, patch, release, number)
166
167
Returns:
168
str: Formatted version string
169
"""
170
171
def get_main_version(version_tuple):
172
"""
173
Return main version components as string.
174
175
Args:
176
version_tuple (tuple): Version tuple
177
178
Returns:
179
str: Main version (major.minor.patch)
180
"""
181
182
def get_stable_branch_name(version_tuple):
183
"""
184
Return stable branch name for the version.
185
186
Args:
187
version_tuple (tuple): Version tuple
188
189
Returns:
190
str: Stable branch name
191
"""
192
```
193
194
### Context Processors
195
196
Context processor for adding menu-related variables to template contexts.
197
198
```python { .api }
199
def wagtailmenus(request):
200
"""
201
Context processor providing menu-related template variables.
202
203
Automatically determines current page, section root, and page ancestors
204
based on the request path and site configuration.
205
206
Args:
207
request: HTTP request object
208
209
Returns:
210
dict: Context containing 'wagtailmenus_vals' with:
211
- current_page: Current page object (if determinable)
212
- section_root: Section root page for current location
213
- current_page_ancestor_ids: Tuple of ancestor page IDs
214
"""
215
```
216
217
### Error Classes
218
219
Exception classes for WagtailMenus-specific errors.
220
221
```python { .api }
222
class RequestUnavailableError(Exception):
223
"""
224
Error when request is unavailable in multisite setup.
225
226
Raised when menu rendering requires request context but
227
none is available (e.g., in management commands).
228
"""
229
230
class SubMenuUsageError(Exception):
231
"""
232
Error for improper sub_menu tag usage.
233
234
Raised when sub_menu template tag is used outside of
235
proper menu rendering context.
236
"""
237
```
238
239
### Deprecation Warnings
240
241
Warning classes for deprecated functionality.
242
243
```python { .api }
244
class RemovedInWagtailMenus32Warning(PendingDeprecationWarning):
245
"""Deprecation warning for functionality removed in version 3.2."""
246
247
class RemovedInWagtailMenus33Warning(PendingDeprecationWarning):
248
"""Pending deprecation warning for functionality to be removed in version 3.3."""
249
```
250
251
## Usage Examples
252
253
### Django Settings Configuration
254
255
```python
256
# settings.py
257
258
# Basic WagtailMenus configuration
259
INSTALLED_APPS = [
260
# ... other apps
261
'wagtailmenus',
262
]
263
264
# Context processor (required for template tags)
265
TEMPLATES = [
266
{
267
'BACKEND': 'django.template.backends.django.DjangoTemplates',
268
'OPTIONS': {
269
'context_processors': [
270
# ... other processors
271
'wagtailmenus.context_processors.wagtailmenus',
272
],
273
},
274
},
275
]
276
277
# Optional: Custom model configuration
278
WAGTAILMENUS_MAIN_MENU_MODEL = 'myapp.CustomMainMenu'
279
WAGTAILMENUS_FLAT_MENU_MODEL = 'myapp.CustomFlatMenu'
280
281
# Optional: Template customization
282
WAGTAILMENUS_DEFAULT_MAIN_MENU_TEMPLATE = 'menus/custom_main_menu.html'
283
WAGTAILMENUS_DEFAULT_FLAT_MENU_TEMPLATE = 'menus/custom_flat_menu.html'
284
285
# Optional: Behavior settings
286
WAGTAILMENUS_DEFAULT_MAIN_MENU_MAX_LEVELS = 3
287
WAGTAILMENUS_DEFAULT_FLAT_MENU_MAX_LEVELS = 2
288
WAGTAILMENUS_FLAT_MENUS_FALL_BACK_TO_DEFAULT_SITE_MENUS = True
289
```
290
291
### Advanced Configuration
292
293
```python
294
# settings.py - Advanced configuration
295
296
# Custom template settings
297
WAGTAILMENUS_SECTION_MENU_USE_SPECIFIC_TEMPLATES = True
298
WAGTAILMENUS_CHILDREN_MENU_USE_SPECIFIC_TEMPLATES = True
299
300
# Performance settings
301
WAGTAILMENUS_ACTIVE_ANCESTOR_CACHE_TIMEOUT = 300 # 5 minutes
302
303
# Multi-site behavior
304
WAGTAILMENUS_FLAT_MENUS_FALL_BACK_TO_DEFAULT_SITE_MENUS = False
305
306
# Debug settings (development only)
307
WAGTAILMENUS_ADD_MENU_ITEMS_INLINE = True
308
```
309
310
### Accessing Settings in Code
311
312
```python
313
from wagtailmenus.conf import settings
314
315
# Access configured models
316
MainMenu = settings.models.MAIN_MENU_MODEL
317
FlatMenu = settings.models.FLAT_MENU_MODEL
318
319
# Access configuration values
320
max_levels = settings.DEFAULT_MAIN_MENU_MAX_LEVELS
321
template_name = settings.DEFAULT_MAIN_MENU_TEMPLATE
322
323
# Check feature flags
324
if settings.FLAT_MENUS_FALL_BACK_TO_DEFAULT_SITE_MENUS:
325
# Handle fallback behavior
326
pass
327
```
328
329
### Custom Settings Helper
330
331
```python
332
from wagtailmenus.conf.settings import WagtailmenusSettingsHelper
333
334
class CustomSettingsHelper(WagtailmenusSettingsHelper):
335
"""Custom settings helper with additional functionality."""
336
337
@property
338
def CUSTOM_MENU_FEATURE_ENABLED(self):
339
"""Check if custom menu feature is enabled."""
340
return getattr(settings, 'CUSTOM_MENU_FEATURE', False)
341
342
@property
343
def MENU_CACHE_TIMEOUT(self):
344
"""Get menu cache timeout with default."""
345
return getattr(settings, 'WAGTAILMENUS_CACHE_TIMEOUT', 300)
346
347
# Use custom settings helper
348
custom_settings = CustomSettingsHelper()
349
if custom_settings.CUSTOM_MENU_FEATURE_ENABLED:
350
cache_timeout = custom_settings.MENU_CACHE_TIMEOUT
351
```
352
353
### Validation Usage
354
355
```python
356
from wagtailmenus.utils.misc import validate_supplied_values
357
358
def custom_menu_tag(context, max_levels=None, **kwargs):
359
"""Custom menu template tag with validation."""
360
361
# Validate parameters
362
validate_supplied_values('custom_menu', max_levels=max_levels)
363
364
# Process menu rendering
365
if max_levels and max_levels > 5:
366
raise ValueError("max_levels cannot exceed 5")
367
368
# ... menu rendering logic
369
```
370
371
### Error Handling
372
373
```python
374
from wagtailmenus.errors import RequestUnavailableError, SubMenuUsageError
375
376
def render_menu_safely(menu_type, **kwargs):
377
"""Safely render menu with error handling."""
378
379
try:
380
if menu_type == 'main':
381
return main_menu(**kwargs)
382
elif menu_type == 'section':
383
return section_menu(**kwargs)
384
except RequestUnavailableError:
385
# Handle missing request context
386
return render_fallback_menu()
387
except SubMenuUsageError:
388
# Handle improper sub-menu usage
389
return render_simple_menu()
390
```
391
392
### Context Processor Usage
393
394
```python
395
# The context processor automatically adds these variables to templates:
396
397
# In templates:
398
# {{ wagtailmenus_site }} - Current site
399
# {{ wagtailmenus_current_page }} - Current page
400
# {{ wagtailmenus_section_root }} - Section root page
401
# {{ wagtailmenus_ancestors }} - Page ancestors
402
403
# You can also access them in views:
404
def my_view(request):
405
context_data = wagtailmenus(request)
406
current_site = context_data['wagtailmenus_site']
407
current_page = context_data['wagtailmenus_current_page']
408
# ... use in view logic
409
```
410
411
## Types
412
413
```python { .api }
414
# Settings and configuration types
415
class ConfigurationTypes:
416
VERSION: tuple[int, int, int, str, int]
417
MAX_LEVELS_CHOICES: tuple[tuple[int, str], ...]
418
419
# Template settings
420
DEFAULT_MAIN_MENU_TEMPLATE: str
421
DEFAULT_FLAT_MENU_TEMPLATE: str
422
DEFAULT_SECTION_MENU_TEMPLATE: str
423
DEFAULT_CHILDREN_MENU_TEMPLATE: str
424
DEFAULT_SUB_MENU_TEMPLATE: str
425
426
# Level settings
427
DEFAULT_MAIN_MENU_MAX_LEVELS: int
428
DEFAULT_FLAT_MENU_MAX_LEVELS: int
429
DEFAULT_SECTION_MENU_MAX_LEVELS: int
430
DEFAULT_CHILDREN_MENU_MAX_LEVELS: int
431
432
# Feature flags
433
FLAT_MENUS_FALL_BACK_TO_DEFAULT_SITE_MENUS: bool
434
SECTION_MENU_USE_SPECIFIC_TEMPLATES: bool
435
CHILDREN_MENU_USE_SPECIFIC_TEMPLATES: bool
436
437
# Context processor return type
438
class ContextProcessorReturn:
439
wagtailmenus_site: 'Site'
440
wagtailmenus_current_page: 'Page'
441
wagtailmenus_section_root: 'Page'
442
wagtailmenus_ancestors: list['Page']
443
```