Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add re-usable components #220

Merged
merged 133 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
133 commits
Select commit Hold shift + click to select a range
4245adc
Fix: Update locales and add floating options for images
fsbraun Nov 7, 2023
e66e618
Merge branch 'master' of github.com:fsbraun/djangocms-frontend
fsbraun Nov 7, 2023
cbaccdd
Merge branch 'master' of github.com:fsbraun/djangocms-frontend
fsbraun Nov 28, 2023
66e053e
fix: icons not showing in ckeditor
fsbraun Nov 28, 2023
fec0ece
Merge branch 'django-cms:master' into master
fsbraun Nov 28, 2023
49e4acc
Merge branch 'django-cms:master' into master
fsbraun Nov 28, 2023
a9ead97
Add image drag and drop
fsbraun Nov 28, 2023
9ac7126
Merge branch 'master' of github.com:fsbraun/djangocms-frontend
fsbraun Nov 28, 2023
f5f27b6
Update docs
fsbraun Nov 28, 2023
6d5fac4
Add tests
fsbraun Nov 28, 2023
18d60ab
Fix tests for v4
fsbraun Nov 28, 2023
44d5035
Bump version
fsbraun Nov 28, 2023
210cccd
Update changelog
fsbraun Nov 28, 2023
510494e
Merge branch 'django-cms:master' into master
fsbraun Nov 28, 2023
297d436
Merge branch 'django-cms:master' into master
fsbraun Dec 13, 2023
fc20a5a
Merge branch 'django-cms:master' into master
fsbraun Dec 15, 2023
606cc91
fix/remove-unused-css
fsbraun Dec 15, 2023
1af2ef9
Merge branch 'django-cms:master' into master
fsbraun Jan 4, 2024
60f810f
Merge branch 'django-cms:master' into master
fsbraun Jan 8, 2024
05a0939
Merge branch 'django-cms:master' into master
fsbraun Jan 8, 2024
a8e5f2d
Doc typos
fsbraun Jan 8, 2024
c7c8bcf
Merge branch 'django-cms:master' into master
fsbraun Jan 9, 2024
ad90c57
Fix: Missing space in auto column short description
fsbraun Jan 11, 2024
d2a2e78
Merge branch 'master' of github.com:fsbraun/djangocms-frontend
fsbraun Jan 11, 2024
41e58bc
Merge branch 'master' into master
fsbraun Jan 11, 2024
ef87c91
Unlist removed iconsets from the docs
fsbraun Jan 12, 2024
8d63c99
Merge branch 'django-cms:master' into master
fsbraun Jan 12, 2024
a165dcd
Merge branch 'master' into master
fsbraun Jan 13, 2024
c7e34a2
Merge branch 'django-cms:master' into master
fsbraun Feb 14, 2024
aa0aff9
Merge branch 'django-cms:master' into master
fsbraun Feb 16, 2024
1017581
Merge branch 'django-cms:master' into master
fsbraun Feb 28, 2024
4a6c6bf
Merge branch 'django-cms:master' into master
fsbraun Mar 21, 2024
25cbc79
Bump version
fsbraun Mar 21, 2024
a006821
Add translations
fsbraun Mar 21, 2024
47cb3d0
Update test environment
fsbraun Mar 21, 2024
17f3b71
Fix: Tree structure for pages
fsbraun Mar 21, 2024
1dd0e83
Restore Django 3.2 compatibility
fsbraun Mar 21, 2024
d405c51
Update changelog
fsbraun Mar 21, 2024
123ee85
Fix: Min width of select2 box
fsbraun Mar 21, 2024
e443877
Merge remote-tracking branch 'upstream/master'
fsbraun Mar 21, 2024
b8ba771
Fix icon picker
fsbraun Mar 21, 2024
68e9889
Prepopulate badge
fsbraun Mar 21, 2024
b6e5f34
Merge branch 'django-cms:master' into master
fsbraun Mar 21, 2024
8754e88
Merge branch 'django-cms:master' into master
fsbraun Apr 9, 2024
4151e55
Merge branch 'django-cms:master' into master
fsbraun Apr 10, 2024
fa6e98f
Merge branch 'django-cms:master' into master
fsbraun Apr 24, 2024
1d735ba
Add empty selection to internal link choices (fixes #206)
fsbraun Apr 24, 2024
1abe124
Merge branch 'django-cms:master' into master
fsbraun Apr 24, 2024
c2f8da8
Merge branch 'django-cms:master' into master
fsbraun Apr 24, 2024
0eb5feb
Fix pypi actions
fsbraun Apr 24, 2024
e993b33
Merge branch 'master' of github.com:fsbraun/djangocms-frontend
fsbraun Apr 24, 2024
6554f84
Add write permissions to pypi actions
fsbraun Apr 24, 2024
83e99f0
Add env.
fsbraun Apr 24, 2024
f3d5a93
fix: Unescape JSONView for django admin's autocomplete widget
fsbraun Apr 29, 2024
db4748a
Merge branch 'master' into fix/escape
fsbraun Apr 29, 2024
0dc9b41
Merge pull request #2 from fsbraun/fix/escape
fsbraun Apr 29, 2024
c615895
Add tests
fsbraun Apr 29, 2024
40cb02e
Merge branch 'fix/escape' of github.com:fsbraun/djangocms-frontend in…
fsbraun Apr 29, 2024
659ed56
Fix tests
fsbraun Apr 29, 2024
1b3c0cf
Merge branch 'django-cms:master' into fix/escape
fsbraun Apr 29, 2024
5918709
Merge pull request #4 from fsbraun/fix/escape
fsbraun Apr 29, 2024
3a44667
Merge branch 'django-cms:master' into master
fsbraun May 28, 2024
1156c6c
Add `{% plugin %}` template tag.
fsbraun May 28, 2024
9b57107
Fix tests
fsbraun May 28, 2024
353cdb3
Improve testing
fsbraun May 28, 2024
b8674ea
Cleanup
fsbraun May 28, 2024
817e666
Update readme.
fsbraun May 28, 2024
fc4628e
Fix readme formatting
fsbraun May 28, 2024
f7a740b
coverage
fsbraun May 28, 2024
89843f4
Fix: Side-effect on attributes
fsbraun May 28, 2024
7518b42
Update docs, add empty children messages
fsbraun May 29, 2024
b4975e9
Remove empty line
fsbraun May 29, 2024
52ec8c6
Refactor common module, add custom components
fsbraun May 29, 2024
e77d34a
first tailwind steps
fsbraun May 29, 2024
d4bfe19
Add slots to components
fsbraun Jun 6, 2024
afce5cb
Merge branch 'master' into feat/components
fsbraun Jun 6, 2024
66721a2
Update custom_components.rst
fsbraun Jun 11, 2024
369fac7
Update custom_components.rst
fsbraun Jun 11, 2024
d7a0172
Add Link-enabled component
fsbraun Jun 13, 2024
6753c90
add link fieldset position as component Meta
fsbraun Jun 13, 2024
6aba1db
Make ImageFields available through their field name in templtes
fsbraun Jun 18, 2024
7afd7fd
Merge branch 'master' into feat/components
fsbraun Jun 18, 2024
73d0940
Simplify related object access
fsbraun Jun 18, 2024
069f783
Fix: Typing for py3.9
fsbraun Jun 18, 2024
d5454fe
Update tests
fsbraun Jun 18, 2024
74cd0f9
Update testing
fsbraun Jun 18, 2024
b5053e9
Remove dj40 and dj41 from tests
fsbraun Jun 18, 2024
bc9a47f
Update test dependencies
fsbraun Jun 18, 2024
cfeeea2
Update tests
fsbraun Jun 18, 2024
3fba47c
Add html5lib dependency for tests
fsbraun Jun 18, 2024
ad135bd
Fix: versatile entangled form support
fsbraun Jun 18, 2024
bed084c
Performance: cached related properties
fsbraun Jun 19, 2024
3407419
Skip Link component test for django CMS 4.1 since djangocms-url-manag…
fsbraun Jun 20, 2024
19779c3
Fix: Workaround for newer versioning versions potentially used with d…
fsbraun Jun 20, 2024
cd465d7
Some pragma no-cover
fsbraun Jun 20, 2024
5289f5c
Add tailwind menu
fsbraun Jun 20, 2024
8d94c2a
Merge branch 'master' into feat/components
fsbraun Jul 1, 2024
a1c86df
Fix: get current page for link
fsbraun Jul 10, 2024
47af84f
Merge branch 'feat/components' of github.com:fsbraun/djangocms-fronte…
fsbraun Jul 10, 2024
7bdca5d
Fix: Migrations for components and rename `djangocms_frontend.pool` t…
fsbraun Jul 10, 2024
d06b71e
Merge branch 'master' into feat/components
fsbraun Jul 11, 2024
8f03797
Update docs
fsbraun Jul 22, 2024
219ceb6
Merge branch 'feat/components' of github.com:fsbraun/djangocms-fronte…
fsbraun Jul 22, 2024
4185bed
Merge branch 'master' into feat/components
fsbraun Aug 29, 2024
b1c48b2
Fix tests
fsbraun Aug 29, 2024
0f265bd
Add filer to test requirements
fsbraun Aug 29, 2024
e3cfcee
Update test requirements to include package requirements themselves
fsbraun Aug 29, 2024
bc5457c
Fix 3.11 test
fsbraun Aug 29, 2024
4012562
Update 5.1 test
fsbraun Aug 29, 2024
70cbbbf
Fix tests
fsbraun Aug 29, 2024
462de10
feat: Make component slots not editable
fsbraun Sep 13, 2024
943a0ba
Fix `child_plugins` improvement
fsbraun Sep 27, 2024
5bad1e9
fix tests
fsbraun Sep 27, 2024
a441b89
fix linting issues
fsbraun Sep 27, 2024
a7f00c9
Update docs build requirements
fsbraun Sep 27, 2024
5012df4
Update sphinx config
fsbraun Sep 27, 2024
fcffc51
Allow `get_render_template` for components
fsbraun Sep 29, 2024
bc1ecc7
Add tests for frontend editable endpoint
fsbraun Sep 29, 2024
bbb6159
Move non-bootstrap render function to plugin (image)
fsbraun Sep 30, 2024
7027832
Merge branch 'master' into feat/components
fsbraun Sep 30, 2024
10f9d66
Remove tailwind file
fsbraun Sep 30, 2024
603e526
Fix: update django-entangled requirement
fsbraun Sep 30, 2024
682e54f
fix coverage
fsbraun Sep 30, 2024
9f96a50
Add Django 5.1 tests
fsbraun Sep 30, 2024
053af23
Fix Django 5.1 test requirements
fsbraun Oct 1, 2024
cadf3a3
Merge branch 'master' into feat/components
fsbraun Oct 7, 2024
290e2a8
Improved inline editing for django CMS v3
fsbraun Oct 7, 2024
4b4c237
fix: Disallow edit for DummyPlugins
fsbraun Oct 7, 2024
e39fc8f
Update tests
fsbraun Oct 7, 2024
ec1bc8d
fix tests to independently install djangocms-url-manager
fsbraun Oct 7, 2024
42bc9c7
tests: Add test for related field descriptor
fsbraun Oct 7, 2024
af6ea3a
Fix: Register component models only once
fsbraun Oct 7, 2024
effbde2
Merge branch 'master' into feat/components
fsbraun Oct 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,6 @@ insert_final_newline = false

[*plugins/image.html]
insert_final_newline = false

[*.html]
indent_size = 2
13 changes: 4 additions & 9 deletions .github/workflows/codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,12 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [ 3.8, 3.9, "3.10", "3.11"] # latest release minus two
python-version: ["3.10", "3.11", "3.12"] # latest release minus two
requirements-file: [
dj32_cms38.txt,
dj32_cms39.txt,
dj32_cms41.txt,
dj40_cms311.txt,
dj41_cms311.txt,
dj42_cms311.txt,
dj40_cms41.txt,
dj41_cms41.txt,
dj42_cms41.txt,
dj50_cms41.txt,
dj51_cms41.txt,
]
os: [
ubuntu-20.04,
Expand All @@ -40,6 +35,6 @@ jobs:
- name: Generate Report
run: |
pip install -r tests/requirements/${{ matrix.requirements-file }}
coverage run setup.py test
coverage run run_tests.py
- name: Upload Coverage to Codecov
uses: codecov/codecov-action@v4
4 changes: 2 additions & 2 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
key: ${{ runner.os }}-pip-${{ hashFiles('docs/requirements.in') }}
restore-keys: |
${{ runner.os }}-pip-
- run: python -m pip install -r docs/requirements.in
- run: python -m pip install -r docs/requirements.txt
- name: Build docs
run: |
cd docs
Expand All @@ -50,7 +50,7 @@ jobs:
key: ${{ runner.os }}-pip-${{ hashFiles('docs/requirements.in') }}
restore-keys: |
${{ runner.os }}-pip-
- run: python -m pip install -r docs/requirements.in
- run: python -m pip install -r docs/requirements.txt
- name: Check spelling
run: |
cd docs
Expand Down
36 changes: 22 additions & 14 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,31 @@ currently used frontend framework such as Bootstrap, or its specific version.
Key features
============

- Support of `Bootstrap 5 <https://getbootstrap.com>`_, django CMS 3.8+
and the new upcoming major django CMS 4.
- Support of `Bootstrap 5 <https://getbootstrap.com>`_, django CMS 3.8+
and django CMS 4.

- **Separation of plugins from css framework**, i.e. no need to
rebuild you site's plugin tree if css framework is changed in the
future, e.g. from Bootstrap 5 to a future version.
- **Separation of plugins from css framework**, i.e. no need to
rebuild you site's plugin tree if css framework is changed in the
future, e.g. from Bootstrap 5 to a future version.

- **New link plugin** allowing to link to internal pages provided by
other applications, such as `djangocms-blog
<https://github.com/nephila/djangocms-blog>`_.
- **New link plugin** allowing to link to internal pages provided by
other applications, such as `djangocms-blog
<https://github.com/nephila/djangocms-blog>`_.

- **Nice and well-arranged admin frontend** of `djangocms-bootstrap4
<https://github.com/django-cms/djangocms-bootstrap4>`_
- **Nice and well-arranged admin frontend** of `djangocms-bootstrap4
<https://github.com/django-cms/djangocms-bootstrap4>`_

- **Extensible** within the project and with separate project (e.g. a
theme app). Create your own components with a few lines of code only.

- **Plugins are re-usable as UI components** anywhere in your project
(e.g. in a custom app) giving your whole project a more consistent
user experience.

- A management command to **migrate from djangocms-bootstrap4**. This
command automatically migrates all ``djangocms-bootstrap4`` plugins to
``djangocms-frontend``.

- **Extensible** within the project and with separate project (e.g. a
theme app)


Description
===========
Expand All @@ -55,6 +59,10 @@ The link plugin has been rewritten to not only allow internal links to other
CMS pages, but also to other django models such as, e.g., posts of
`djangocms-blog <https://github.com/nephila/djangocms-blog>`_.

The plugins are designed to be re-usable as UI components in your
project, e.g. in a custom app, giving your whole project a more
consistent user experience.

Contributing
============

Expand Down Expand Up @@ -150,7 +158,7 @@ See readthedocs for the `documentation
License
=======

See `LICENSE <https://github.com/django-cms/djangocms-frontend/blob/master/LICENSE>`_.
See `LICENSE <https://github.com/django-cms/djangocms-frontend/blob/master/LICENSE>`_.

.. |pypi| image:: https://badge.fury.io/py/djangocms-frontend.svg
:target: http://badge.fury.io/py/djangocms-frontend
Expand Down
2 changes: 1 addition & 1 deletion djangocms_frontend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@
13. Github actions will publish the new package to pypi
"""

__version__ = "1.3.4"
__version__ = "2.0.0a"
11 changes: 11 additions & 0 deletions djangocms_frontend/apps.py
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()
36 changes: 35 additions & 1 deletion djangocms_frontend/cms_plugins.py
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

Check warning on line 9 in djangocms_frontend/cms_plugins.py

View check run for this annotation

Codecov / codecov/patch

djangocms_frontend/cms_plugins.py#L9

Added line #L9 was not covered by tests
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)
40 changes: 40 additions & 0 deletions djangocms_frontend/common/__init__.py
Original file line number Diff line number Diff line change
@@ -1,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:

Check warning on line 20 in djangocms_frontend/common/__init__.py

View check run for this annotation

Codecov / codecov/patch

djangocms_frontend/common/__init__.py#L20

Added line #L20 was not covered by tests
for cls in classes:
globals()[cls] = type(cls, (object,), {})

Check warning on line 22 in djangocms_frontend/common/__init__.py

View check run for this annotation

Codecov / codecov/patch

djangocms_frontend/common/__init__.py#L22

Added line #L22 was not covered by tests

__all__ = [
"TitleMixin",
"TitleFormMixin",
"AttributesMixin",
"BackgroundFormMixin",
"BackgroundMixin",
"ResponsiveFormMixin",
"ResponsiveMixin",
"SizingFormMixin",
"SizingMixin",
"SpacingFormMixin",
"SpacingMixin",
"MarginFormMixin",
"MarginMixin",
"PaddingFormMixin",
"PaddingMixin",
]
15 changes: 0 additions & 15 deletions djangocms_frontend/common/background.py

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ def compress(self, data_list):
return ""

def clean(self, value):
value = value or ["", ""]
if value[1] and not value[0]:
raise ValidationError(
_("Please choose a side to which the spacing should be applied."),
Expand Down
15 changes: 0 additions & 15 deletions djangocms_frontend/common/responsive.py

This file was deleted.

15 changes: 0 additions & 15 deletions djangocms_frontend/common/sizing.py

This file was deleted.

97 changes: 97 additions & 0 deletions djangocms_frontend/component_pool.py
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)
4 changes: 3 additions & 1 deletion djangocms_frontend/contrib/accordion/cms_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from ... import settings
from ...cms_plugins import CMSUIPlugin
from ...common.attributes import AttributesMixin
from ...common import AttributesMixin
from ...helpers import add_plugin
from .. import accordion
from . import forms, models
Expand Down Expand Up @@ -98,3 +98,5 @@ class AccordionItemPlugin(mixin_factory("AccordionItem"), CMSUIPlugin):
},
),
]

frontend_editable_fields = ("accordion_item_header",)
Loading