Skip to content

Commit 86dfb2d

Browse files
committed
Integrate into main package
1 parent d4d833f commit 86dfb2d

File tree

7 files changed

+102
-103
lines changed

7 files changed

+102
-103
lines changed

djangocms_frontend/apps.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ class DjangocmsFrontendConfig(apps.AppConfig):
88

99
def ready(self):
1010
from . import plugin_tag
11+
from . import component_pool
1112

1213
plugin_tag.setup()
14+
component_pool.setup()
1315
checks.register(check_settings)
1416
checks.register(check_installed_apps)
1517

djangocms_frontend/cms_plugins.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from cms.plugin_pool import plugin_pool
22

3-
from .component_pool import components
43
from .ui_plugin_base import CMSUIPluginBase
54

65

@@ -9,6 +8,8 @@ class CMSUIPlugin(CMSUIPluginBase):
98

109

1110
def update_plugin_pool():
11+
from .component_pool import components
12+
1213
# Loop through the values in the components' registry
1314
for _, plugin, slot_plugins in components._registry.values():
1415
if plugin.__name__ not in plugin_pool.plugins:
@@ -23,6 +24,3 @@ def update_plugin_pool():
2324
globals()[slot_plugin.__name__] = slot_plugin
2425
# Register the slot plugin with the plugin pool
2526
plugin_pool.register_plugin(slot_plugin)
26-
27-
28-
update_plugin_pool()

djangocms_frontend/component_base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ def slot_plugin_factory(cls) -> list[type]:
193193
"module": getattr(cls._component_meta, "module", _("Component")),
194194
"allow_children": True,
195195
"edit_disabled": True,
196+
"is_local": False,
196197
"show_add_form": False,
197198
"parent_classes": cls.__name__ + "Plugin",
198199
"render_template": cls.slot_template,

djangocms_frontend/component_pool.py

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,91 @@
1+
from collections import defaultdict
2+
import importlib
3+
import os
14
import warnings
25

6+
from django.apps import apps
7+
from django.template import loader
38
from django.utils.module_loading import autodiscover_modules
49

10+
from djangocms_frontend import settings
11+
from djangocms_frontend.component_base import CMSFrontendComponent
12+
13+
14+
def find_cms_component_templates() -> list[str]:
15+
templates = []
16+
for app in apps.get_app_configs():
17+
app_template_dir = os.path.join(app.path, "templates", app.label, "cms_components")
18+
if os.path.exists(app_template_dir):
19+
for root, _, files in os.walk(app_template_dir):
20+
for file in files:
21+
if file.endswith(".html") or file.endswith(".htm"):
22+
relative_path = os.path.relpath(os.path.join(root, file), app_template_dir)
23+
templates.append(f"{app.label}/cms_components/{relative_path}")
24+
return templates
25+
26+
27+
class CMSAutoComponentDiscovery:
28+
default_field_context = {
29+
"djanghocms_text": "djangocms_text.fields.TextFormField",
30+
"djanghocms_text_ckeditor": "djangocms_text_ckeditor.fields.TextFormField",
31+
"djangocms_link": "djangocms_link.fields.LinkFormField",
32+
"djangocms_frontend.contrib.image": "djangocms_frontend.contrib.image.fields.ImageFormField",
33+
"djangocms_frontend.contrib.icon": "djangocms_frontend.contrib.icon.fields.IconPickerField",
34+
}
35+
36+
def __init__(self, register_to):
37+
templates = find_cms_component_templates()
38+
auto_components = self.scan_templates_for_component_declaration(templates)
39+
for component in auto_components:
40+
register_to.register(component)
41+
42+
def get_field_context(self) -> dict:
43+
field_context = {}
44+
self.default_field_context.update(settings.COMPONENT_FIELDS)
45+
for key, value in self.default_field_context.items():
46+
if apps.is_installed(key) and "." in value:
47+
module, field_name = value.rsplit(".", 1)
48+
field_context[field_name] = importlib.import_module(module).__dict__[field_name]
49+
return field_context
50+
51+
@staticmethod
52+
def component_factory(component: tuple, fields: list[tuple], template: str) -> CMSFrontendComponent:
53+
args, kwargs = component
54+
(name,) = args
55+
56+
kwargs["render_template"] = template
57+
meta = type("Meta", (), kwargs)
58+
cls = type(
59+
name,
60+
(CMSFrontendComponent,),
61+
{
62+
"Meta": meta,
63+
"__module__": "djangocms_frontend.contrib.auto_component.cms_components",
64+
**{
65+
# Django template engine instantiates objects -- re-instantiate them here
66+
args[0]: args[1].__class__(**kwargs)
67+
for args, kwargs in fields
68+
},
69+
},
70+
)
71+
return cls
72+
73+
def scan_templates_for_component_declaration(self, templates: list[str]) -> list[CMSFrontendComponent]:
74+
from django.forms import fields
75+
76+
components = []
77+
field_context = self.get_field_context()
78+
for template_name in templates:
79+
context = {"_cms_components": defaultdict(list), "forms": fields, "instance": {}, **field_context}
80+
loader.render_to_string(template_name, context)
81+
cms_component = context["_cms_components"].get("cms_component", [])
82+
fields = context["_cms_components"].get("fields", [])
83+
if len(cms_component) == 1:
84+
components.append(self.component_factory(cms_component[0], fields, template_name))
85+
elif len(cms_component) > 1:
86+
raise ValueError(f"Multiple cms_component tags found in {template_name}")
87+
return components
88+
589

690
class Components:
791
_registry: dict = {}
@@ -20,6 +104,16 @@ def __getitem__(self, item):
20104

21105
components = Components()
22106

23-
if not components._discovered:
24-
autodiscover_modules("cms_components", register_to=components)
25-
components._discovered = True
107+
108+
def setup():
109+
global components
110+
111+
if not components._discovered:
112+
from .cms_plugins import update_plugin_pool
113+
114+
# First discover components in cms_components module
115+
autodiscover_modules("cms_components", register_to=components)
116+
# The discover auto components by their templates
117+
CMSAutoComponentDiscovery(register_to=components)
118+
update_plugin_pool()
119+
components._discovered = True

djangocms_frontend/contrib/auto_component/__init__.py

Whitespace-only changes.

djangocms_frontend/contrib/auto_component/apps.py

Lines changed: 0 additions & 96 deletions
This file was deleted.

djangocms_frontend/contrib/auto_component/templatetags/cms_component.py renamed to djangocms_frontend/templatetags/cms_component.py

File renamed without changes.

0 commit comments

Comments
 (0)