or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

administration.mdconfiguration.mdindex.mdmodels.mdpage-integration.mdtemplate-tags.md

page-integration.mddocs/

0

# Page Integration

1

2

Mixins and base classes for integrating Wagtail pages with the WagtailMenus system. These components enable pages to participate in navigation structures, control their menu behavior, and provide specialized page types for menu functionality.

3

4

## Capabilities

5

6

### Menu Page Mixin

7

8

A mixin class that adds menu-related functionality to any Wagtail page, providing settings and behavior for controlling how pages appear in menus.

9

10

```python { .api }

11

class MenuPageMixin:

12

"""

13

Mixin for pages with menu functionality.

14

15

Adds menu-related fields and methods to control how pages

16

participate in menu structures and navigation.

17

"""

18

19

# Menu behavior fields

20

repeat_in_subnav: models.BooleanField # Whether to repeat in sub-navigation

21

repeated_item_text: models.CharField # Custom text for repeated items

22

23

# Menu settings panels for admin

24

menu_settings_panels: list

25

26

def modify_submenu_items(

27

self, menu_items, current_page, current_ancestor_ids, current_site,

28

allow_repeating_parents, apply_active_classes, original_menu_tag,

29

menu_instance=None, request=None, use_absolute_page_urls=False

30

):

31

"""

32

Modify menu items for sub-menu display.

33

34

Args:

35

menu_items: List of menu items to modify

36

current_page: The current page being viewed

37

current_ancestor_ids: IDs of current page ancestors

38

current_site: Current site object

39

allow_repeating_parents (bool): Whether to show repeating parent items

40

apply_active_classes (bool): Whether to apply active CSS classes

41

original_menu_tag (str): Name of original menu tag ('main_menu', etc.)

42

menu_instance: Menu instance calling this method

43

request: HTTP request object

44

use_absolute_page_urls (bool): Whether to use absolute URLs

45

46

Returns:

47

Modified menu items list

48

"""

49

50

def has_submenu_items(self, current_page, allow_repeating_parents,

51

original_menu_tag, menu_instance=None, request=None):

52

"""

53

Check if this page has items for sub-menu display.

54

55

Args:

56

current_page: The current page being viewed

57

allow_repeating_parents (bool): Allow parent items in sub-menus

58

current_site: Current site object

59

check_for_children (bool): Whether to check for child pages

60

61

Returns:

62

bool: True if page has sub-menu items

63

"""

64

```

65

66

### Menu Page

67

68

An abstract page class that combines MenuPageMixin with Wagtail's Page model, providing a complete base for pages that participate in menu systems.

69

70

```python { .api }

71

class MenuPage(MenuPageMixin, Page):

72

"""

73

Abstract page with menu functionality.

74

75

Extends Wagtail's Page model with menu-related fields and methods.

76

Use as a base class for pages that need menu integration.

77

"""

78

79

class Meta:

80

abstract = True

81

```

82

83

### Link Page

84

85

An abstract page type specifically designed for menu items that link to external URLs or provide redirects.

86

87

```python { .api }

88

class AbstractLinkPage:

89

"""

90

Base class for link pages that redirect to external URLs.

91

92

Provides functionality for pages that exist primarily to

93

link to external resources or redirect to other locations.

94

"""

95

96

link_url: str # External URL to redirect to

97

link_text: str # Display text for the link

98

99

def get_sitemap_urls(self, request=None):

100

"""

101

Return empty list as link pages shouldn't appear in sitemaps.

102

103

Args:

104

request: HTTP request object

105

106

Returns:

107

list: Empty list (link pages not included in sitemaps)

108

"""

109

110

def serve(self, request):

111

"""

112

Serve a redirect to the external URL.

113

114

Args:

115

request: HTTP request object

116

117

Returns:

118

HttpResponseRedirect: Redirect to link_url

119

"""

120

```

121

122

### Sub-Menu Template Mixin

123

124

A mixin for pages that need to define custom templates for their sub-menu rendering.

125

126

```python { .api }

127

class DefinesSubMenuTemplatesMixin:

128

"""

129

Mixin for sub-menu template handling.

130

131

Allows pages to specify custom templates for rendering

132

their sub-menus at different levels.

133

"""

134

135

def get_sub_menu_template_names(self, current_level=1):

136

"""

137

Get template names for sub-menu rendering at specific levels.

138

139

Args:

140

current_level (int): Current menu depth level

141

142

Returns:

143

list: Template names for sub-menu rendering

144

"""

145

```

146

147

## Usage Examples

148

149

### Creating Menu-Enabled Pages

150

151

```python

152

from wagtailmenus.models import MenuPageMixin

153

from wagtail.models import Page

154

from wagtail.fields import RichTextField

155

from wagtail.admin.panels import FieldPanel

156

157

class CustomPage(MenuPageMixin, Page):

158

"""Custom page with menu functionality."""

159

160

body = RichTextField()

161

162

content_panels = Page.content_panels + [

163

FieldPanel('body'),

164

]

165

166

# Add menu settings to the settings tab

167

settings_panels = Page.settings_panels + MenuPageMixin.menu_settings_panels

168

```

169

170

### Using MenuPage Base Class

171

172

```python

173

from wagtailmenus.models import MenuPage

174

from wagtail.fields import RichTextField

175

from wagtail.admin.panels import FieldPanel

176

177

class ArticlePage(MenuPage):

178

"""Article page with built-in menu functionality."""

179

180

body = RichTextField()

181

author = models.CharField(max_length=100)

182

183

content_panels = Page.content_panels + [

184

FieldPanel('body'),

185

FieldPanel('author'),

186

]

187

188

# menu_settings_panels are automatically included

189

```

190

191

### Creating Link Pages

192

193

```python

194

from wagtailmenus.models import AbstractLinkPage

195

from wagtail.models import Page

196

from wagtail.admin.panels import FieldPanel

197

from django.db import models

198

199

class ExternalLinkPage(AbstractLinkPage, Page):

200

"""Page that redirects to external URLs."""

201

202

# Additional fields beyond AbstractLinkPage

203

description = models.TextField(blank=True)

204

205

content_panels = Page.content_panels + [

206

FieldPanel('link_url'),

207

FieldPanel('link_text'),

208

FieldPanel('description'),

209

]

210

211

def get_link_text(self):

212

"""Get display text for menu items."""

213

return self.link_text or self.title

214

```

215

216

### Customizing Menu Behavior

217

218

```python

219

class SpecialPage(MenuPageMixin, Page):

220

"""Page with custom menu behavior."""

221

222

def modify_submenu_behaviour(self, menu_items, current_page,

223

current_ancestor_ids, current_site,

224

check_for_children=True):

225

"""Custom sub-menu behavior."""

226

227

# Add custom menu items

228

custom_items = self.get_custom_menu_items()

229

menu_items.extend(custom_items)

230

231

# Filter items based on user permissions

232

if hasattr(current_page, 'request'):

233

user = getattr(current_page.request, 'user', None)

234

if user and not user.is_staff:

235

menu_items = [item for item in menu_items

236

if not getattr(item, 'staff_only', False)]

237

238

return menu_items

239

240

def has_submenu_items(self, current_page, allow_repeating_parents=True,

241

current_site=None, check_for_children=True):

242

"""Check for custom sub-menu items."""

243

244

# Always return True if we have custom items

245

if self.get_custom_menu_items():

246

return True

247

248

# Otherwise use default behavior

249

return super().has_submenu_items(

250

current_page, allow_repeating_parents,

251

current_site, check_for_children

252

)

253

```

254

255

### Working with Sub-Menu Templates

256

257

```python

258

from wagtailmenus.models import DefinesSubMenuTemplatesMixin

259

260

class CategoryPage(DefinesSubMenuTemplatesMixin, MenuPageMixin, Page):

261

"""Page with custom sub-menu templates."""

262

263

category_type = models.CharField(max_length=50, choices=[

264

('products', 'Products'),

265

('services', 'Services'),

266

('resources', 'Resources'),

267

])

268

269

def get_sub_menu_template_names(self, current_level=1):

270

"""Return category-specific sub-menu templates."""

271

272

templates = []

273

274

if self.category_type == 'products':

275

templates.append('menus/product_submenu.html')

276

elif self.category_type == 'services':

277

templates.append('menus/service_submenu.html')

278

279

# Add level-specific templates

280

templates.append(f'menus/submenu_level_{current_level}.html')

281

templates.append('menus/submenu.html') # Fallback

282

283

return templates

284

```

285

286

### Menu Integration in Templates

287

288

```django

289

<!-- Check if current page supports menu functionality -->

290

{% if page.show_in_menus %}

291

<nav class="page-navigation">

292

{% children_menu parent_page=page max_levels=1 %}

293

</nav>

294

{% endif %}

295

296

<!-- Show sub-navigation if page has menu items -->

297

{% if page.has_submenu_items %}

298

<aside class="subnav">

299

{% section_menu show_section_root=False %}

300

</aside>

301

{% endif %}

302

```

303

304

### Page Settings Configuration

305

306

```python

307

# In your page models, configure menu settings

308

class MyPage(MenuPageMixin, Page):

309

# ... other fields

310

311

settings_panels = Page.settings_panels + [

312

# Menu settings are added via MenuPageMixin.menu_settings_panels

313

FieldPanel('show_in_menus'),

314

FieldPanel('repeat_in_subnav'),

315

] + MenuPageMixin.menu_settings_panels

316

```

317

318

## Types

319

320

```python { .api }

321

# Page integration field types

322

class PageIntegrationTypes:

323

show_in_menus: bool

324

repeat_in_subnav: bool

325

link_url: str

326

link_text: str

327

menu_settings_panels: list

328

329

# Method parameter and return types

330

class PageMethodTypes:

331

menu_items: list

332

current_page: 'Page'

333

current_ancestor_ids: list[int]

334

current_site: 'Site'

335

check_for_children: bool

336

allow_repeating_parents: bool

337

current_level: int

338

```