Skip to content

Commit 4c61320

Browse files
committed
feat: Make component folder configurable
1 parent 647d1d0 commit 4c61320

File tree

7 files changed

+40
-6
lines changed

7 files changed

+40
-6
lines changed

djangocms_frontend/component_pool.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from collections import defaultdict
2+
from collections.abc import Iterator
23
import importlib
34
import os
4-
from collections.abc import Iterator
55
import warnings
66

77
from django import forms
@@ -15,16 +15,16 @@
1515
from djangocms_frontend.component_base import CMSFrontendComponent
1616

1717

18-
def find_cms_component_templates() -> list[tuple[str, str]]:
18+
def find_cms_component_templates(subfolder: str) -> list[tuple[str, str]]:
1919
templates = []
2020
for app in apps.get_app_configs():
21-
app_template_dir = os.path.join(app.path, "templates", app.label, "cms_components")
21+
app_template_dir = os.path.join(app.path, "templates", app.label, subfolder)
2222
if os.path.exists(app_template_dir):
2323
for root, _, files in os.walk(app_template_dir):
2424
for file in files:
2525
if file.endswith(".html") or file.endswith(".htm"):
2626
relative_path = os.path.relpath(os.path.join(root, file), app_template_dir)
27-
templates.append((app.module.__name__, f"{app.label}/cms_components/{relative_path}"))
27+
templates.append((app.module.__name__, f"{app.label}/{subfolder}/{relative_path}"))
2828
return templates
2929

3030

@@ -43,7 +43,7 @@ class CMSAutoComponentDiscovery:
4343

4444
def __init__(self, register_to):
4545
self.default_field_context.update(settings.COMPONENT_FIELDS)
46-
templates = find_cms_component_templates()
46+
templates = find_cms_component_templates(settings.COMPONENT_FOLDER)
4747
auto_components = self.scan_templates_for_component_declaration(templates)
4848
for component in auto_components:
4949
register_to.register(component)

djangocms_frontend/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
FORM_OPTIONS = getattr(django_settings, "DJANGOCMS_FRONTEND_FORM_OPTIONS", {})
7878

7979
COMPONENT_FIELDS = getattr(django_settings, "DJANGOCMS_FRONTEND_COMPONENT_FIELDS", {})
80-
80+
COMPONENT_FOLDER = getattr(django_settings, "DJANGOCMS_FRONTEND_COMPONENT_FOLDER", "cms_components")
8181
framework = getattr(django_settings, "DJANGOCMS_FRONTEND_FRAMEWORK", "bootstrap5")
8282
theme = getattr(django_settings, "DJANGOCMS_FRONTEND_THEME", "djangocms_frontend")
8383

djangocms_frontend/templatetags/frontend.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ def render_tag(self, context, instance, attribute, **kwargs):
317317
instance = context.get("instance", None) # Use instance from context
318318

319319
if is_registering_component(context) and attribute:
320+
# Autodetect inline field and add it to the component
320321
update_component_properties(context, "frontend_editable_fields", attribute, append=True)
321322
elif is_inline_editing_active(context) and isinstance(instance, CMSPlugin) and instance.pk:
322323
# Only allow inline field to be rendered if inline editing is active and the instance is a CMSPlugin

docs/source/reference.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,24 @@ in your project's ``settings.py``.
2828
]
2929

3030

31+
.. py:attribute:: settings.DJANGOCMS_FRONTEND_COMPONENT_FOLDER
32+
33+
Defaults to ``"cms_components"``
34+
35+
The subfolder where the component templates are discovered. This is used by the
36+
:ref:`template components <template_components>` to find the templates
37+
for the components.
38+
39+
The folder needs to be created in your app's ``templates/<app_name>/`` directory.
40+
If you want to use a different folder, set this to the folder name of your choice.
41+
42+
For example, if you want to use ``"my_components"``, add the following line to your project's settings::
43+
44+
DJANGOCMS_FRONTEND_COMPONENT_FOLDER = "my_components"
45+
46+
This causes djangocms-frontend to search for templates on the following paths: ``templates/<app_name>/my_components/``,
47+
where ``<app_name>`` is the name of any installed app.
48+
3149
.. py:attribute:: settings.DJANGOCMS_FRONTEND_COMPONENT_FIELDS
3250
3351
Defaults to ``{}``

tests/test_app/templates/test_app/cms_components/ui/button.html

Whitespace-only changes.

tests/test_app/templates/test_app/my_components/test_component.htm

Whitespace-only changes.

tests/test_autocomponent.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,18 @@ def test_multiple_cms_component_tags_error(self):
106106
invalid_template = "{% load cms_tags %}{% cms_component 'Hero' %}{% cms_component 'Footer' %}"
107107
with self.assertRaises(TemplateSyntaxError):
108108
Template(invalid_template)
109+
110+
def test_component_folder_selection(self):
111+
from djangocms_frontend.component_pool import find_cms_component_templates
112+
113+
all_components = find_cms_component_templates("cms_components")
114+
private_components = find_cms_component_templates("my_components")
115+
no_components = find_cms_component_templates("no_components")
116+
117+
assert set(all_components) == {
118+
("tests.test_app", "test_app/cms_components/hero.html"),
119+
("tests.test_app", "test_app/cms_components/with_slots.html"),
120+
("tests.test_app", "test_app/cms_components/ui/button.html"),
121+
}
122+
assert private_components == [("tests.test_app", "test_app/my_components/test_component.htm")]
123+
assert no_components == []

0 commit comments

Comments
 (0)