diff --git a/news/128.feature b/news/128.feature
new file mode 100644
index 0000000..9e8ad04
--- /dev/null
+++ b/news/128.feature
@@ -0,0 +1 @@
+Allows working copy of Plone Site. @wesleybl
diff --git a/plone/app/iterate/base.py b/plone/app/iterate/base.py
index 062574c..d38da35 100644
--- a/plone/app/iterate/base.py
+++ b/plone/app/iterate/base.py
@@ -65,7 +65,12 @@ def checkout(self, container):
# use the object copier to checkout the content to the container
copier = queryAdapter(self.context, IObjectCopier)
- working_copy, relation = copier.copyTo(container)
+ # The container for the Portal's working copy is the Portal itself.
+ if self.context.portal_type == "Plone Site":
+ working_copy_container = self.context
+ else:
+ working_copy_container = container
+ working_copy, relation = copier.copyTo(working_copy_container)
# publish the event for any subscribers
notify(CheckoutEvent(self.context, working_copy, relation))
diff --git a/plone/app/iterate/containers.py b/plone/app/iterate/containers.py
index c22142c..da1cc18 100644
--- a/plone/app/iterate/containers.py
+++ b/plone/app/iterate/containers.py
@@ -64,11 +64,11 @@ def __init__(self, context):
@property
def available(self):
- return bool(
- getSecurityManager().checkPermission(
- AddPortalContent, aq_parent(aq_inner(self.context))
- )
- )
+ obj = aq_inner(self.context)
+ # In Plone Site checkout, the working copy container is the portal itself.
+ if obj.portal_type != "Plone Site":
+ obj = aq_parent(obj)
+ return bool(getSecurityManager().checkPermission(AddPortalContent, obj))
def __call__(self):
if not self.available:
diff --git a/plone/app/iterate/dexterity/configure.zcml b/plone/app/iterate/dexterity/configure.zcml
index 0457c7b..2909fdf 100644
--- a/plone/app/iterate/dexterity/configure.zcml
+++ b/plone/app/iterate/dexterity/configure.zcml
@@ -29,4 +29,8 @@
+
+
+
+
diff --git a/plone/app/iterate/dexterity/copier.py b/plone/app/iterate/dexterity/copier.py
index bfa8ab4..3e4d47f 100644
--- a/plone/app/iterate/dexterity/copier.py
+++ b/plone/app/iterate/dexterity/copier.py
@@ -98,6 +98,10 @@ def _replaceBaseline(self, baseline):
return baseline
def _reassembleWorkingCopy(self, new_baseline, baseline):
+ # Does not change Plone Site permissions.
+ if new_baseline.portal_type == "Plone Site":
+ return new_baseline
+
# reattach the source's workflow history, try avoid a dangling ref
try:
new_baseline.workflow_history = PersistentMapping(
@@ -171,11 +175,20 @@ def checkin(self, checkin_message):
class FolderishContentCopier(ContentCopier):
def _copyBaseline(self, container):
+ if self.context.portal_type == "Plone Site":
+ portal_type = "Document"
+ else:
+ portal_type = self.context.portal_type
obj = createContentInContainer(
container,
- self.context.portal_type,
+ portal_type,
id=f"working_copy_of_{self.context.id}",
)
+ # Since the working copy of the Portal is originally a Document,
+ # we force its portal_type to "Plone Site", so that the "Plone Site"
+ # schema is used.
+ if self.context.portal_type == "Plone Site":
+ obj.portal_type = "Plone Site"
# copy all field values from the baseline to the working copy
for schema in iterSchemata(self.context):
diff --git a/plone/app/iterate/tests/test_containers.py b/plone/app/iterate/tests/test_containers.py
index b79735d..d18df35 100644
--- a/plone/app/iterate/tests/test_containers.py
+++ b/plone/app/iterate/tests/test_containers.py
@@ -219,11 +219,11 @@ def test_container_control_checkin_allowed_with_no_policy(self):
self.assertFalse(control.checkin_allowed())
def test_container_control_checkout_allowed_with_no_policy(self):
- control = Control(self.portal, self.layer["request"])
+ control = Control(self.portal.docs, self.layer["request"])
self.assertFalse(control.checkout_allowed())
def test_container_control_cancel_allowed_with_no_policy(self):
- control = Control(self.portal, self.layer["request"])
+ control = Control(self.portal.docs, self.layer["request"])
self.assertFalse(control.cancel_allowed())
def test_container_control_cancel_on_original_does_not_delete_original(self):
diff --git a/plone/app/iterate/tests/test_iterate.py b/plone/app/iterate/tests/test_iterate.py
index 93b9397..dc72b04 100644
--- a/plone/app/iterate/tests/test_iterate.py
+++ b/plone/app/iterate/tests/test_iterate.py
@@ -126,11 +126,11 @@ def test_control_checkin_allowed_with_no_policy(self):
self.assertFalse(control.checkin_allowed())
def test_control_checkout_allowed_with_no_policy(self):
- control = Control(self.portal, self.layer["request"])
+ control = Control(self.portal.docs, self.layer["request"])
self.assertFalse(control.checkout_allowed())
def test_control_cancel_allowed_with_no_policy(self):
- control = Control(self.portal, self.layer["request"])
+ control = Control(self.portal.docs, self.layer["request"])
self.assertFalse(control.cancel_allowed())
def test_control_cancel_on_original_does_not_delete_original(self):