Skip to content

Commit

Permalink
Redefine the way presets are specified
Browse files Browse the repository at this point in the history
  • Loading branch information
matthiask committed Dec 17, 2024
1 parent 7c61ab9 commit fae89c8
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 81 deletions.
13 changes: 7 additions & 6 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
97 changes: 22 additions & 75 deletions django_prose_editor/widgets.py
Original file line number Diff line number Diff line change
@@ -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(
'<script src="{}"{}></script>',
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={
Expand All @@ -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"),
Expand All @@ -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,
Expand All @@ -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",
]
}
)
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ dynamic = [
]
dependencies = [
"django>=4.2",
"django-js-asset>=3",
]

optional-dependencies.sanitize = [
Expand Down

0 comments on commit fae89c8

Please sign in to comment.