-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
213 additions
and
220 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,23 @@ | ||
from cms.constants import SLUG_REGEXP | ||
from cms.plugin_base import CMSPluginBase | ||
from django.utils.encoding import force_str | ||
from cms.plugin_pool import plugin_pool | ||
|
||
from djangocms_frontend.helpers import get_related | ||
from .component_pool import components | ||
from .ui_plugin_base import CMSUIPluginBase | ||
|
||
if hasattr(CMSPluginBase, "edit_field"): | ||
# FrontendEditable functionality already implemented in core? | ||
FrontendEditableAdminMixin = object | ||
else: | ||
# If not use our own version of the plugin-enabled mixin | ||
from .helpers import FrontendEditableAdminMixin | ||
|
||
class CMSUIPlugin(CMSUIPluginBase): | ||
pass | ||
|
||
class CMSUIPlugin(FrontendEditableAdminMixin, CMSPluginBase): | ||
render_template = "djangocms_frontend/html_container.html" | ||
change_form_template = "djangocms_frontend/admin/base.html" | ||
|
||
def __str__(self): | ||
return force_str(super().__str__()) | ||
# Loop through the values in the components' registry | ||
for _, plugin, slot_plugins in components._registry.values(): | ||
# Add the plugin to the global namespace | ||
globals()[plugin.__name__] = plugin | ||
# Register the plugin with the plugin pool | ||
plugin_pool.register_plugin(plugin) | ||
|
||
def render(self, context, instance, placeholder): | ||
for key, value in instance.config.items(): | ||
if isinstance(value, dict) and set(value.keys()) == {"pk", "model"}: | ||
if key not in instance.__dir__(): # hasattr would return the value in the config dict | ||
setattr(instance.__class__, key, get_related(key)) | ||
return super().render(context, instance, placeholder) | ||
|
||
def get_plugin_urls(self): | ||
from django.urls import re_path | ||
|
||
info = f"{self.model._meta.app_label}_{self.model._meta.model_name}" | ||
|
||
def pat(regex, fn): | ||
return re_path(regex, fn, name=f"{info}_{fn.__name__}") | ||
|
||
return [ | ||
pat(r'edit-field/(%s)/([a-z\-]+)/$' % SLUG_REGEXP, self.edit_field), | ||
] | ||
|
||
def _get_object_for_single_field(self, object_id, language): | ||
from .models import FrontendUIItem | ||
|
||
return FrontendUIItem.objects.get(pk=object_id) | ||
# Loop through the slot plugins associated with the current plugin | ||
for slot_plugin in slot_plugins: | ||
# Add the slot plugin to the global namespace | ||
globals()[slot_plugin.__name__] = slot_plugin | ||
# Register the slot plugin with the plugin pool | ||
plugin_pool.register_plugin(slot_plugin) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,97 +1,25 @@ | ||
import copy | ||
import importlib | ||
import warnings | ||
|
||
from cms.plugin_pool import plugin_pool | ||
from cms.templatetags.cms_tags import render_plugin | ||
from django.conf import settings | ||
from django.contrib.admin.sites import site as admin_site | ||
from django.template import engines | ||
from django.template.library import SimpleNode | ||
from django.template.loader import get_template | ||
from django.utils.module_loading import autodiscover_modules | ||
|
||
django_engine = engines["django"] | ||
|
||
plugin_tag_pool = {} | ||
class Components: | ||
_registry: dict = {} | ||
_discovered: bool = False | ||
|
||
def register(self, component): | ||
if component.__name__ in self._registry: | ||
warnings.warn(f"Component {component.__name__} already registered", stacklevel=2) | ||
return component | ||
self._registry[component.__name__] = component.get_registration() | ||
return component | ||
|
||
IGNORED_FIELDS = ( | ||
"id", | ||
"cmsplugin_ptr", | ||
"language", | ||
"plugin_type", | ||
"position", | ||
"creation_date", | ||
"ui_item", | ||
) | ||
def __getitem__(self, item): | ||
return self._registry[item] | ||
|
||
allowed_plugin_types = tuple( | ||
getattr(importlib.import_module(cls.rsplit(".", 1)[0]), cls.rsplit(".", 1)[-1]) if isinstance(cls, str) else cls | ||
for cls in getattr(settings, "CMS_COMPONENT_PLUGINS", []) | ||
) | ||
|
||
components = Components() | ||
|
||
def _get_plugindefaults(instance): | ||
defaults = { | ||
field.name: getattr(instance, field.name) | ||
for field in instance._meta.fields | ||
if field.name not in IGNORED_FIELDS and bool(getattr(instance, field.name)) | ||
} | ||
defaults["plugin_type"] = instance.__class__.__name__ | ||
return defaults | ||
|
||
|
||
class _DummyUser: | ||
is_superuser = True | ||
is_staff = True | ||
|
||
|
||
class _DummyRequest: | ||
user = _DummyUser() | ||
|
||
|
||
def render_dummy_plugin(context, dummy_plugin): | ||
return dummy_plugin.nodelist.render(context) | ||
|
||
|
||
def patch_template(template): | ||
"""Patches the template to use the dummy plugin renderer instead of the real one.""" | ||
copied_template = copy.deepcopy(template) | ||
patch = False | ||
for node in copied_template.template.nodelist.get_nodes_by_type(SimpleNode): | ||
if node.func == render_plugin: | ||
patch = True | ||
node.func = render_dummy_plugin | ||
return copied_template if patch else template | ||
|
||
|
||
def setup(): | ||
global plugin_tag_pool | ||
|
||
for plugin in plugin_pool.get_all_plugins(): | ||
if not issubclass(plugin, allowed_plugin_types): | ||
continue | ||
tag_name = plugin.__name__.lower() | ||
if tag_name.endswith("plugin"): | ||
tag_name = tag_name[:-6] | ||
try: | ||
instance = plugin.model() # Create instance with defaults | ||
plugin_admin = plugin(admin_site=admin_site) | ||
if hasattr(instance, "initialize_from_form"): | ||
instance.initialize_from_form(plugin.form) | ||
if tag_name not in plugin_tag_pool: | ||
template = get_template(plugin_admin._get_render_template({"request": None}, instance, None)) | ||
plugin_tag_pool[tag_name] = { | ||
"defaults": { | ||
**_get_plugindefaults(instance), | ||
**dict(plugin_type=plugin.__name__), | ||
}, | ||
"template": patch_template(template), | ||
"class": plugin, | ||
} | ||
else: # pragma: no cover | ||
warnings.warn( | ||
f"Duplicate candidates for {{% plugin \"{tag_name}\" %}} found. " | ||
f"Only registered {plugin_tag_pool[tag_name]['class'].__name__}.", stacklevel=1) | ||
except Exception as exc: # pragma: no cover | ||
warnings.warn(f"{plugin.__name__}: \n{str(exc)}", stacklevel=1) | ||
if not components._discovered: | ||
autodiscover_modules("cms_components", register_to=components) | ||
components._discovered = True |
Empty file.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.