From 88fa608d8f9d14cb2f42856f3f59c3b779ae1467 Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Mon, 2 Dec 2024 15:09:50 +0100 Subject: [PATCH] Introduce the concept of presets where each preset has its own initialization script --- django_prose_editor/fields.py | 9 +++- .../static/django_prose_editor/init.js | 2 +- django_prose_editor/widgets.py | 52 ++++++++++++------- src/init.js | 2 +- 4 files changed, 44 insertions(+), 21 deletions(-) diff --git a/django_prose_editor/fields.py b/django_prose_editor/fields.py index 7d735c8..10b37c9 100644 --- a/django_prose_editor/fields.py +++ b/django_prose_editor/fields.py @@ -25,6 +25,7 @@ class ProseEditorField(models.TextField): def __init__(self, *args, **kwargs): self.sanitize = kwargs.pop("sanitize", _actually_empty) self.config = kwargs.pop("config", {}) + self.preset = kwargs.pop("preset", "default") super().__init__(*args, **kwargs) def clean(self, value, instance): @@ -47,7 +48,11 @@ def deconstruct(self): return (name, "django.db.models.TextField", args, kwargs) def formfield(self, **kwargs): - defaults = {"config": self.config, "form_class": ProseEditorFormField} | kwargs + defaults = { + "config": self.config, + "form_class": ProseEditorFormField, + "preset": self.preset, + } | kwargs return super().formfield(**defaults) @@ -56,6 +61,7 @@ class ProseEditorFormField(forms.CharField): def __init__(self, *args, **kwargs): config = kwargs.pop("config", {}) + preset = kwargs.pop("preset", "default") widget = kwargs.get("widget") # We don't know if widget is set, and if it is, we do not know if it is @@ -74,3 +80,4 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.widget.config = config + self.widget.preset = preset diff --git a/django_prose_editor/static/django_prose_editor/init.js b/django_prose_editor/static/django_prose_editor/init.js index 97f67e1..005eab4 100644 --- a/django_prose_editor/static/django_prose_editor/init.js +++ b/django_prose_editor/static/django_prose_editor/init.js @@ -1 +1 @@ -(()=>{window.__proseEditor=JSON.parse(document.currentScript.dataset.config);var i="data-django-prose-editor";function H(t){if(t.closest(".prose-editor"))return;let o=JSON.parse(t.getAttribute(i)),{Document:n,Dropcursor:s,Gapcursor:l,Paragraph:c,HardBreak:a,Text:d,Blockquote:u,Bold:p,BulletList:g,Heading:k,HorizontalRule:b,Italic:h,ListItem:E,OrderedList:f,Strike:S,Subscript:_,Superscript:T,Underline:m,Link:B,Menu:D,NoSpellCheck:I,Typographic:L,createTextareaEditor:O}=DjangoProseEditor,e=(r=>z=>r!=null&&r.length?r.includes(z):!0)(o.types),j=[n,s,l,c,a,d,D.configure({config:o}),I,o.typographic&&L,e("blockquote")&&u,e("strong")&&p,e("bullet_list")&&g,e("heading")&&k,e("horizontal_rule")&&b,e("em")&&h,e("link")&&B.configure({openOnClick:!1}),(e("bullet_list")||e("ordered_list"))&&E,e("ordered_list")&&f,e("strikethrough")&&S,e("sub")&&_,e("sup")&&T,e("underline")&&m].filter(Boolean);return O(t,j)}DjangoProseEditor.initializeEditors(H,`[${i}]`);})(); +(()=>{window.__proseEditor=JSON.parse(document.currentScript.dataset.config);var i="data-django-prose-editor-default";function H(t){if(t.closest(".prose-editor"))return;let o=JSON.parse(t.getAttribute(i)),{Document:n,Dropcursor:l,Gapcursor:s,Paragraph:a,HardBreak:c,Text:d,Blockquote:u,Bold:p,BulletList:g,Heading:k,HorizontalRule:b,Italic:f,ListItem:h,OrderedList:E,Strike:S,Subscript:_,Superscript:T,Underline:m,Link:B,Menu:D,NoSpellCheck:I,Typographic:L,createTextareaEditor:O}=DjangoProseEditor,e=(r=>z=>r!=null&&r.length?r.includes(z):!0)(o.types),j=[n,l,s,a,c,d,D.configure({config:o}),I,o.typographic&&L,e("blockquote")&&u,e("strong")&&p,e("bullet_list")&&g,e("heading")&&k,e("horizontal_rule")&&b,e("em")&&f,e("link")&&B.configure({openOnClick:!1}),(e("bullet_list")||e("ordered_list"))&&h,e("ordered_list")&&E,e("strikethrough")&&S,e("sub")&&_,e("sup")&&T,e("underline")&&m].filter(Boolean);return O(t,j)}DjangoProseEditor.initializeEditors(H,`[${i}]`);})(); diff --git a/django_prose_editor/widgets.py b/django_prose_editor/widgets.py index 7e633fd..eb3e89c 100644 --- a/django_prose_editor/widgets.py +++ b/django_prose_editor/widgets.py @@ -1,13 +1,24 @@ import json from django import forms +from django.conf import settings from django.utils.translation import gettext from js_asset.js import JS +def _get_presets(): + presets = { + "default": { + "script": "django_prose_editor/init.js", + }, + } + return presets | getattr(settings, "DJANGO_PROSE_EDITOR_PRESETS", {}) + + class ProseEditorWidget(forms.Textarea): def __init__(self, *args, **kwargs): self.config = kwargs.pop("config", {}) + self.preset = kwargs.pop("preset", "default") super().__init__(*args, **kwargs) @property @@ -24,21 +35,24 @@ def media(self): "django_prose_editor/editor.js", {"defer": True}, ), - JS( - "django_prose_editor/init.js", - { - "defer": True, - "data-config": json.dumps( - { - "messages": { - "url": gettext("URL"), - "title": gettext("Title"), - "update": gettext("Update"), - "cancel": gettext("Cancel"), - }, - } - ), - }, + *( + JS( + preset["script"], + { + "defer": True, + "data-config": json.dumps( + { + "messages": { + "url": gettext("URL"), + "title": gettext("Title"), + "update": gettext("Update"), + "cancel": gettext("Cancel"), + }, + } + ), + }, + ) + for key, preset in _get_presets().items() ), ], ) @@ -53,9 +67,11 @@ def get_config(self): def get_context(self, name, value, attrs): context = super().get_context(name, value, attrs) - context["widget"]["attrs"]["data-django-prose-editor"] = json.dumps( - self.get_config(), - separators=(",", ":"), + context["widget"]["attrs"][f"data-django-prose-editor-{self.preset}"] = ( + json.dumps( + self.get_config(), + separators=(",", ":"), + ) ) return context diff --git a/src/init.js b/src/init.js index d950eca..564ec18 100644 --- a/src/init.js +++ b/src/init.js @@ -1,6 +1,6 @@ window.__proseEditor = JSON.parse(document.currentScript.dataset.config) -const marker = "data-django-prose-editor" +const marker = "data-django-prose-editor-default" function createEditor(textarea) { if (textarea.closest(".prose-editor")) return