[Checkins] SVN: CompositePage/trunk/ - Fixed test failures caused by 7 years of changes to Zope. This mostly
Shane Hathaway
shane at hathawaymix.org
Mon Apr 11 19:46:04 EDT 2011
Log message for revision 121402:
- Fixed test failures caused by 7 years of changes to Zope. This mostly
involved simple modernization:
- Use zope.interface, zope.tales, and zope.pagetemplate rather than
their predecessors.
- Use absolute imports.
- Use Unicode where possible.
- Let's stop swallowing errors that occur when rendering the template
to get the list of slots. Error messages are friendlier than silent
breakage.
Changed:
U CompositePage/trunk/CHANGES.txt
U CompositePage/trunk/composite.py
U CompositePage/trunk/designuis.py
U CompositePage/trunk/element.py
U CompositePage/trunk/interfaces.py
U CompositePage/trunk/perm_names.py
U CompositePage/trunk/slot.py
U CompositePage/trunk/slotclass.py
U CompositePage/trunk/slotexpr.py
U CompositePage/trunk/tests/test_composite.py
U CompositePage/trunk/tests/test_tool.py
U CompositePage/trunk/tool.py
U CompositePage/trunk/utils.py
-=-
Modified: CompositePage/trunk/CHANGES.txt
===================================================================
--- CompositePage/trunk/CHANGES.txt 2011-04-11 21:45:02 UTC (rev 121401)
+++ CompositePage/trunk/CHANGES.txt 2011-04-11 23:46:03 UTC (rev 121402)
@@ -1,9 +1,27 @@
-After Version 0.2
- - allow to subclass rendering of target
- change order of targets rendering
+Next Release
+------------
-Version 0.2
+- Fixed test failures caused by 7 years of changes to Zope. This mostly
+ involved simple modernization:
+ - Use zope.interface, zope.tales, and zope.pagetemplate rather than
+ their predecessors.
+
+ - Use absolute imports.
+
+ - Use Unicode where possible.
+
+- Let's stop swallowing errors that occur when rendering the template
+ to get the list of slots. Error messages are friendlier than silent
+ breakage.
+
+- Slots now show the add element interface only at the top and bottom
+ of the slot, not between elements. (Hmm, should this be configurable?)
+
+
+0.2 (2004-06-16)
+----------------
+
- Changed the UI to use images for elements and targets.
- Added inline views. You can now select templates to render objects.
Modified: CompositePage/trunk/composite.py
===================================================================
--- CompositePage/trunk/composite.py 2011-04-11 21:45:02 UTC (rev 121401)
+++ CompositePage/trunk/composite.py 2011-04-11 23:46:03 UTC (rev 121402)
@@ -20,22 +20,32 @@
import Globals
import Acquisition
-from Acquisition import aq_base, aq_inner, aq_parent, aq_get
+from Acquisition import aq_base
+from Acquisition import aq_inner
+from Acquisition import aq_parent
+from Acquisition import aq_get
from OFS.Folder import Folder
from OFS.SimpleItem import SimpleItem
-from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
from AccessControl import ClassSecurityInfo
from AccessControl.ZopeGuards import guarded_getattr
+from zope.interface import implements
+from zope.pagetemplate.pagetemplatefile import PageTemplateFile
-from interfaces import IComposite, ISlot, ISlotGenerator, CompositeError
-from slot import Slot, getIconURL, formatException
-import perm_names
+from Products.CompositePage.interfaces import IComposite
+from Products.CompositePage.interfaces import ISlot
+from Products.CompositePage.interfaces import ISlotGenerator
+from Products.CompositePage.interfaces import CompositeError
+from Products.CompositePage.slot import Slot
+from Products.CompositePage.slot import getIconURL
+from Products.CompositePage.slot import formatException
+from Products.CompositePage.perm_names import view_perm
+from Products.CompositePage.perm_names import change_composites_perm
_www = os.path.join(os.path.dirname(__file__), "www")
-class SlotGenerator (Acquisition.Explicit):
+class SlotGenerator(Acquisition.Explicit):
"""Automatically makes slots available to the template.
Note: instances of this class are shared across threads.
@@ -49,12 +59,13 @@
template. Assigns attributes (class_name and title) to the
slot at the same time.
"""
+ name = str(name)
composite = aq_parent(aq_inner(self))
composite._usingSlot(name, class_name, title)
slots = composite.filled_slots
- try:
+ if slots.hasObject(name):
return slots[name]
- except (KeyError, AttributeError):
+ else:
# Generate a new slot.
s = self._slot_class(name)
if composite.isEditing():
@@ -73,8 +84,8 @@
elements. This base class provides the nuts and bolts of a
composite editing interface.
"""
+ implements(IComposite)
meta_type = "Composite"
- __implements__ = IComposite
security = ClassSecurityInfo()
@@ -87,7 +98,6 @@
template_path = "template"
_v_editing = 0
_v_rendering = 0
- _v_generating = 0
_v_slot_specs = None # [{'name', 'class', 'title'}]
security.declarePublic("slots")
@@ -98,19 +108,19 @@
"label": "Path to template"},
)
- security.declareProtected(perm_names.view, "hasTemplate")
+ security.declareProtected(view_perm, "hasTemplate")
def hasTemplate(self):
if self.template_path:
return 1
return 0
- security.declareProtected(perm_names.view, "getTemplate")
+ security.declareProtected(view_perm, "getTemplate")
def getTemplate(self):
if not self.template_path:
raise CompositeError("No template set")
return self.restrictedTraverse(str(self.template_path))
- security.declareProtected(perm_names.change_composites, "generateSlots")
+ security.declareProtected(change_composites_perm, "generateSlots")
def generateSlots(self):
"""Creates the slots defined by the template.
"""
@@ -120,7 +130,7 @@
finally:
self._v_editing = 0
- security.declareProtected(perm_names.view, "__call__")
+ security.declareProtected(view_perm, "__call__")
def __call__(self):
"""Renders the composite.
"""
@@ -137,7 +147,7 @@
index_html = None
- security.declareProtected(perm_names.change_composites, "design")
+ security.declareProtected(change_composites_perm, "design")
def design(self, ui=None):
"""Renders the composite with editing features.
"""
@@ -152,14 +162,13 @@
finally:
self._v_editing = 0
- security.declareProtected(perm_names.change_composites,
- "manage_designForm")
+ security.declareProtected(change_composites_perm, "manage_designForm")
def manage_designForm(self):
"""Renders the composite with editing and ZMI features.
"""
return self.design("zmi")
- security.declareProtected(perm_names.change_composites, "getUI")
+ security.declareProtected(change_composites_perm, "getUI")
def getUI(self, ui=None):
"""Returns a UI object.
"""
@@ -186,7 +195,7 @@
'title': title,
})
- security.declareProtected(perm_names.change_composites, "getSlotSpecs")
+ security.declareProtected(change_composites_perm, "getSlotSpecs")
def getSlotSpecs(self):
"""Returns the slot specs within the template.
@@ -196,13 +205,13 @@
self._v_slot_specs = []
try:
self()
+ slots = self._v_slot_specs
+ return slots
finally:
self._v_editing = 0
- slots = self._v_slot_specs
self._v_slot_specs = None
- return slots
- security.declareProtected(perm_names.change_composites, "getSlotClassName")
+ security.declareProtected(change_composites_perm, "getSlotClassName")
def getSlotClassName(self, slot_name):
"""Returns the class_name of a slot.
@@ -215,7 +224,7 @@
return spec['class_name']
raise KeyError(slot_name)
- security.declareProtected(perm_names.change_composites, "getManifest")
+ security.declareProtected(change_composites_perm, "getManifest")
def getManifest(self):
"""Returns a manifest of slot contents.
@@ -228,9 +237,9 @@
if hasattr(self, 'portal_url'):
icon_base_url = self.portal_url()
else:
- REQUEST = getattr(self, 'REQUEST', None)
- if REQUEST is not None:
- icon_base_url = self.REQUEST['BASEPATH1']
+ request = getattr(self, 'REQUEST', None)
+ if request is not None:
+ icon_base_url = request['BASEPATH1']
else:
icon_base_url = ''
for spec in specs:
@@ -287,7 +296,7 @@
contents.append(slot_info)
return contents
- security.declareProtected(perm_names.view, "isEditing")
+ security.declareProtected(view_perm, "isEditing")
def isEditing(self):
"""Returns true if currently rendering in design mode.
"""
@@ -334,7 +343,7 @@
title = 'Error'
-addCompositeForm = PageTemplateFile("addCompositeForm", _www)
+addCompositeForm = PageTemplateFile("addCompositeForm.zpt", _www)
def manage_addComposite(dispatcher, id, title="", create_sample="",
REQUEST=None):
@@ -342,7 +351,7 @@
"""
ob = Composite()
ob._setId(id)
- ob.title = string(title)
+ ob.title = unicode(title)
dispatcher._setObject(ob.getId(), ob)
if create_sample:
ob = dispatcher.this()._getOb(ob.getId())
@@ -356,13 +365,3 @@
ob._setObject(pt.getId(), pt)
if REQUEST is not None:
return dispatcher.manage_main(dispatcher, REQUEST)
-
-
-def string(s):
- """Ensures an object is either a string or a unicode.
- """
- try:
- return str(s)
- except UnicodeEncodeError:
- return unicode(s)
-
Modified: CompositePage/trunk/designuis.py
===================================================================
--- CompositePage/trunk/designuis.py 2011-04-11 21:45:02 UTC (rev 121401)
+++ CompositePage/trunk/designuis.py 2011-04-11 23:46:03 UTC (rev 121402)
@@ -22,12 +22,13 @@
import Globals
from Acquisition import aq_base, aq_inner, aq_parent
from OFS.SimpleItem import SimpleItem
-from Products.PageTemplates.PageTemplateFile import PageTemplateFile
+from zope.pagetemplate.pagetemplatefile import PageTemplateFile
from AccessControl import ClassSecurityInfo
from AccessControl.ZopeGuards import guarded_getattr
-from rawfile import RawFile, InterpolatedFile
-from interfaces import ICompositeElement
+from Products.CompositePage.rawfile import RawFile
+from Products.CompositePage.rawfile import InterpolatedFile
+from Products.CompositePage.interfaces import ICompositeElement
_common = os.path.join(os.path.dirname(__file__), "common")
@@ -58,7 +59,7 @@
</html>
'''
-class CommonUI (SimpleItem):
+class CommonUI(SimpleItem):
"""Basic page design UI.
Adds editing features to a rendered composite.
@@ -148,7 +149,7 @@
"""
root = self.getPhysicalRoot()
obj = root.restrictedTraverse(path)
- if ICompositeElement.isImplementedBy(obj):
+ if ICompositeElement.providedBy(obj):
obj = obj.dereference()
RESPONSE.redirect("%s/%s" % (
obj.absolute_url(), self.workspace_view_name))
@@ -160,7 +161,7 @@
"""
root = self.getPhysicalRoot()
obj = root.restrictedTraverse(path)
- if ICompositeElement.isImplementedBy(obj):
+ if ICompositeElement.providedBy(obj):
obj = obj.dereference()
RESPONSE.redirect(obj.absolute_url())
@@ -175,11 +176,7 @@
parts = str(path).split('/')
for name in parts:
obj = obj.restrictedTraverse(name)
- try:
- is_comp = isinstance(obj, Composite)
- except TypeError:
- is_comp = 0 # Python 2.1 bug
- if is_comp:
+ if IComposite.providedBy(obj):
gen = guarded_getattr(obj, "generateSlots")
gen()
RESPONSE.redirect("%s/%s" % (
@@ -198,7 +195,7 @@
for path in str(paths).split(':'):
ob = root.unrestrictedTraverse(path)
obs.append(ob)
- if not ICompositeElement.isImplementedBy(ob):
+ if not ICompositeElement.providedBy(ob):
raise ValueError("Not a composite element: %s" % path)
m = guarded_getattr(ob, "queryInlineTemplate")
template = m()
@@ -236,7 +233,7 @@
raise KeyError("Template %s is not among the choices" % template)
tool = aq_parent(aq_inner(self))
for ob in info["obs"]:
- assert ICompositeElement.isImplementedBy(ob)
+ assert ICompositeElement.providedBy(ob)
m = guarded_getattr(ob, "setInlineTemplate")
m(template)
if REQUEST is not None:
Modified: CompositePage/trunk/element.py
===================================================================
--- CompositePage/trunk/element.py 2011-04-11 21:45:02 UTC (rev 121401)
+++ CompositePage/trunk/element.py 2011-04-11 23:46:03 UTC (rev 121402)
@@ -23,19 +23,20 @@
from OFS.SimpleItem import SimpleItem
from OFS.PropertyManager import PropertyManager
from DocumentTemplate.DT_Util import safe_callable
-from Products.PageTemplates.PageTemplateFile import PageTemplateFile
+from zope.pagetemplate.pagetemplatefile import PageTemplateFile
+from zope.interface import implements
-from interfaces import ICompositeElement
+from Products.CompositePage.interfaces import ICompositeElement
_www = os.path.join(os.path.dirname(__file__), "www")
-class CompositeElement (SimpleItem, PropertyManager):
+class CompositeElement(SimpleItem, PropertyManager):
"""A simple path-based reference to an object and a template.
You can render it and choose which template to apply for rendering.
"""
- __implements__ = ICompositeElement
+ implements(ICompositeElement)
meta_type = "Composite Element"
security = ClassSecurityInfo()
manage_options = PropertyManager.manage_options + SimpleItem.manage_options
@@ -72,7 +73,7 @@
# Special template name "call" means to call the object.
if safe_callable(obj):
return obj()
- return str(obj)
+ return unicode(obj)
def queryInlineTemplate(self, slot_class_name=None):
"""Returns the name of the inline template this object uses.
@@ -100,7 +101,7 @@
Globals.InitializeClass(CompositeElement)
-addElementForm = PageTemplateFile("addElementForm", _www)
+addElementForm = PageTemplateFile("addElementForm.zpt", _www)
def manage_addElement(dispatcher, id, path, template_name=None, REQUEST=None):
"""Adds an element to a slot.
Modified: CompositePage/trunk/interfaces.py
===================================================================
--- CompositePage/trunk/interfaces.py 2011-04-11 21:45:02 UTC (rev 121401)
+++ CompositePage/trunk/interfaces.py 2011-04-11 23:46:03 UTC (rev 121402)
@@ -15,9 +15,10 @@
$Id: interfaces.py,v 1.14 2004/04/15 22:13:44 shane Exp $
"""
-from Interface import Interface
-from Interface.Attribute import Attribute
+from zope.interface import Attribute
+from zope.interface import Interface
+
class CompositeError(Exception):
"""An error in constructing a composite
"""
Modified: CompositePage/trunk/perm_names.py
===================================================================
--- CompositePage/trunk/perm_names.py 2011-04-11 21:45:02 UTC (rev 121401)
+++ CompositePage/trunk/perm_names.py 2011-04-11 23:46:03 UTC (rev 121402)
@@ -16,6 +16,6 @@
$Id: perm_names.py,v 1.1 2003/10/01 18:59:31 shane Exp $
"""
-change_composites = "Change Composites"
-view = "View"
+change_composites_perm = "Change Composites"
+view_perm = "View"
Modified: CompositePage/trunk/slot.py
===================================================================
--- CompositePage/trunk/slot.py 2011-04-11 21:45:02 UTC (rev 121401)
+++ CompositePage/trunk/slot.py 2011-04-11 23:46:03 UTC (rev 121402)
@@ -21,14 +21,21 @@
from cgi import escape
import Globals
-from Acquisition import aq_base, aq_inner, aq_parent, aq_get
+from Acquisition import aq_base
+from Acquisition import aq_inner
+from Acquisition import aq_parent
+from Acquisition import aq_get
from ZODB.POSException import ConflictError
from OFS.SimpleItem import SimpleItem
-from Products.PageTemplates.PageTemplateFile import PageTemplateFile
+from zope.pagetemplate.pagetemplatefile import PageTemplateFile
from AccessControl import ClassSecurityInfo
from zLOG import LOG, ERROR
+from zope.interface import implements
-from interfaces import ICompositeElement
+from Products.CompositePage.interfaces import ICompositeElement
+from Products.CompositePage.interfaces import ISlot
+from Products.CompositePage.perm_names import view_perm
+from Products.CompositePage.perm_names import change_composites_perm
try:
@@ -38,9 +45,6 @@
# Fall back to normal folders, which happen to retain order anyway.
from OFS.Folder import Folder as OrderedFolder
-from interfaces import ISlot
-import perm_names
-
_www = os.path.join(os.path.dirname(__file__), "www")
target_tag = '''<div class="slot_target" title="Slot: %s [%d]"
@@ -63,20 +67,20 @@
class NullElement(SimpleItem):
- """Temporary slot content
+ """Empty placeholder for slot content
"""
- meta_type = "Temporary Null Page Element"
+ meta_type = "Temporary Empty Slot Content"
def __init__(self, id):
self.id = id
+
class Slot(OrderedFolder):
"""A slot in a composite.
"""
+ implements(ISlot)
meta_type = "Composite Slot"
- __implements__ = ISlot, OrderedFolder.__implements__
-
security = ClassSecurityInfo()
null_element = NullElement("null_element")
@@ -89,7 +93,7 @@
return OrderedFolder.all_meta_types(
self, interfaces=(ICompositeElement,))
- security.declareProtected(perm_names.view, "single")
+ security.declareProtected(view_perm, "single")
def single(self):
"""Renders as a single-element slot.
@@ -100,7 +104,7 @@
allow_add = (not self._objects)
return "".join(self.renderToList(allow_add))
- security.declareProtected(perm_names.view, "multiple")
+ security.declareProtected(view_perm, "multiple")
def multiple(self):
"""Renders as a list containing multiple elements.
"""
@@ -111,7 +115,9 @@
"""
return "".join(self.renderToList(1))
- security.declareProtected(perm_names.change_composites, "reorder")
+ __unicode__ = __str__
+
+ security.declareProtected(change_composites_perm, "reorder")
def reorder(self, name, new_index):
if name not in self.objectIds():
raise KeyError, name
@@ -120,7 +126,7 @@
{'id': name, 'meta_type': getattr(self, name).meta_type})
self._objects = tuple(objs)
- security.declareProtected(perm_names.change_composites, "nullify")
+ security.declareProtected(change_composites_perm, "nullify")
def nullify(self, name):
res = self[name]
objs = list(self._objects)
@@ -131,12 +137,12 @@
delattr(self, name)
return res
- security.declareProtected(perm_names.change_composites, "nullify")
+ security.declareProtected(change_composites_perm, "nullify")
def pack(self):
objs = [info for info in self._objects if info["id"] != "null_element"]
self._objects = tuple(objs)
- security.declareProtected(perm_names.view, "renderToList")
+ security.declareProtected(view_perm, "renderToList")
def renderToList(self, allow_add):
"""Renders the items to a list.
"""
@@ -149,20 +155,21 @@
myid = self.getId()
if hasattr(self, 'portal_url'):
icon_base_url = self.portal_url()
- elif hasattr(self, 'REQUEST'):
- icon_base_url = self.REQUEST['BASEPATH1']
else:
- icon_base_url = '/'
-
+ request = getattr(self, 'REQUEST', None)
+ if request is not None:
+ icon_base_url = request['BASEPATH1']
+ else:
+ icon_base_url = '/'
+
if editing and allow_add:
res.append(self._render_add_target(myid, 0, mypath))
-
+
for index in range(len(items)):
name, obj = items[index]
-
try:
- assert ICompositeElement.isImplementedBy(obj), (
+ assert ICompositeElement.providedBy(obj), (
"Not a composite element: %s" % repr(obj))
text = obj.renderInline()
except ConflictError:
@@ -199,9 +206,9 @@
def getIconURL(obj, icon_base_url):
base = aq_base(obj)
if hasattr(base, 'getIcon'):
- icon = str(obj.getIcon())
+ icon = obj.getIcon()
elif hasattr(base, 'icon'):
- icon = str(obj.icon)
+ icon = obj.icon
else:
icon = ""
if icon and '://' not in icon:
@@ -230,18 +237,22 @@
"this part of the page.")
try:
log = aq_get(context, '__error_log__', None, 1)
+ raising = getattr(log, 'raising', None)
except AttributeError:
+ raising = None
+
+ if raising is not None:
+ error_log_url = raising(exc_info)
+ return error_tag % (msg, error_log_url)
+ else:
LOG("Composite", ERROR, "Error in a page element",
error=exc_info)
return msg
- else:
- error_log_url = log.raising(exc_info)
- return error_tag % (msg, error_log_url)
finally:
del exc_info
-addSlotForm = PageTemplateFile("addSlotForm", _www)
+addSlotForm = PageTemplateFile("addSlotForm.zpt", _www)
def manage_addSlot(dispatcher, id, REQUEST=None):
"""Adds a slot to a composite.
Modified: CompositePage/trunk/slotclass.py
===================================================================
--- CompositePage/trunk/slotclass.py 2011-04-11 21:45:02 UTC (rev 121401)
+++ CompositePage/trunk/slotclass.py 2011-04-11 23:46:03 UTC (rev 121402)
@@ -21,17 +21,19 @@
from Acquisition import aq_inner, aq_parent
from OFS.SimpleItem import SimpleItem
from OFS.PropertyManager import PropertyManager
-from Products.PageTemplates.PageTemplateFile import PageTemplateFile
+from zope.pagetemplate.pagetemplatefile import PageTemplateFile
+from zope.interface import implements
-from interfaces import ISlotClass
+from Products.CompositePage.interfaces import ISlotClass
_www = os.path.join(os.path.dirname(__file__), "www")
+
class SlotClass(SimpleItem, PropertyManager):
"""Parameters and constraints for a slot.
"""
- __implements__ = ISlotClass
+ implements(ISlotClass)
meta_type = "Composite Slot Class"
find_script = ""
@@ -51,7 +53,7 @@
return s(slot)
-addSlotClassForm = PageTemplateFile("addSlotClassForm", _www)
+addSlotClassForm = PageTemplateFile("addSlotClassForm.zpt", _www)
def manage_addSlotClass(dispatcher, id, REQUEST=None):
"""Adds a slot class to a composite tool.
Modified: CompositePage/trunk/slotexpr.py
===================================================================
--- CompositePage/trunk/slotexpr.py 2011-04-11 21:45:02 UTC (rev 121401)
+++ CompositePage/trunk/slotexpr.py 2011-04-11 23:46:03 UTC (rev 121402)
@@ -17,18 +17,21 @@
$Id: slotexpr.py,v 1.5 2004/05/03 16:02:40 sidnei Exp $
"""
+import logging
import re
-from Products.PageTemplates.TALES import CompilerError, Default
+from zope.tales.tales import CompilerError
-from interfaces import IComposite
+from Products.CompositePage.interfaces import IComposite
name_re = re.compile("\s*([a-zA-Z][a-zA-Z0-9_]*)")
class_name_re = re.compile("\s*[(]([a-zA-Z][a-zA-Z0-9_]*)[)]")
title_re = re.compile("\s*[']([^']+)[']")
+log = logging.getLogger(__name__)
-class SlotExpr:
+
+class SlotExpr(object):
"""Slot expression type.
Provides a concise syntax for specifying composite slots in
@@ -38,7 +41,7 @@
"""
def __init__(self, name, expr, engine):
- self._s = s = expr
+ self._s = s = expr.strip()
mo = name_re.match(s)
if mo is None:
raise CompilerError('Invalid slot expression "%s"' % s)
@@ -60,29 +63,43 @@
# Can't interpret some of the expression
raise CompilerError(
'Slot expression syntax error near %s' % repr(s))
-
+
def __call__(self, econtext):
context = econtext.contexts.get('options')
if context is None:
raise RuntimeError("Could not find options")
composite = context.get('composite')
- if IComposite.isImplementedBy(composite):
+ if IComposite.providedBy(composite):
slot = composite.slots.get(
self._name, self._class_name, self._title)
# Render the slot
- return "".join(slot.multiple())
+ return unicode(slot)
else:
# Show the default content
- return Default
+ return econtext.getDefault()
def __repr__(self):
- return 'slot:%s' % self._s
+ return '<SlotExpr %s>' % repr(self._s)
def registerSlotExprType():
# Register the 'slot:' expression type.
- from Products.PageTemplates.Expressions import getEngine
- # Avoid registering twice.
- engine = getEngine()
- if not engine.getTypes().has_key('slot'):
- engine.registerType('slot', SlotExpr)
+
+ # Register with Products.PageTemplates.
+ try:
+ from Products.PageTemplates.Expressions import getEngine
+ except ImportError:
+ log.exception("Unable to register the slot expression type")
+ else:
+ engine = getEngine()
+ if not engine.getTypes().has_key('slot'):
+ engine.registerType('slot', SlotExpr)
+
+ # Register with zope.tales.
+ try:
+ from zope.tales.engine import Engine
+ except ImportError:
+ log.exception("Unable to register the slot expression type")
+ else:
+ if not Engine.getTypes().has_key('slot'):
+ Engine.registerType('slot', SlotExpr)
Modified: CompositePage/trunk/tests/test_composite.py
===================================================================
--- CompositePage/trunk/tests/test_composite.py 2011-04-11 21:45:02 UTC (rev 121401)
+++ CompositePage/trunk/tests/test_composite.py 2011-04-11 23:46:03 UTC (rev 121402)
@@ -17,27 +17,15 @@
"""
import unittest
+from zope.testing.cleanup import cleanUp
-import ZODB
-from OFS.Folder import Folder
-from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
-from TAL.TALDefs import TALError
-from Products.CompositePage.slot import Slot
-from Products.CompositePage.composite import Composite
-from Products.CompositePage.element import CompositeElement
-from AccessControl.SecurityManagement import noSecurityManager
-from AccessControl.SecurityManager import setSecurityPolicy
-import AccessControl.User # Get the "nobody" user defined
-from Products.CompositePage.tests.test_tool import PermissiveSecurityPolicy
-
-
template_text = '''\
<html>
<body>
<div tal:replace="structure slot: slot_a (top) 'Top News Stories'">slot_a</div>
<span tal:replace="structure slot: slot_b 'Other News'">slot_b</span>
-<div tal:replace="structure here/slots/slot_c">slot_c</div>
+<div tal:replace="structure context/slots/slot_c">slot_c</div>
</body>
</html>
'''
@@ -46,37 +34,62 @@
class CompositeTests(unittest.TestCase):
def setUp(self):
+ cleanUp()
+ from AccessControl.SecurityManagement import noSecurityManager
+ from AccessControl.SecurityManager import setSecurityPolicy
+ from Products.CompositePage.tests.test_tool import PermissiveSecurityPolicy
+ self.old_policy = setSecurityPolicy(PermissiveSecurityPolicy())
+ noSecurityManager()
+
+ def tearDown(self):
+ from AccessControl.SecurityManagement import noSecurityManager
+ from AccessControl.SecurityManager import setSecurityPolicy
+ setSecurityPolicy(self.old_policy)
+ noSecurityManager()
+ cleanUp()
+
+ def _make_composite(self):
+ from OFS.Folder import Folder
f = Folder()
f.getPhysicalPath = lambda: ()
f.getPhysicalRoot = lambda f=f: f
+ from ZPublisher.HTTPRequest import HTTPRequest
+ f.REQUEST = HTTPRequest('', dict(HTTP_HOST='localhost:8080'), {})
+ from Products.CompositePage.composite import Composite
f.composite = Composite()
f.composite._setId("composite")
+ from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
t = ZopePageTemplate(
id="template", text=template_text, content_type="text/html")
+ f.composite.template = t
+ from Products.CompositePage.slot import Slot
+ f.composite.filled_slots.slot_a = slot_a = Slot("slot_a")
+ t = f.composite.template
if t.pt_errors():
raise SyntaxError(t.pt_errors())
- f.composite.template = t
- f.composite.filled_slots.slot_a = slot_a = Slot("slot_a")
a1 = ZopePageTemplate(id="a1", text="<b>Slot A</b>")
f._setObject(a1.id, a1)
+ from Products.CompositePage.element import CompositeElement
e1 = CompositeElement('e1', f.a1)
slot_a._setObject(e1.id, e1)
- self.composite = f.composite
- self.old_policy = setSecurityPolicy(PermissiveSecurityPolicy())
- noSecurityManager()
+ return f.composite
- def tearDown(self):
- setSecurityPolicy(self.old_policy)
- noSecurityManager()
+ def _registerTraversable(self):
+ from zope.component import getGlobalSiteManager
+ from zope.interface import Interface
+ from zope.traversing.interfaces import ITraversable
+ from zope.traversing.adapters import DefaultTraversable
+ getGlobalSiteManager().registerAdapter(
+ DefaultTraversable, [Interface], ITraversable)
def assertTextEqual(self, a, b):
a = a.strip().replace("\n", "")
b = b.strip().replace("\n", "")
self.assertEqual(a, b)
-
def testRender(self):
- rendered = self.composite()
+ self._registerTraversable()
+ rendered = self._make_composite()()
expected = ('<html><body>'
'<div class="slot_header"></div><div><b>Slot A</b></div>'
'<div class="slot_header"></div>'
@@ -85,7 +98,8 @@
self.assertTextEqual(rendered, expected)
def testGetManifest(self):
- manifest = self.composite.getManifest()
+ self._registerTraversable()
+ manifest = self._make_composite().getManifest()
self.assertEqual(len(manifest), 3)
self.assertEqual(manifest[0]['name'], 'slot_a')
self.assertEqual(manifest[0]['title'], 'Top News Stories')
@@ -110,25 +124,28 @@
def testSlotExprCompilerError(self):
# Bad slot expressions should produce a reasonable error.
+ from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
+ from zope.tal.taldefs import TALError
text = '<div tal:content="structure slot: a b" />'
try:
t = ZopePageTemplate(
id="template", text=text, content_type="text/html")
except TALError, e:
- msg = str(e)
+ msg = unicode(e)
else:
msg = ' '.join(t.pt_errors())
if not msg:
raise AssertionError("Expected a syntax error")
- substr = "near ' b'"
- self.assert_(msg.find(substr) >= 0)
+ self.assertTrue("syntax error" in msg)
def testGetSlotClassName(self):
- self.assertEqual(self.composite.getSlotClassName('slot_a'), 'top')
- self.assertEqual(self.composite.getSlotClassName('slot_b'), None)
- self.assertEqual(self.composite.getSlotClassName('slot_c'), None)
+ self._registerTraversable()
+ composite = self._make_composite()
+ self.assertEqual(composite.getSlotClassName('slot_a'), 'top')
+ self.assertEqual(composite.getSlotClassName('slot_b'), None)
+ self.assertEqual(composite.getSlotClassName('slot_c'), None)
self.assertRaises(
- KeyError, self.composite.getSlotClassName, 'nonexistent_slot')
+ KeyError, composite.getSlotClassName, 'nonexistent_slot')
def test_suite():
suite = unittest.TestSuite()
Modified: CompositePage/trunk/tests/test_tool.py
===================================================================
--- CompositePage/trunk/tests/test_tool.py 2011-04-11 21:45:02 UTC (rev 121401)
+++ CompositePage/trunk/tests/test_tool.py 2011-04-11 23:46:03 UTC (rev 121402)
@@ -18,17 +18,16 @@
import unittest
-import ZODB
from OFS.Folder import Folder
-from Products.CompositePage.tool import CompositeTool
-from Products.CompositePage.slot import Slot
-from Products.CompositePage.interfaces import CompositeError
-
from AccessControl.SecurityManagement import noSecurityManager
from AccessControl.SecurityManager import setSecurityPolicy
import AccessControl.User # Get the "nobody" user defined
+from Products.CompositePage.tool import CompositeTool
+from Products.CompositePage.slot import Slot
+from Products.CompositePage.interfaces import CompositeError
+
class PermissiveSecurityPolicy:
def validate(*args, **kw):
return 1
@@ -37,7 +36,6 @@
return 1
-
class ToolTests(unittest.TestCase):
def setUp(self):
Modified: CompositePage/trunk/tool.py
===================================================================
--- CompositePage/trunk/tool.py 2011-04-11 21:45:02 UTC (rev 121401)
+++ CompositePage/trunk/tool.py 2011-04-11 23:46:03 UTC (rev 121402)
@@ -24,10 +24,12 @@
from AccessControl import ClassSecurityInfo
from AccessControl.ZopeGuards import guarded_getattr
-from interfaces import ISlot, ISlotClass, ICompositeElement
-from interfaces import CompositeError
-from element import CompositeElement
-from utils import copyOf
+from Products.CompositePage.interfaces import ICompositeElement
+from Products.CompositePage.interfaces import ISlot
+from Products.CompositePage.interfaces import ISlotClass
+from Products.CompositePage.interfaces import CompositeError
+from Products.CompositePage.element import CompositeElement
+from Products.CompositePage.utils import copyOf
_uis = {}
@@ -129,10 +131,10 @@
root = self.getPhysicalRoot()
elements = []
target = root.restrictedTraverse(target_path)
- assert ISlot.isImplementedBy(target), repr(target)
+ assert ISlot.providedBy(target), repr(target)
for source in sources:
slot = root.restrictedTraverse(source[:-1])
- assert ISlot.isImplementedBy(slot), repr(slot)
+ assert ISlot.providedBy(slot), repr(slot)
element = slot.restrictedTraverse(source[-1])
elements.append(element)
if self._check_security:
@@ -155,7 +157,7 @@
# Add the elements and reorder.
for element in elements:
- if not ICompositeElement.isImplementedBy(element):
+ if not ICompositeElement.providedBy(element):
# Make a composite element wrapper.
element = CompositeElement(element.getId(), element)
@@ -189,7 +191,7 @@
try:
for source in sources:
slot = self.restrictedTraverse(source[:-1])
- assert ISlot.isImplementedBy(slot), repr(slot)
+ assert ISlot.providedBy(slot), repr(slot)
slot_id = id(aq_base(slot))
if not orig_slots.has_key(slot_id):
orig_slots[slot_id] = slot
Modified: CompositePage/trunk/utils.py
===================================================================
--- CompositePage/trunk/utils.py 2011-04-11 21:45:02 UTC (rev 121401)
+++ CompositePage/trunk/utils.py 2011-04-11 23:46:03 UTC (rev 121402)
@@ -20,7 +20,6 @@
from cStringIO import StringIO
from cPickle import Pickler, Unpickler
-from types import StringType
def copyOf(source):
@@ -40,7 +39,7 @@
if hasattr(ob, '__bases__'):
m = getattr(ob, '__module__', None)
if (m is not None
- and isinstance(m, StringType)
+ and isinstance(m, basestring)
and m.startswith('*')):
n = getattr(ob, '__name__', None)
if n is not None:
More information about the checkins
mailing list