or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdmenus.mdpages.mdpermissions.mdplugins.mdtemplates.mdutilities.md

plugins.mddocs/

0

# Plugin System

1

2

Django CMS features an extensible plugin architecture that allows modular content components to be inserted into placeholders, with support for custom plugin development, nested plugins, and comprehensive plugin management.

3

4

## Capabilities

5

6

### Plugin Management

7

8

Add, configure, and manage plugins within placeholders with full control over positioning and hierarchy.

9

10

```python { .api }

11

def add_plugin(

12

placeholder,

13

plugin_type,

14

language,

15

position="last-child",

16

target=None,

17

**data

18

):

19

"""

20

Add a plugin to a placeholder.

21

22

Args:

23

placeholder (Placeholder): Target placeholder

24

plugin_type (str): Plugin type identifier

25

language (str): Language code

26

position (str): Position relative to target ("first-child", "last-child", "left", "right")

27

target (CMSPlugin, optional): Reference plugin for positioning

28

**data: Plugin-specific configuration data

29

30

Returns:

31

CMSPlugin: Created plugin instance

32

"""

33

```

34

35

### Plugin Base Classes

36

37

Foundation classes for developing custom plugins with admin integration, rendering, and configuration.

38

39

```python { .api }

40

class CMSPluginBase:

41

"""

42

Base class for all CMS plugins.

43

44

Attributes:

45

model: Plugin model class

46

name: Human-readable plugin name

47

render_template: Template for frontend rendering

48

admin_preview: Show preview in admin

49

allow_children: Allow child plugins

50

child_classes: Allowed child plugin types

51

parent_classes: Allowed parent plugin types

52

require_parent: Require parent plugin

53

text_enabled: Enable text plugin features

54

cache: Enable plugin caching

55

"""

56

57

def render(self, context, instance, placeholder):

58

"""Render plugin content."""

59

60

def get_render_template(self, context, instance, placeholder):

61

"""Get template for rendering."""

62

63

def get_form(self, request, obj=None, **kwargs):

64

"""Get admin form for plugin."""

65

66

def save_model(self, request, obj, form, change):

67

"""Save plugin instance."""

68

69

class CMSPluginBaseMetaclass:

70

"""Metaclass for automatic plugin registration."""

71

72

class PluginMenuItem:

73

"""Configuration for plugin menu items."""

74

```

75

76

### Plugin Models

77

78

Core models for plugin data storage and hierarchy management.

79

80

```python { .api }

81

class CMSPlugin:

82

"""

83

Base model for all plugin instances.

84

85

Attributes:

86

placeholder: Associated placeholder

87

parent: Parent plugin for nesting

88

position: Position within placeholder

89

language: Language code

90

plugin_type: Plugin type identifier

91

creation_date: Creation timestamp

92

changed_date: Last modification timestamp

93

numchild: Number of child plugins

94

depth: Nesting depth level

95

path: Tree path for hierarchy

96

"""

97

98

def get_plugin_class(self):

99

"""Get plugin class instance."""

100

101

def get_plugin_instance(self, admin=None):

102

"""Get downcasted plugin instance."""

103

104

def get_bound_plugin(self):

105

"""Get bound plugin with class."""

106

107

def copy_relations(self, old_instance):

108

"""Copy plugin relationships."""

109

110

class AliasPlugin:

111

"""Plugin for referencing other plugins."""

112

113

class PlaceholderPlugin:

114

"""Plugin containing nested placeholder."""

115

```

116

117

### Plugin Pool Management

118

119

Global registry for plugin types and plugin discovery.

120

121

```python { .api }

122

class PluginPool:

123

"""Global plugin registry and management."""

124

125

def register_plugin(self, plugin_class):

126

"""Register a plugin class."""

127

128

def unregister_plugin(self, plugin_class):

129

"""Unregister a plugin class."""

130

131

def get_all_plugins(self, placeholder=None, page=None, setting_key="plugins"):

132

"""Get available plugins for context."""

133

134

def get_text_enabled_plugins(self, placeholder, page):

135

"""Get text-enabled plugins."""

136

137

# Global plugin pool instance

138

plugin_pool = PluginPool()

139

```

140

141

## Usage Examples

142

143

### Adding Plugins to Pages

144

145

```python

146

from cms.api import create_page, add_plugin

147

from cms.models import Placeholder

148

149

# Create a page

150

page = create_page(

151

title="Sample Page",

152

template="page.html",

153

language="en"

154

)

155

156

# Get a placeholder

157

placeholder = page.get_placeholders("en").get(slot="content")

158

159

# Add a text plugin

160

text_plugin = add_plugin(

161

placeholder=placeholder,

162

plugin_type="TextPlugin",

163

language="en",

164

body="<h1>Welcome!</h1><p>This is sample content.</p>"

165

)

166

167

# Add an image plugin after the text

168

image_plugin = add_plugin(

169

placeholder=placeholder,

170

plugin_type="PicturePlugin",

171

language="en",

172

position="right",

173

target=text_plugin,

174

picture="/path/to/image.jpg",

175

alt_text="Sample image"

176

)

177

178

# Add a nested plugin structure

179

container_plugin = add_plugin(

180

placeholder=placeholder,

181

plugin_type="MultiColumnPlugin",

182

language="en"

183

)

184

185

column_plugin = add_plugin(

186

placeholder=placeholder,

187

plugin_type="ColumnPlugin",

188

language="en",

189

parent=container_plugin,

190

width="50%"

191

)

192

```

193

194

### Custom Plugin Development

195

196

```python

197

from cms.plugin_base import CMSPluginBase

198

from cms.plugin_pool import plugin_pool

199

from django import forms

200

from django.db import models

201

202

# Plugin model

203

class CallToActionPlugin(models.Model):

204

title = models.CharField(max_length=100)

205

description = models.TextField()

206

button_text = models.CharField(max_length=50)

207

button_url = models.URLField()

208

209

def __str__(self):

210

return self.title

211

212

# Plugin class

213

@plugin_pool.register_plugin

214

class CallToActionPluginPublisher(CMSPluginBase):

215

model = CallToActionPlugin

216

name = "Call to Action"

217

render_template = "plugins/call_to_action.html"

218

cache = True

219

220

fieldsets = (

221

('Content', {

222

'fields': ('title', 'description')

223

}),

224

('Button', {

225

'fields': ('button_text', 'button_url')

226

}),

227

)

228

229

def render(self, context, instance, placeholder):

230

context['instance'] = instance

231

return context

232

```

233

234

### Working with Plugin Hierarchy

235

236

```python

237

from cms.models import CMSPlugin

238

from cms.utils.plugins import copy_plugins_to_placeholder

239

240

# Get all plugins in a placeholder

241

plugins = CMSPlugin.objects.filter(

242

placeholder=placeholder,

243

language="en"

244

).order_by('path')

245

246

# Get root level plugins only

247

root_plugins = plugins.filter(parent=None)

248

249

# Get child plugins of a specific plugin

250

child_plugins = plugins.filter(parent=parent_plugin)

251

252

# Copy plugins to another placeholder

253

copy_plugins_to_placeholder(

254

plugins=plugins,

255

placeholder=target_placeholder,

256

language="en"

257

)

258

259

# Move plugin to different position

260

plugin.move(target_plugin, position="right")

261

plugin.save()

262

```

263

264

### Plugin Utilities

265

266

```python

267

from cms.utils.plugins import (

268

get_bound_plugins,

269

has_reached_plugin_limit,

270

get_plugin_class

271

)

272

273

# Get plugin instances with their classes

274

bound_plugins = get_bound_plugins(plugins)

275

276

# Check plugin limits

277

can_add = not has_reached_plugin_limit(

278

placeholder=placeholder,

279

plugin_type="TextPlugin",

280

language="en",

281

template="page.html"

282

)

283

284

# Get plugin class by type

285

plugin_class = get_plugin_class("TextPlugin")

286

```

287

288

## Types

289

290

```python { .api }

291

class Placeholder:

292

"""

293

Container for plugins within templates.

294

295

Attributes:

296

slot: Placeholder name/identifier

297

default_width: Default width for plugins

298

locked: Whether placeholder is locked

299

"""

300

301

def get_plugins(self, language=None):

302

"""Get plugins for language."""

303

304

def get_label(self):

305

"""Get placeholder display label."""

306

307

def is_editable(self, request):

308

"""Check if placeholder is editable."""

309

310

class PlaceholderReference:

311

"""Reference to placeholder for generic relationships."""

312

```