From cfff50f81c5611701643406ea52fb796c673c1e2 Mon Sep 17 00:00:00 2001 From: David Henne Date: Tue, 28 Sep 2021 16:20:38 -0500 Subject: [PATCH 1/2] Add 'untemplate' action. Change modal options if an object is a template or not. --- castle/cms/browser/content/actions.py | 19 ++++++++++++++++++- castle/cms/tasks/template.py | 11 ++++++++++- castle/cms/tests/test_content.py | 18 +++++++++++++++++- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/castle/cms/browser/content/actions.py b/castle/cms/browser/content/actions.py index 07eb68a2d..4807dceac 100644 --- a/castle/cms/browser/content/actions.py +++ b/castle/cms/browser/content/actions.py @@ -6,6 +6,7 @@ from castle.cms import tasks from castle.cms import trash from castle.cms.browser.utils import Utils +from castle.cms.interfaces import ITemplate from castle.cms.tasks import template from castle.cms.utils import get_paste_data from castle.cms.utils import is_max_paste_items @@ -179,7 +180,9 @@ class TemplateForm(form.Form): description = _('description_convert_template', default='"Convert to Template" will turn current item into a template ' + 'and move it to repository folder, while "Copy to Template" ' + - 'will keep current item and create a template from a copied version.') + 'will keep current item and create a template from a copied version. ' + + 'If the current object is already a template, you will have the option ' + + 'to "Untemplate" and revert to a regular object.') @button.buttonAndHandler(_(u'Convert To Template'), name='Convert') def handle_convert(self, action): @@ -193,6 +196,12 @@ def handle_copy(self, action): IStatusMessage(self.request).add(u'%s has been copied to template.' % template_obj.title) return self.do_redirect(template_obj) + @button.buttonAndHandler(_(u'Untemplate'), name='Untemplate') + def handle_untemplate(self, action): + template_obj = template.untemplate(self.context) + IStatusMessage(self.request).add(u'%s is no longer a template.' % template_obj.title) + return self.do_redirect(template_obj) + @button.buttonAndHandler(u'Cancel', name='Cancel') def handle_cancel(self, action): return self.do_redirect(self.context) @@ -201,3 +210,11 @@ def do_redirect(self, context): utils = Utils(self.context, self.request) target = utils.get_object_url(context) return self.request.response.redirect(target) + + def updateActions(self): + super(TemplateForm, self).updateActions() + if ITemplate.providedBy(self.context): + del self.actions["Copy"] + del self.actions["Convert"] + else: + del self.actions["Untemplate"] diff --git a/castle/cms/tasks/template.py b/castle/cms/tasks/template.py index e270f2aa4..fed36e513 100644 --- a/castle/cms/tasks/template.py +++ b/castle/cms/tasks/template.py @@ -2,7 +2,7 @@ from castle.cms.interfaces import ITemplate from plone import api from zope.component.hooks import getSite -from zope.interface import alsoProvides +from zope.interface import alsoProvides, noLongerProvides def save_as_template(obj, action): @@ -22,3 +22,12 @@ def save_as_template(obj, action): site.template_list = [template_obj] return template_obj + + +def untemplate(obj): + if ITemplate.providedBy(obj): + noLongerProvides(obj, ITemplate) + site = getSite() + if obj in site.template_list: + site.template_list.remove(obj) + return obj diff --git a/castle/cms/tests/test_content.py b/castle/cms/tests/test_content.py index 8a01722d8..5068a29e8 100644 --- a/castle/cms/tests/test_content.py +++ b/castle/cms/tests/test_content.py @@ -6,7 +6,7 @@ from castle.cms.browser import content from castle.cms.interfaces import ITemplate -from castle.cms.tasks.template import save_as_template +from castle.cms.tasks.template import save_as_template, untemplate from castle.cms.testing import CASTLE_PLONE_INTEGRATION_TESTING from plone import api from plone.app.testing import TEST_USER_ID @@ -289,6 +289,22 @@ def test_template_action_in_toolbar(self): temp_action_in_toolbar = True self.assertTrue(temp_action_in_toolbar) + def test_untemplate(self): + site = getSite() + obj = api.content.create( + type='Document', + id='template-document', + title='Template Document', + container=self.portal) + + template_obj = save_as_template(obj, 'convert') + self.assertTrue(ITemplate.providedBy(template_obj)) + self.assertTrue(template_obj in site.template_list) + + untemplated_obj = untemplate(template_obj) + self.assertFalse(ITemplate.providedBy(untemplated_obj)) + self.assertFalse(untemplated_obj in site.template_list) + class TestContentAccess(unittest.TestCase): From cd62655148a14ba1631ec9537474a3ab4cd79da7 Mon Sep 17 00:00:00 2001 From: David Henne Date: Thu, 21 Oct 2021 13:23:09 -0500 Subject: [PATCH 2/2] move content from template repository when 'untemplated' --- castle/cms/tasks/template.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/castle/cms/tasks/template.py b/castle/cms/tasks/template.py index fed36e513..07792361b 100644 --- a/castle/cms/tasks/template.py +++ b/castle/cms/tasks/template.py @@ -28,6 +28,8 @@ def untemplate(obj): if ITemplate.providedBy(obj): noLongerProvides(obj, ITemplate) site = getSite() + if 'template-repository' in obj.getPhysicalPath(): + obj = api.content.move(source=obj, target=site) if obj in site.template_list: site.template_list.remove(obj) return obj