Skip to content

Commit cbb7515

Browse files
committed
feincms3 5.4
1 parent 0ddcd3c commit cbb7515

File tree

4 files changed

+35
-21
lines changed

4 files changed

+35
-21
lines changed

CHANGELOG.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ Change log
66
Next version
77
~~~~~~~~~~~~
88

9+
10+
5.4 (2025-06-19)
11+
~~~~~~~~~~~~~~~~
12+
913
- Added Django 5.2 to the CI.
1014
- Undeprecated the :mod:`~feincms3.mixins.TemplateMixin`, it's useful even
1115
though using :mod:`~feincms3.applications.PageTypeMixin` is obviously
@@ -17,6 +21,8 @@ Next version
1721
Sections are a more powerful alternative or addition to subregions already
1822
supported by django-content-editor. The main upside of sections is that they
1923
can be nested.
24+
- Allowed passing a list of plugins to ``RegionRenderer.register``. This is
25+
useful if registering several plugins with identical renderers etc.
2026

2127

2228
5.3 (2024-11-18)

feincms3/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "5.3.1"
1+
__version__ = "5.4.0"

feincms3/renderer.py

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def template_renderer(template_name, local_context=default_context, /):
8383
_subregion = 2
8484
_marks = 3
8585
_fetch = 4
86-
CLOSE_SECTION = "__close_section__"
86+
_CLOSE_SECTION = "_close_section"
8787

8888

8989
class RegionRenderer:
@@ -184,13 +184,17 @@ def register(
184184
f"The renderer function {renderer} has less than the two required arguments."
185185
)
186186

187-
if plugin in self._plugins:
188-
warnings.warn(
189-
f"The plugin {plugin} has already been registered with {self.__class__} before.",
190-
stacklevel=2,
191-
)
187+
if not isinstance(plugin, (list, tuple)):
188+
plugin = [plugin]
189+
190+
for p in plugin:
191+
if p in self._plugins:
192+
warnings.warn(
193+
f"The plugin {p} has already been registered with {self.__class__} before.",
194+
stacklevel=2,
195+
)
192196

193-
self._plugins[plugin] = (plugin, renderer, subregion, marks, fetch)
197+
self._plugins[p] = (p, renderer, subregion, marks, fetch)
194198

195199
def plugins(self, *, fetch=True):
196200
"""
@@ -295,9 +299,6 @@ def handle_default(self, plugins, context):
295299
for plugin in self.takewhile_subregion(plugins, "default"):
296300
yield self.render_plugin(plugin, context)
297301

298-
def handle___close_section__(self, plugins, context):
299-
yield self.render_plugin(plugins.popleft(), context)
300-
301302
def render_region(self, *, region, contents, context):
302303
"""
303304
Render one region.
@@ -334,7 +335,7 @@ def render_section_plugins(self, section, plugins, context):
334335
.. code-block:: python
335336
336337
from django.utils.html import mark_safe
337-
from feincms3.renderer import CLOSE_SECTION, render_in_context
338+
from feincms3.renderer import render_in_context
338339
339340
class SectionRenderer(RegionRenderer):
340341
def handle_section(self, plugins, context):
@@ -348,22 +349,22 @@ def handle_section(self, plugins, context):
348349
)
349350
350351
renderer = SectionRenderer()
351-
renderer.register(models.CloseSection, "", subregion=CLOSE_SECTION)
352+
renderer.register_section_close(models.CloseSection)
352353
renderer.register(models.Accordion, "", subregion="section")
353354
354355
This code automatically determines the template name from the class
355356
name, making it easier to reuse for different section types.
356357
357358
Subregions are automatically closed when subregions change. Sections
358-
only end when encountering an explicit ``CLOSE_SECTION`` subregion or
359-
when there are no more plugins in the current region at all. Sections
360-
can contain other sections and subregions making them quite powerful
361-
when for organizing and grouping content.
359+
only end when encountering an explicit section closing plugin or when
360+
there are no more plugins in the current region at all. Sections can
361+
contain other sections and subregions making them quite powerful when
362+
for organizing and grouping content.
362363
"""
363364
out = []
364365
while plugins:
365366
subregion = self.subregion(plugins[0])
366-
if subregion == CLOSE_SECTION:
367+
if subregion is _CLOSE_SECTION:
367368
plugins.popleft()
368369
break
369370
elif subregion is not None:
@@ -372,6 +373,14 @@ def handle_section(self, plugins, context):
372373
out.append(self.render_plugin(plugins.popleft(), context))
373374
return out
374375

376+
def register_section_close(self, plugin, renderer="", **kwargs):
377+
kwargs["subregion"] = _CLOSE_SECTION
378+
self.register(plugin, renderer, **kwargs)
379+
380+
def handle__close_section(self, plugins, context):
381+
plugins.popleft()
382+
yield from ()
383+
375384
# Main external rendering API
376385

377386
def regions_from_contents(self, contents, **kwargs):

tests/testapp/test_region_renderer.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
from pytest_django.asserts import assertHTMLEqual
1010

1111
from feincms3.renderer import (
12-
CLOSE_SECTION,
1312
PluginNotRegisteredError,
1413
RegionRenderer,
1514
template_renderer,
@@ -225,10 +224,10 @@ class CloseSection:
225224
pass
226225

227226
renderer = SectionRenderer()
228-
renderer.register(Text, "Text")
227+
renderer.register([Text], "Text") # Register as list
229228
renderer.register(Image, "Image", subregion="images")
230229
renderer.register(Section, "", subregion="section")
231-
renderer.register(CloseSection, "", subregion=CLOSE_SECTION)
230+
renderer.register_section_close(CloseSection)
232231

233232
def render(plugins):
234233
return renderer.render_region(

0 commit comments

Comments
 (0)