Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news/2039.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add IJsonCompatible converter for IRichTextValue to handle nested RichText fields safely.
1 change: 1 addition & 0 deletions src/plone/restapi/serializer/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
<adapter factory=".converters.persistent_mapping_converter" />
<adapter factory=".converters.python_datetime_converter" />
<adapter factory=".converters.RichtextDXContextConverter" />
<adapter factory=".converters.richtext_converter" />
<adapter factory=".converters.set_converter" />
<adapter factory=".converters.bytes_converter" />
<adapter factory=".converters.time_converter" />
Expand Down
10 changes: 10 additions & 0 deletions src/plone/restapi/serializer/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,16 @@ def timedelta_converter(value):
return json_compatible(value.total_seconds())


@adapter(IRichTextValue)
@implementer(IJsonCompatible)
def richtext_converter(value):
return {
"data": json_compatible(value.raw),
"content-type": json_compatible(value.mimeType),
"encoding": json_compatible(value.encoding),
}


@adapter(IRichTextValue, IDexterityContent)
@implementer(IContextawareJsonCompatible)
class RichtextDXContextConverter:
Expand Down
14 changes: 14 additions & 0 deletions src/plone/restapi/tests/test_serializer_converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from DateTime import DateTime
from persistent.list import PersistentList
from persistent.mapping import PersistentMapping
from plone.app.textfield.value import RichTextValue
from plone.restapi.serializer.converters import json_compatible
from plone.restapi.testing import PLONE_RESTAPI_DX_INTEGRATION_TESTING
from unittest import TestCase
Expand Down Expand Up @@ -218,3 +219,16 @@ def test_i18n_message(self):

def test_missing_value(self):
self.assertEqual(None, json_compatible(Missing.Value))

def test_richtext_value_nested(self):
value = RichTextValue(
raw="<p>foo</p>", mimeType="text/html", outputMimeType="text/x-html-safe"
)
self.assertEqual(
{
"data": "<p>foo</p>",
"content-type": "text/html",
"encoding": "utf-8",
},
json_compatible({"foo": value})["foo"],
)