or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

admin-forms.mdcms-integration.mdconfiguration.mdfeeds-sitemaps.mdindex.mdmodels.mdtemplates-utilities.mdviews.md

templates-utilities.mddocs/

0

# Template Tags and Utilities

1

2

Template tags for extracting media content from posts, utility functions, and helper classes for template integration and content management.

3

4

## Capabilities

5

6

### Media Template Tags

7

8

Template tags for working with media attachments in blog posts.

9

10

```python { .api }

11

@register.simple_tag(name="media_plugins", takes_context=True)

12

def media_plugins(context: Dict[str, Any], post: Post) -> List[CMSPlugin]:

13

"""

14

Extract MediaAttachmentPluginMixin plugins from post media placeholder.

15

16

Parameters:

17

- context: Template context dictionary

18

- post: Post instance to extract media from

19

20

Returns:

21

List of MediaAttachmentPluginMixin plugins from the media placeholder

22

23

Usage in templates:

24

{% media_plugins post as media_plugins %}

25

{% for plugin in media_plugins %}{% render_plugin plugin %}{% endfor %}

26

"""

27

28

@register.simple_tag(name="media_images", takes_context=True)

29

def media_images(context: Dict[str, Any], post: Post, main: bool = True) -> List[str]:

30

"""

31

Extract images from MediaAttachmentPluginMixin plugins in post media placeholder.

32

33

Parameters:

34

- context: Template context dictionary

35

- post: Post instance to extract images from

36

- main: If True, get main images; if False, get thumbnail images

37

38

Returns:

39

List of image URLs from media plugins

40

41

Features:

42

- Supports main images and thumbnails

43

- Handles djangocms-video poster field fallback

44

- Graceful error handling for missing methods

45

46

Usage in templates:

47

{% media_images post False as thumbs %}

48

{% for thumb in thumbs %}<img src="{{ thumb }}"/>{% endfor %}

49

50

{% media_images post as main_images %}

51

{% for image in main_images %}<img src="{{ image }}"/>{% endfor %}

52

"""

53

```

54

55

### Utility Functions

56

57

Core utility functions for slug generation and text processing.

58

59

```python { .api }

60

def slugify(base: str) -> str:

61

"""

62

Generate URL-friendly slugs with unicode support.

63

64

Parameters:

65

- base: String to convert to slug

66

67

Returns:

68

URL-friendly slug string

69

70

Features:

71

- Respects BLOG_UNICODE_SLUGS setting

72

- Uses Django's slugify with unicode support

73

- Consistent slug generation across the application

74

"""

75

```

76

77

### Manager Utilities

78

79

Custom manager classes for advanced querying and filtering.

80

81

```python { .api }

82

class TaggedFilterItem:

83

"""

84

Manager mixin for tag filtering functionality.

85

86

Features:

87

- Tag-based content filtering

88

- Related content discovery

89

- Cross-model tag relationships

90

"""

91

92

def tagged(self, other_model: Optional[models.Model] = None, queryset: Optional[QuerySet] = None) -> QuerySet:

93

"""

94

Return queryset of items tagged with same tags as other model/queryset.

95

96

Parameters:

97

- other_model: Model instance to match tags with

98

- queryset: QuerySet to match tags with

99

100

Returns:

101

QuerySet filtered by matching tags

102

"""

103

104

def _taglist(self, other_model: Optional[models.Model] = None, queryset: Optional[QuerySet] = None) -> List[int]:

105

"""

106

Return list of tag IDs common to current model and provided model/queryset.

107

108

Parameters:

109

- other_model: Model instance to find common tags with

110

- queryset: QuerySet to find common tags with

111

112

Returns:

113

List of tag IDs that are common between models

114

"""

115

116

def tag_list(self, other_model: Optional[models.Model] = None, queryset: Optional[QuerySet] = None) -> QuerySet:

117

"""

118

Return queryset of tags common to current model and provided model/queryset.

119

120

Parameters:

121

- other_model: Model instance to find common tags with

122

- queryset: QuerySet to find common tags with

123

124

Returns:

125

QuerySet of Tag objects that are common

126

"""

127

128

class GenericDateTaggedManager(TaggedFilterItem, AppHookConfigTranslatableManager):

129

"""

130

Manager combining date filtering, tag filtering, and app config support.

131

132

Features:

133

- App config filtering

134

- Multilingual content support

135

- Tag-based filtering

136

- Date-based filtering

137

- Publication status filtering

138

"""

139

140

def published(self) -> QuerySet:

141

"""Return published posts queryset."""

142

143

def archived(self) -> QuerySet:

144

"""Return archived posts queryset."""

145

146

def available(self) -> QuerySet:

147

"""Return posts available for current site."""

148

149

def by_author(self, author: AbstractUser) -> QuerySet:

150

"""Return posts by specific author."""

151

152

def by_category(self, category: BlogCategory) -> QuerySet:

153

"""Return posts in specific category."""

154

155

def by_tag(self, tag: str) -> QuerySet:

156

"""Return posts with specific tag."""

157

158

def featured(self) -> QuerySet:

159

"""Return featured posts."""

160

161

def recent(self, count: int = 5) -> QuerySet:

162

"""Return recent posts."""

163

```

164

165

### Template Context Processors

166

167

Context processors for adding blog-related data to template contexts.

168

169

```python { .api }

170

# Context data automatically available in templates when using blog views:

171

# - post: Current post object (in detail views)

172

# - post_list: List of posts (in list views)

173

# - categories: Available categories

174

# - tags: Available tags

175

# - config: Current blog configuration

176

# - meta: Meta information for SEO

177

# - view: Current view instance

178

```

179

180

## Template Integration Examples

181

182

```python

183

# Using template tags in templates

184

# Load the template tags

185

{% load cms_tags djangocms_blog %}

186

187

# Extract and display media plugins

188

{% media_plugins post as media_plugins %}

189

{% if media_plugins %}

190

<div class="post-media">

191

{% for plugin in media_plugins %}

192

{% render_plugin plugin %}

193

{% endfor %}

194

</div>

195

{% endif %}

196

197

# Display media images

198

{% media_images post as main_images %}

199

{% if main_images %}

200

<div class="post-images">

201

{% for image in main_images %}

202

<img src="{{ image }}" alt="{{ post.title }}" class="post-image">

203

{% endfor %}

204

</div>

205

{% endif %}

206

207

# Display thumbnail images

208

{% media_images post False as thumbs %}

209

{% if thumbs %}

210

<div class="post-thumbnails">

211

{% for thumb in thumbs %}

212

<img src="{{ thumb }}" alt="{{ post.title }}" class="post-thumb">

213

{% endfor %}

214

</div>

215

{% endif %}

216

217

# Custom template tag usage

218

from django import template

219

from djangocms_blog.models import Post

220

from djangocms_blog.templatetags.djangocms_blog import media_images

221

222

register = template.Library()

223

224

@register.simple_tag

225

def post_gallery(post, image_type='main'):

226

"""Custom tag for post image gallery."""

227

if image_type == 'main':

228

images = media_images({'request': None}, post, main=True)

229

else:

230

images = media_images({'request': None}, post, main=False)

231

232

return {

233

'images': images,

234

'post': post,

235

'image_type': image_type

236

}

237

238

# Using utility functions

239

from djangocms_blog.fields import slugify

240

241

# Generate slugs

242

title = "My Awesome Blog Post with Ñoño Characters"

243

slug = slugify(title) # Returns "my-awesome-blog-post-with-ñoño-characters"

244

245

# Custom slug generation

246

def generate_unique_slug(title, model_class, instance=None):

247

"""Generate unique slug for model instance."""

248

base_slug = slugify(title)

249

slug = base_slug

250

counter = 1

251

252

queryset = model_class.objects.all()

253

if instance and instance.pk:

254

queryset = queryset.exclude(pk=instance.pk)

255

256

while queryset.filter(slug=slug).exists():

257

slug = f"{base_slug}-{counter}"

258

counter += 1

259

260

return slug

261

262

# Using manager utilities

263

from djangocms_blog.models import Post

264

265

# Find posts with similar tags

266

main_post = Post.objects.get(pk=1)

267

related_posts = Post.objects.tagged(main_post)[:5]

268

269

# Find posts tagged with same tags as a set of posts

270

featured_posts = Post.objects.featured()

271

similar_posts = Post.objects.tagged(queryset=featured_posts)

272

273

# Complex querying with manager

274

from djangocms_blog.managers import GenericDateTaggedManager

275

276

class CustomPostManager(GenericDateTaggedManager):

277

"""Custom manager with additional methods."""

278

279

def by_year(self, year):

280

"""Get posts by year."""

281

return self.published().filter(date_published__year=year)

282

283

def popular(self, limit=10):

284

"""Get popular posts (example implementation)."""

285

return self.published().order_by('-views')[:limit]

286

287

def with_images(self):

288

"""Get posts that have main images."""

289

return self.published().exclude(main_image__isnull=True)

290

291

# Template context usage

292

# In templates, access manager methods:

293

# {% for post in view.get_queryset.featured %}

294

# {% for post in view.get_queryset.by_author:request.user %}

295

# {% for post in view.get_queryset.recent:10 %}

296

297

# Custom template filters

298

from django import template

299

from django.utils.safestring import mark_safe

300

from djangocms_blog.fields import slugify

301

302

register = template.Library()

303

304

@register.filter

305

def blog_slugify(value):

306

"""Template filter for slug generation."""

307

return slugify(str(value))

308

309

@register.filter

310

def post_excerpt(post, length=150):

311

"""Generate post excerpt."""

312

if post.abstract:

313

text = post.abstract

314

elif post.post_text:

315

text = post.post_text

316

else:

317

return ""

318

319

# Strip HTML and truncate

320

from django.utils.html import strip_tags

321

from django.utils.text import Truncator

322

323

plain_text = strip_tags(text)

324

truncated = Truncator(plain_text).chars(length, truncate='...')

325

return mark_safe(truncated)

326

327

# Usage in templates:

328

# {{ post.title|blog_slugify }}

329

# {{ post|post_excerpt:200 }}

330

331

# Custom inclusion tags

332

@register.inclusion_tag('blog/tags/related_posts.html', takes_context=True)

333

def related_posts(context, post, count=5):

334

"""Inclusion tag for related posts."""

335

related = Post.objects.published().tagged(post).exclude(pk=post.pk)[:count]

336

337

return {

338

'related_posts': related,

339

'current_post': post,

340

'request': context.get('request')

341

}

342

343

# Usage: {% related_posts post 3 %}

344

```