From fae89c87df7c82e1eee524f25207c1e2a589aa2f Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Tue, 17 Dec 2024 11:59:36 +0100 Subject: [PATCH] Redefine the way presets are specified --- README.rst | 13 ++--- django_prose_editor/widgets.py | 97 ++++++++-------------------------- pyproject.toml | 1 + 3 files changed, 30 insertions(+), 81 deletions(-) diff --git a/README.rst b/README.rst index 8708cff..225d6c9 100644 --- a/README.rst +++ b/README.rst @@ -94,15 +94,16 @@ Customization **NOTE!** The previous way of customizing the editor is still supported, but it's not recommended (and documented) anymore. -The editor can be customized using presets; the way to do this is by adding a list of presets to your Django settings: +The editor can be customized using presets; the way to do this is by adding +additional assets to load: .. code-block:: python - DJANGO_PROSE_EDITOR_PRESETS = { - "announcements": { - "script": "prose-editors/announcements.js", - }, - } + from js_asset import JS + + DJANGO_PROSE_EDITOR_ASSETS = [ + JS("prose-editors/announcements.js", {"defer": True}), + ] The preset can be selected when instantiating the field: diff --git a/django_prose_editor/widgets.py b/django_prose_editor/widgets.py index 34c05c2..d11c2a7 100644 --- a/django_prose_editor/widgets.py +++ b/django_prose_editor/widgets.py @@ -1,58 +1,19 @@ import json -from functools import cached_property from django import forms from django.conf import settings -from django.forms.utils import flatatt from django.templatetags.static import static -from django.utils.html import format_html, json_script, mark_safe from django.utils.translation import gettext_lazy - - -class JS: - def __init__(self, src, attrs): - self.src = src - self.attrs = attrs - - def __html__(self): - return format_html( - '', - self.src - if self.src.startswith(("http://", "https://", "/")) - else static(self.src), - mark_safe(flatatt(self.attrs)), - ) - - def __eq__(self, other): - return ( - isinstance(other, JS) - and self.src == other.src - and self.attrs == other.attrs - ) - - def __hash__(self): - return hash(self.__str__()) - - -class JSON: - def __init__(self, id, data): - self.id = id - self.data = data - - def __html__(self): - return json_script(self.data, self.id) - - def __eq__(self, other): - return ( - isinstance(other, JSON) and self.id == other.id and self.data == other.data - ) - - def __hash__(self): - return hash(self.__str__()) +from js_asset import JS, JSON class ProseEditorWidget(forms.Textarea): - @cached_property + def __init__(self, *args, **kwargs): + self.config = kwargs.pop("config", {}) + self.preset = kwargs.pop("preset", "default") + super().__init__(*args, **kwargs) + + @property def base_media(self): return forms.Media( css={ @@ -62,12 +23,8 @@ def base_media(self): ] }, js=[ - JS( - "django_prose_editor/editor.js", - {"defer": True}, - ), + JS("django_prose_editor/editor.js", {"defer": True}), JSON( - "django-prose-editor-settings", { "stylesheets": [ static("django_prose_editor/material-icons.css"), @@ -80,35 +37,20 @@ def base_media(self): "cancel": gettext_lazy("Cancel"), }, }, + "django-prose-editor-settings", ), + JS("django_prose_editor/init.js", {"defer": True}), ], ) - def __init__(self, *args, **kwargs): - self.config = kwargs.pop("config", {}) - self.preset = kwargs.pop("preset", "default") - super().__init__(*args, **kwargs) - @property def media(self): - return self.base_media + forms.Media( - js=[ - JS( - preset["script"], - {"defer": True}, - ) - for key, preset in self.get_presets().items() - ], + return ( + (self.base_media + forms.Media(js=assets)) + if (assets := getattr(settings, "DJANGO_PROSE_EDITOR_ASSETS", ())) + else self.base_media ) - def get_presets(self): - presets = { - "default": { - "script": "django_prose_editor/init.js", - }, - } - return presets | getattr(settings, "DJANGO_PROSE_EDITOR_PRESETS", {}) - def get_config(self): return self.config or { "types": None, @@ -130,7 +72,12 @@ def get_context(self, name, value, attrs): class AdminProseEditorWidget(ProseEditorWidget): @property - def media(self): - return super().media + forms.Media( - css={"all": ["django_prose_editor/overrides.css"]} + def base_media(self): + return super().base_media + forms.Media( + css={ + "all": [ + "django_prose_editor/editor.css", # For the ordering + "django_prose_editor/overrides.css", + ] + } ) diff --git a/pyproject.toml b/pyproject.toml index 2abd369..4d29ebd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,6 +36,7 @@ dynamic = [ ] dependencies = [ "django>=4.2", + "django-js-asset>=3", ] optional-dependencies.sanitize = [