Skip to content

feat: Add CKEDITOR_BASEPATH configuration for CKEditor 4 #94

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

Merged
merged 14 commits into from
May 28, 2025
Merged
6 changes: 5 additions & 1 deletion djangocms_text/cms_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
from cms.utils.urlutils import admin_reverse

from . import settings
from .editors import get_editor_config
from .forms import ActionTokenValidationForm, RenderPluginForm, TextForm
from .html import render_dynamic_attributes
from .models import Text, _MAX_RTE_LENGTH
Expand All @@ -62,7 +63,10 @@
random_comment_exempt,
replace_plugin_tags,
)
from .widgets import TextEditorWidget, rte_config
from .widgets import TextEditorWidget


rte_config = get_editor_config()


def post_add_plugin(operation, **kwargs):
Expand Down
6 changes: 5 additions & 1 deletion djangocms_text/cms_toolbars.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@
from cms.toolbar_pool import toolbar_pool

from . import settings
from .editors import get_editor_config
from .utils import get_cancel_url, get_messages_url, get_render_plugin_url
from .widgets import TextEditorWidget, get_url_endpoint, rte_config
from .widgets import TextEditorWidget, get_url_endpoint


rte_config = get_editor_config()


class IconButton(Button):
Expand Down
21 changes: 20 additions & 1 deletion djangocms_text/contrib/text_ckeditor4/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
from cms.utils.urlutils import static_with_version
from django.conf import settings
from django.templatetags.static import static
from django.utils.functional import lazy
from django.utils.html import format_html, html_safe

from djangocms_text.editors import RTEConfig

from cms.utils.urlutils import static_with_version

@html_safe
class BasePath:
def __str__(self):
return format_html(
'<script src="{scriptsrc}" data-ckeditor-basepath="{basepath}"></script>',
scriptsrc=static("djangocms_text/js/basepath.js"),
basepath=getattr(
settings,
"TEXT_CKEDITOR_BASE_PATH",
lazy(static, str)("djangocms_text/vendor/ckeditor4/"),
),
)


ckeditor4 = RTEConfig(
name="ckeditor4",
config="CKEDITOR",
js=(
static_with_version("cms/js/dist/bundle.admin.base.min.js"),
BasePath(),
"djangocms_text/vendor/ckeditor4/ckeditor.js",
"djangocms_text/bundles/bundle.ckeditor4.min.js",
),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// CKEDITOR_BASEPATH is setting for CKEditor 4 which reveals the base path from which to load config etc.
// It can be configred by the TEXT_CKEDITOR_BASEPATH setting in the Django settings file.
// It's loaded in this script since we avoid inline scripts (to better support CSP headers) and it needs to be
// set before the CKEditor script is loaded which in turn needs to be loaded before the integration script.

window.CKEDITOR_BASEPATH = document.currentScript.dataset.ckeditorBasepath

4 changes: 4 additions & 0 deletions djangocms_text/editors.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,7 @@ class RTEConfig:
admin_css (Iterable[str]): An iterable of CSS files for the admin interface only.
inline_editing (bool): Whether to enable inline editing.
child_plugin_support (bool): Whether to support child plugins.
additional_context (dict | None): Additional context to pass to the editor's global setting.

Attributes:
name (str): The name of the RTE configuration.
Expand All @@ -445,6 +446,7 @@ class RTEConfig:
admin_css (Iterable[str]): An iterable of CSS files for the admin interface only.
inline_editing (bool): Whether to enable inline editing.
child_plugin_support (bool): Whether to support child plugins.
additional_context (dict): Additional context to pass to the editor's global setting.
"""

def __init__(
Expand All @@ -456,6 +458,7 @@ def __init__(
admin_css: Iterable[str] | None = None,
inline_editing: bool = False,
child_plugin_support: bool = False,
additional_context: dict | None = None,
):
""" """
self.name = name
Expand All @@ -465,6 +468,7 @@ def __init__(
self.admin_css = admin_css or ()
self.inline_editing = inline_editing
self.child_plugin_support = child_plugin_support
self.additional_context = additional_context or {}

def process_base_config(self, base_config: dict) -> dict:
"""
Expand Down
12 changes: 0 additions & 12 deletions djangocms_text/templates/cms/plugins/text_plugin_change_formx.html

This file was deleted.

5 changes: 2 additions & 3 deletions djangocms_text/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
from .editors import DEFAULT_TOOLBAR_CMS, DEFAULT_TOOLBAR_HTMLField, get_editor_base_config, get_editor_config
from .utils import admin_reverse, cms_placeholder_add_plugin

rte_config = get_editor_config()
#: The configuration for the text editor widget


@cache
def get_url_endpoint():
Expand Down Expand Up @@ -224,6 +221,7 @@ def get_installed_plugins(self):
def get_global_settings(self, language):
"""The global settings are shared by all widgets and are the same for all instances. They only need
to be loaded once."""
rte_config = get_editor_config()
# Get the toolbar setting
toolbar_setting = get_editor_base_config()
for plugin in self.installed_plugins:
Expand All @@ -247,6 +245,7 @@ def get_global_settings(self, language):
"render_plugin_url": self.render_plugin_url or "",
"cancel_plugin_url": self.cancel_url or "",
"messages_url": self.messages_url or "",
**rte_config.additional_context,
}

def render_additions(self, name, value, attrs=None, renderer=None):
Expand Down
4 changes: 4 additions & 0 deletions tests/integration/test_ckeditor4.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ def handle_console_message(msg):

page.goto(f"{live_server.url}{admin_reverse('cms_placeholder_edit_plugin', args=(text_plugin.pk,))}")

basepath = page.locator("script[data-ckeditor-basepath]").get_attribute("data-ckeditor-basepath")

assert basepath == "/static/djangocms_text/vendor/ckeditor4/"

editor = page.locator(".cke.cke_reset")
expect(editor).to_be_visible() # Editor

Expand Down