diff --git a/CHANGES.rst b/CHANGES.rst index c90f53c..d27aa94 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,10 @@ Changelog 5.0.3 (unreleased) ------------------ -- Nothing changed yet. +- Fix creation script: now set default blocks and blocks_layout. + [cekk] +- Upgrade-step to fix all contents with broken blocks_layout. + [cekk] 5.0.2 (2023-05-09) diff --git a/src/design/plone/policy/profiles/default/metadata.xml b/src/design/plone/policy/profiles/default/metadata.xml index 8bcbc2f..2a0a549 100644 --- a/src/design/plone/policy/profiles/default/metadata.xml +++ b/src/design/plone/policy/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 3002 + 3100 profile-plone.restapi:default profile-design.plone.contenttypes:default diff --git a/src/design/plone/policy/tests/test_initial_structure.py b/src/design/plone/policy/tests/test_initial_structure.py index 5fe5f7c..11f6ffa 100644 --- a/src/design/plone/policy/tests/test_initial_structure.py +++ b/src/design/plone/policy/tests/test_initial_structure.py @@ -7,6 +7,7 @@ from design.plone.policy.utils import TASSONOMIA_SERVIZI from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID +from plone.restapi.behaviors import IBlocks from plone.i18n.normalizer.interfaces import IURLNormalizer from zope.component import getUtility @@ -27,7 +28,7 @@ def normalize_ids(self, string): return getUtility(IURLNormalizer).normalize(string) def check_initial_blocks(self, obj): - self.assertEqual(obj.portal_type, "Document") + self.assertTrue(IBlocks.providedBy(obj)) self.assertEqual(len(obj.blocks.values()), 1) self.assertEqual(len(obj.blocks_layout["items"]), 1) @@ -108,3 +109,10 @@ def test_argomenti_section(self): self.assertEqual(child.portal_type, "Pagina Argomento") self.assertEqual(len(child.blocks.values()), 1) self.assertEqual(len(child.blocks_layout["items"]), 1) + + def test_enabled_blocks_contents_have_defaults(self): + brains = self.portal.portal_catalog( + object_provides="plone.restapi.behaviors.IBlocks" + ) + for brain in brains: + self.check_initial_blocks(brain.getObject()) diff --git a/src/design/plone/policy/upgrades.py b/src/design/plone/policy/upgrades.py index 391faa5..f72fa67 100644 --- a/src/design/plone/policy/upgrades.py +++ b/src/design/plone/policy/upgrades.py @@ -5,10 +5,12 @@ from design.plone.policy.interfaces import IDesignPlonePolicySettings from design.plone.policy.setuphandlers import disable_searchable_types from design.plone.policy.setuphandlers import set_default_subsite_colors +from design.plone.policy.utils import create_default_blocks from plone import api from plone.app.upgrade.utils import installOrReinstallProduct from plone.dexterity.utils import iterSchemata from plone.registry.interfaces import IRegistry +from plone.restapi.behaviors import IBlocks from Products.CMFPlone.interfaces import IFilterSchema from Products.CMFPlone.interfaces import ISelectableConstrainTypes from zope.component import getUtility @@ -328,3 +330,37 @@ def to_3001(context): run_dependencies=False, ) installOrReinstallProduct(api.portal.get(), "collective.feedback") + + +def to_3100(context): + already_modified = [] + not_modified = [] + brains = api.content.find(object_provides=IBlocks.__identifier__) + tot = len(brains) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info(f"Progress: {i}/{tot}") + item = brain.getObject().aq_base + blocks = getattr(item, "blocks", {}) + blocks_layout = getattr(item, "blocks_layout", {}) + + if blocks and blocks_layout == {"items": []}: + # case where document has been created without blocks, and has been modified + item.blocks_layout = {"items": [x for x in blocks.keys()]} + already_modified.append(brain.getPath()) + continue + if not blocks and blocks_layout == {"items": []}: + create_default_blocks(item) + not_modified.append(brain.getPath()) + + if already_modified: + logger.info("### Items that were already modified ###") + for i, path in enumerate(already_modified): + logger.info(f"[{i+1}/{len(already_modified)}] - {path}") + + if not_modified: + logger.info("### Items that were not modified ###") + for i, path in enumerate(not_modified): + logger.info(f"[{i+1}/{len(not_modified)}] - {path}") diff --git a/src/design/plone/policy/upgrades.zcml b/src/design/plone/policy/upgrades.zcml index 79a6290..bd112bc 100644 --- a/src/design/plone/policy/upgrades.zcml +++ b/src/design/plone/policy/upgrades.zcml @@ -171,4 +171,14 @@ handler=".upgrades.update_rolemap" /> + + + diff --git a/src/design/plone/policy/utils.py b/src/design/plone/policy/utils.py index e66e5a1..0468f35 100644 --- a/src/design/plone/policy/utils.py +++ b/src/design/plone/policy/utils.py @@ -4,6 +4,7 @@ from collective.volto.subfooter.interfaces import ISubfooter from plone import api from plone.i18n.normalizer.interfaces import IIDNormalizer +from plone.restapi.behaviors import IBlocks from plone.restapi.interfaces import ISerializeToJsonSummary from Products.CMFPlone.interfaces import ISelectableConstrainTypes from redturtle.voltoplugin.editablefooter.interfaces import IEditableFooterSettings @@ -231,9 +232,10 @@ def restrict_types(context, types): def create_default_blocks(context): - title_uuid = str(uuid4()) - context.blocks = {title_uuid: {"@type": "title"}} - context.blocks_layout = {"items": [title_uuid]} + if IBlocks.providedBy(context): + title_uuid = str(uuid4()) + context.blocks = {title_uuid: {"@type": "title"}} + context.blocks_layout = {"items": [title_uuid]} def create_footer(): @@ -245,6 +247,7 @@ def create_footer(): type=item.get("type", "Pagina"), title=item.get("title", "Titolo"), ) + create_default_blocks(context=obj) api.content.transition(obj=obj, transition="publish") item["path"] = f"/{obj.getId()}" obj.exclude_from_nav = True @@ -334,6 +337,7 @@ def create_footer(): type="Document", title="Media Policy", ) + create_default_blocks(context=obj) obj.exclude_from_nav = True obj.reindexObject()