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..07792361b 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,14 @@ 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 '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 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):