-
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.
feat: Add re-usable components (#220)
- Loading branch information
Showing
122 changed files
with
2,240 additions
and
501 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,3 +38,6 @@ insert_final_newline = false | |
|
||
[*plugins/image.html] | ||
insert_final_newline = false | ||
|
||
[*.html] | ||
indent_size = 2 |
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
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 |
---|---|---|
|
@@ -19,4 +19,4 @@ | |
13. Github actions will publish the new package to pypi | ||
""" | ||
|
||
__version__ = "1.3.4" | ||
__version__ = "2.0.0a" |
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 |
---|---|---|
@@ -0,0 +1,11 @@ | ||
from django import apps | ||
|
||
|
||
class DjangocmsFrontendConfig(apps.AppConfig): | ||
name = "djangocms_frontend" | ||
verbose_name = "DjangoCMS Frontend" | ||
|
||
def ready(self): | ||
from .component_pool import setup | ||
|
||
setup() |
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,10 +1,44 @@ | ||
from cms.constants import SLUG_REGEXP | ||
from cms.plugin_base import CMSPluginBase | ||
from django.utils.encoding import force_str | ||
|
||
from djangocms_frontend.helpers import get_related | ||
|
||
class CMSUIPlugin(CMSPluginBase): | ||
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(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__()) | ||
|
||
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) |
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 |
---|---|---|
@@ -0,0 +1,40 @@ | ||
from importlib import import_module | ||
|
||
from djangocms_frontend import settings | ||
|
||
from .title import TitleFormMixin, TitleMixin | ||
|
||
__common = { | ||
"attributes": ("AttributesMixin",), | ||
"background": ("BackgroundFormMixin", "BackgroundMixin"), | ||
"responsive": ("ResponsiveFormMixin", "ResponsiveMixin"), | ||
"sizing": ("SizingFormMixin", "SizingMixin"), | ||
"spacing": ("SpacingFormMixin", "SpacingMixin", "MarginFormMixin", "MarginMixin", "PaddingFormMixin", "PaddingMixin"), | ||
} | ||
|
||
for module, classes in __common.items(): | ||
try: | ||
module = import_module(f"{__name__}.{settings.framework}.{module}", module) | ||
for cls in classes: | ||
globals()[cls] = getattr(module, cls) | ||
except ModuleNotFoundError: | ||
for cls in classes: | ||
globals()[cls] = type(cls, (object,), {}) | ||
|
||
__all__ = [ | ||
"TitleMixin", | ||
"TitleFormMixin", | ||
"AttributesMixin", | ||
"BackgroundFormMixin", | ||
"BackgroundMixin", | ||
"ResponsiveFormMixin", | ||
"ResponsiveMixin", | ||
"SizingFormMixin", | ||
"SizingMixin", | ||
"SpacingFormMixin", | ||
"SpacingMixin", | ||
"MarginFormMixin", | ||
"MarginMixin", | ||
"PaddingFormMixin", | ||
"PaddingMixin", | ||
] |
This file was deleted.
Oops, something went wrong.
File renamed without changes.
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 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
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 | ||
|
||
django_engine = engines["django"] | ||
|
||
plugin_tag_pool = {} | ||
|
||
|
||
IGNORED_FIELDS = ( | ||
"id", | ||
"cmsplugin_ptr", | ||
"language", | ||
"plugin_type", | ||
"position", | ||
"creation_date", | ||
"ui_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", []) | ||
) | ||
|
||
|
||
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) |
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.