diff --git a/wagtail/admin/rich_text/editors/draftail/__init__.py b/wagtail/admin/rich_text/editors/draftail/__init__.py index 9ecaf9d474..18068d3e75 100644 --- a/wagtail/admin/rich_text/editors/draftail/__init__.py +++ b/wagtail/admin/rich_text/editors/draftail/__init__.py @@ -2,7 +2,9 @@ import json import warnings from django.forms import Media, widgets +from django.urls import reverse_lazy from django.utils.functional import cached_property +from django.utils.translation import gettext_lazy from wagtail.admin.rich_text.converters.contentstate import ContentstateConverter from wagtail.admin.staticfiles import versioned_static @@ -11,6 +13,21 @@ from wagtail.telepath import register from wagtail.widget_adapters import WidgetAdapter +class LazyStringEncoder(json.JSONEncoder): + """ + Add support for lazy strings to the JSON encoder so that URLs and + translations can be resolved when rendering the widget only. + """ + + lazy_string_types = [type(reverse_lazy("")), type(gettext_lazy(""))] + + def default(self, obj): + if type(obj) in self.lazy_string_types: + return str(obj) + + return json.JSONEncoder.default(self, obj) + + class DraftailRichTextArea(widgets.HiddenInput): template_name = "wagtailadmin/widgets/draftail_rich_text_area.html" is_hidden = False @@ -65,7 +82,9 @@ class DraftailRichTextArea(widgets.HiddenInput): def get_context(self, name, value, attrs): context = super().get_context(name, value, attrs) - context["widget"]["options_json"] = json.dumps(self.options) + context["widget"]["options_json"] = json.dumps( + self.options, cls=LazyStringEncoder + ) return context def value_from_datadict(self, data, files, name):