Skip to content

Commit

Permalink
Merge pull request #8 from RedTurtle/fix_deserializer_for_footertop
Browse files Browse the repository at this point in the history
Fix serializer/deserializer for footerTop blocks: use blocks handlers…
  • Loading branch information
cekk authored Apr 24, 2024
2 parents a049dad + 08c030c commit f17a6eb
Show file tree
Hide file tree
Showing 15 changed files with 256 additions and 50 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ jobs:
max-parallel: 4
matrix:
python: ["3.8", "3.9", "3.10", "3.11"]
plone: ["52", "60"]
exclude:
- python: "3.10"
plone: "52"
- python: "3.11"
plone: "52"
plone: ["60"]
# exclude:
# - python: "3.10"
# plone: "52"
# - python: "3.11"
# plone: "52"
steps:
- uses: actions/checkout@v3
- name: Cache eggs
Expand Down
3 changes: 2 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ Changelog
1.3.3 (unreleased)
------------------

- Nothing changed yet.
- Fix serializer/deserializer for footerTop blocks: use blocks handlers to fix data.
[cekk]


1.3.2 (2024-03-14)
Expand Down
2 changes: 1 addition & 1 deletion base.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ recipe = plone.recipe.codeanalysis
directory = ${buildout:directory}/src
flake8-exclude=bootstrap.py,bootstrap-buildout.py,docs,bin,*.egg,setup.py,overrides,omelette
flake8-max-complexity = 25
flake8-ignore = E203, E266, E501, W503, E999
flake8-ignore = E203, E266, E501, W503, E999, C101
flake8-max-line-length = 200
# flake8-select = B,C,E,F,W,T4,B9
flake8-extensions =
Expand Down
12 changes: 4 additions & 8 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,8 @@ ignore =
.gitattributes

[isort]
# for details see
# http://docs.plone.org/develop/styleguide/python.html#grouping-and-sorting
force_alphabetical_sort = True
force_single_line = True
lines_after_imports = 2
line_length = 200
not_skip = __init__.py
# black compatible isort rules:
profile = plone

[flake8]
# black compatible flake8 rules:
Expand All @@ -22,10 +17,11 @@ ignore =
E501
T001
C813
C101
# E203, E266
exclude = bootstrap.py,docs,*.egg.,omelette
max-line-length = 88
max-complexity = 18
select = B,C,E,F,W,T4,B9
builtins = unicode,basestring

builtins = unicode,basestring
3 changes: 1 addition & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@
install_requires=[
"setuptools",
"plone.api >= 1.8.4",
"plone.restapi",
"plone.app.dexterity",
"plone.restapi>=9.5.0",
"plone.volto",
],
extras_require={
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# -*- coding: utf-8 -*-
from plone.app.registry.browser import controlpanel
from redturtle.voltoplugin.editablefooter.interfaces import (
IEditableFooterSettings,
)
from redturtle.voltoplugin.editablefooter import _
from redturtle.voltoplugin.editablefooter.interfaces import IEditableFooterSettings


class EditableFooterForm(controlpanel.RegistryEditForm):
Expand Down
14 changes: 14 additions & 0 deletions src/redturtle/voltoplugin/editablefooter/restapi/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from plone.restapi.blocks import iter_block_transform_handlers
from plone.restapi.blocks import visit_blocks


def fix_footer_top_blocks(context, blocks, transformer):
if not blocks:
return blocks
for block in visit_blocks(context, blocks):
new_block = block.copy()
for handler in iter_block_transform_handlers(context, block, transformer):
new_block = handler(new_block)
block.clear()
block.update(new_block)
return blocks
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
from plone.restapi.controlpanels import RegistryConfigletPanel
from redturtle.voltoplugin.editablefooter.interfaces import IEditableFooterSettings
from redturtle.voltoplugin.editablefooter.interfaces import (
IRedturtleVoltoEditablefooterLayer,
IEditableFooterSettings,
)
from zope.component import adapter
from zope.interface import implementer
Expand Down
45 changes: 37 additions & 8 deletions src/redturtle/voltoplugin/editablefooter/restapi/deserializer.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
from plone import api
from plone.restapi.deserializer import json_body
from plone.restapi.deserializer.controlpanels import (
ControlpanelDeserializeFromJson,
)
from plone.restapi.deserializer.controlpanels import ControlpanelDeserializeFromJson
from plone.restapi.interfaces import IBlockFieldDeserializationTransformer
from plone.restapi.interfaces import IDeserializeFromJson
from redturtle.voltoplugin.editablefooter.interfaces import (
IEditableFooterSettings,
)
from redturtle.voltoplugin.editablefooter import _
from redturtle.voltoplugin.editablefooter.interfaces import IEditableFooterSettings
from redturtle.voltoplugin.editablefooter.restapi import fix_footer_top_blocks
from zExceptions import BadRequest
from zope.component import adapter
from zope.interface import implementer
Expand All @@ -21,10 +21,39 @@ def __call__(self):
req = json_body(self.controlpanel.request)
proxy = self.registry.forInterface(self.schema, prefix=self.schema_prefix)
errors = []
data = req.get("footer_columns", {})
data = req.get("footer_columns", [])
if not data:
errors.append({"message": "Missing data", "field": "footer_columns"})
errors.append(
{
"message": api.portal.translate(
_("missing_data_label", default="Missing data")
),
"field": "footer_columns",
}
)
raise BadRequest(errors)
if not isinstance(data, list):
errors.append(
{
"message": api.portal.translate(
_(
"wrong_type_data_label",
default="Wrong type: need to be a list of values",
)
),
"field": "footer_columns",
}
)
raise BadRequest(errors)
for path_setting in data:
footer_top = path_setting.get("footerTop", {}).get("blocks", {})
if footer_top:
path_setting["footerTop"]["blocks"] = fix_footer_top_blocks(
context=self.context,
blocks=footer_top,
transformer=IBlockFieldDeserializationTransformer,
)

try:
# later we need to do some validations
setattr(proxy, "footer_columns", json.dumps(data))
Expand Down
21 changes: 14 additions & 7 deletions src/redturtle/voltoplugin/editablefooter/restapi/get.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
# -*- coding: utf-8 -*-
from redturtle.voltoplugin.editablefooter.interfaces import (
IEditableFooterSettings,
)
from plone import api
from plone.registry.interfaces import IRegistry
from plone.restapi.interfaces import IBlockFieldSerializationTransformer
from plone.restapi.serializer.converters import json_compatible
from plone.restapi.services import Service
from redturtle.voltoplugin.editablefooter.interfaces import IEditableFooterSettings
from redturtle.voltoplugin.editablefooter.restapi import fix_footer_top_blocks
from zope.component import getUtility
from zope.interface import implementer
from zope.publisher.interfaces import IPublishTraverse


try:
from plone.volto.interfaces import IVoltoSettings

Expand All @@ -21,9 +23,6 @@

@implementer(IPublishTraverse)
class FooterColumns(Service):
def __init__(self, context, request):
super(FooterColumns, self).__init__(context, request)

def reply(self):
record = api.portal.get_registry_record(
"footer_columns", interface=IEditableFooterSettings, default=""
Expand All @@ -34,6 +33,14 @@ def reply(self):
portal_url = self.get_portal_url()
for el in data or []:
if isinstance(el, dict):
footer_top = el.get("footerTop", {}).get("blocks", {})
if footer_top:
el["footerTop"]["blocks"] = fix_footer_top_blocks(
context=self.context,
blocks=footer_top,
transformer=IBlockFieldSerializationTransformer,
)

for item in el.get("items") or []:
if (
isinstance(item, dict)
Expand All @@ -44,7 +51,7 @@ def reply(self):
item["text"]["data"] = item["text"]["data"].replace(
'href="/', f'href="{portal_url}/'
)
return data
return json_compatible(data)

def get_portal_url(self):
portal_url = api.portal.get().absolute_url()
Expand Down
25 changes: 19 additions & 6 deletions src/redturtle/voltoplugin/editablefooter/restapi/serializer.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
from redturtle.voltoplugin.editablefooter.interfaces import (
IEditableFooterSettings,
)
from plone import api
from plone.restapi.interfaces import IBlockFieldSerializationTransformer
from plone.restapi.interfaces import ISerializeToJson
from plone.restapi.serializer.controlpanels import ControlpanelSerializeToJson
from redturtle.voltoplugin.editablefooter.interfaces import IEditableFooterSettings
from redturtle.voltoplugin.editablefooter.restapi import fix_footer_top_blocks
from zope.component import adapter
from zope.interface import implementer

Expand All @@ -14,8 +15,20 @@
@adapter(IEditableFooterSettings)
class EditableFooterControlpanelSerializeToJson(ControlpanelSerializeToJson):
def __call__(self):
json_data = super(EditableFooterControlpanelSerializeToJson, self).__call__()
json_data = super().__call__()
conf = json_data["data"].get("footer_columns", "")
if conf:
json_data["data"]["footer_columns"] = json.loads(conf)
if not conf:
return json_data
footer_columns = json.loads(conf)

for path_setting in footer_columns:
footer_top = path_setting.get("footerTop", {}).get("blocks", {})
if footer_top:
path_setting["footerTop"]["blocks"] = fix_footer_top_blocks(
context=api.portal.get(),
blocks=footer_top,
transformer=IBlockFieldSerializationTransformer,
)

json_data["data"]["footer_columns"] = footer_columns
return json_data
2 changes: 1 addition & 1 deletion src/redturtle/voltoplugin/editablefooter/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
from plone.restapi.testing import PloneRestApiDXLayer
from plone.testing import z2

import redturtle.voltoplugin.editablefooter
import plone.restapi
import plone.volto
import redturtle.voltoplugin.editablefooter


class VoltoEditableFooterLayer(PloneSandboxLayer):
Expand Down
Loading

0 comments on commit f17a6eb

Please sign in to comment.