Author: jmorliaguet Date: Sat Jun 17 11:46:37 2006 New Revision: 3430 Modified: cpsskins/branches/paris-sprint-2006/browser/tree/slot.py cpsskins/branches/paris-sprint-2006/configure.zcml cpsskins/branches/paris-sprint-2006/controllers/portlet.py cpsskins/branches/paris-sprint-2006/doc/portlets.txt cpsskins/branches/paris-sprint-2006/elements/format.py cpsskins/branches/paris-sprint-2006/elements/interfaces.py cpsskins/branches/paris-sprint-2006/elements/presentation.py cpsskins/branches/paris-sprint-2006/elements/slot.py cpsskins/branches/paris-sprint-2006/setup/io/README.txt
Log: - updated doc tests for when a perspective is assigned to a slot - API updates / cleanup Modified: cpsskins/branches/paris-sprint-2006/browser/tree/slot.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/browser/tree/slot.py (original) +++ cpsskins/branches/paris-sprint-2006/browser/tree/slot.py Sat Jun 17 11:46:37 2006 @@ -49,9 +49,9 @@ relations = getRelationStorage(context) # The slot can override the perspective from which portlets are looked - # up. If the specified perspective is '*' then we ignore it. + # up unless the assigned perspective is '.' slot_perspective = context.perspective - if slot_perspective != u'*': + if slot_perspective != u'.': perspective = slot_perspective if perspective is None: @@ -67,7 +67,7 @@ index = order.index return cmp(index(a.identifier), index(b.identifier)) - portlets.sort(cmp_by_order) + portlets.sort(cmp_by_order) return portlets class SlotAdding(Adding): @@ -83,8 +83,12 @@ if not IPortlet.providedBy(content): raise TypeError("Only portlet can be added into slots") - perspective = getMultiAdapter(objects=(container, request), - interface=INegotiation, name='negotiation').getPerspective() + slot_perspective = container.perspective + if slot_perspective != u'*': + perspective = slot_perspective + else: + perspective = getMultiAdapter((container, request), INegotiation, + name='negotiation').getPerspective() # a slot is not a container, it is a collection of references to # portlets that are physically stored in a portlet folder. Modified: cpsskins/branches/paris-sprint-2006/configure.zcml ============================================================================== --- cpsskins/branches/paris-sprint-2006/configure.zcml (original) +++ cpsskins/branches/paris-sprint-2006/configure.zcml Sat Jun 17 11:46:37 2006 @@ -79,8 +79,6 @@ <!-- Package includes --> - <include package=".perspectives" /> - <include package=".controllers" /> <include package=".elements" /> Modified: cpsskins/branches/paris-sprint-2006/controllers/portlet.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/controllers/portlet.py (original) +++ cpsskins/branches/paris-sprint-2006/controllers/portlet.py Sat Jun 17 11:46:37 2006 @@ -41,7 +41,7 @@ element = self.element parent = getParent(element) - # only portlets located in cells have their own display + # only portlets located in cells have their own presentation if ICell.providedBy(parent): IPresentable(self.element).addPresentation() @@ -49,5 +49,5 @@ """What to do when the element has been removed. """ element = self.element - getThemeManager(element).removeFormats(element) + IPresentable(self.element).removePresentation() Modified: cpsskins/branches/paris-sprint-2006/doc/portlets.txt ============================================================================== --- cpsskins/branches/paris-sprint-2006/doc/portlets.txt (original) +++ cpsskins/branches/paris-sprint-2006/doc/portlets.txt Sat Jun 17 11:46:37 2006 @@ -303,6 +303,9 @@ Local portlets are located in slots. They can be made visible from a given perspective. +Here is a low-level description of how slots, portlets, and perspectives set in +relation. For the high-level API see the 'PORTLET MANIPULATION' section. + Let us create a portlet: >>> from cpsskins.elements.portlet import TestPortlet as Portlet @@ -384,12 +387,6 @@ Portlets can be associated to a slot from a given perspective. -We create a perspective: - - >>> from cpsskins.perspectives import Perspective - >>> perspective = Perspective('Some perspective') - >>> perspective.identifier = 3 - Let us create a relation to connect the slots, the portlet and the perspective: >>> from cpsskins.ontology import hasPortletFromPerspective @@ -399,7 +396,7 @@ ... predicate=hasPortletFromPerspective, ... first=slot, ... second=portlet, - ... third=perspective) + ... third=u'some perspective') and add it to the relation storage: @@ -410,20 +407,15 @@ >>> relations.getSeconds( ... predicate=hasPortletFromPerspective, ... first=slot, - ... third=perspective - ... ) + ... third=u'some perspective') [Portlet('Some portlet')] The portlet will not be visible from another perspective: - >>> other_perspective = Perspective('Some other perspective') - >>> other_perspective.identifier = 4 - >>> relations.getSeconds( ... predicate=hasPortletFromPerspective, ... first=slot, - ... third=other_perspective - ... ) + ... third=u'some other perspective') [] @@ -556,3 +548,52 @@ >>> traversing.getChildNodes() [Portlet('0'), Portlet('3'), Portlet('2')] + +Perspectives +------------ + +Slots can specify a perspective from which portlets will be added and looked +up: + + >>> slot_C = Slot(name=u'C') + + >>> adding_C = getMultiAdapter((slot_C, request), INodeAdding) + >>> traversing_C = getMultiAdapter((slot_C, request), INodeTraversing) + + >>> slot_C.perspective = u'some perspective' + >>> portlet5 = Portlet(u'5') + >>> added = adding_C.add(portlet5) + + >>> traversing_C.getChildNodes() + [Portlet('5')] + + >>> slot_C.perspective = u'some other perspective' + >>> portlet6 = Portlet(u'6') + >>> added = adding_C.add(portlet6) + + >>> traversing_C.getChildNodes() + [Portlet('6')] + +if the slot's assigned perspective is called '.' then the perspective passed to +getChildNodes() will be used instead to look up portlets. + + >>> slot_C.perspective = u'.' + + >>> traversing_C.getChildNodes(u'some perspective') + [Portlet('5')] + + >>> traversing_C.getChildNodes(u'some other perspective') + [Portlet('6')] + +if the slot's assigned perspective is None then perspectives are ignored and +portlets are added and looked from no specific perspective: + + >>> slot_C.perspective = None + >>> portlet7 = Portlet(u'7') + >>> added = adding_C.add(portlet7) + + >>> traversing_C.getChildNodes() + [Portlet('7')] + + + Modified: cpsskins/branches/paris-sprint-2006/elements/format.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/elements/format.py (original) +++ cpsskins/branches/paris-sprint-2006/elements/format.py Sat Jun 17 11:46:37 2006 @@ -114,6 +114,13 @@ formats.append(format) return formats + def removeFormats(self): + context = self.context + relations = getRelationStorage(context) + format_relations = relations.search(first=context, predicate=hasFormat) + relations.remove(format_relations) + # TODO clean up orphans + def getFormat(self, name=u''): res = self.getFormats(name) if res: @@ -121,8 +128,6 @@ return None def getFormatNames(self): - """Return the list of format names in alphabetical order. - """ names = [IType(f).resourcename for f in self.getFormats()] names.sort() return names @@ -134,11 +139,6 @@ return self.setFormat(format) def setFormat(self, format=None): - """Assign a format to an element - - The formerly associated format -- if it exists -- is replaced. - - """ context = self.context relations = getRelationStorage(context) @@ -157,8 +157,6 @@ relations.add(relation) def cloneFormat(self, format): - """Clone the format - """ new_format = cloneObject(format) return self.storeFormat(new_format) Modified: cpsskins/branches/paris-sprint-2006/elements/interfaces.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/elements/interfaces.py (original) +++ cpsskins/branches/paris-sprint-2006/elements/interfaces.py Sat Jun 17 11:46:37 2006 @@ -56,37 +56,58 @@ class IFormattable(Interface): def getFormats(name, resolve): - """ """ + """Get the formats of an element + + - 'name' is the format type name ('layout', 'style', ...) + + - if resolve is True, presets are dereferenced and resources are + returned. + + """ + + def removeFormats(): + """Remove all formats of an element.""" def getFormatNames(): - """ """ + """Return the list of format names in alphabetical order.""" def getFormat(name): - """ """ + """Get the format of an element by name.""" def addFormat(name): - """Add a format to a formattable element.""" + """Create and assign a format to an element.""" def setFormat(format): - """ """ + """Assign an existing format to an element + + The formerly associated format, if it exists, is replaced. + """ def cloneFormat(format): - """ """ + """Clone a format and store it, the cloned object is returned.""" def storeFormat(format): """Add a format to the format storage.""" class IPresentable(Interface): - """Presentable elements can be formatted.""" + """Presentable elements can have a presentation (i.e. a collection of + formats). - def addPresentation(perspective): - """ """ + """ + def this(): + """Return the adapted element. Used in ZPT""" - def clonePresentation(perspective): - """ """ + def addPresentation(perspective): + """Add a presentation to an element""" def removePresentation(perspective): - """ """ + """Remove the presentation of an element""" + + def customizeFormat(name, perspective): + """Customize the format of an element in a given perspective""" + + def decustomizeFormat(name, perspective): + """Decustomize the format of an element in a given perspective""" # The actual elements Modified: cpsskins/branches/paris-sprint-2006/elements/presentation.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/elements/presentation.py (original) +++ cpsskins/branches/paris-sprint-2006/elements/presentation.py Sat Jun 17 11:46:37 2006 @@ -44,9 +44,6 @@ return self def addPresentation(self, perspective=None): - """Add a presentation to an element - - """ context = self.context formattable = IFormattable(context) @@ -60,27 +57,16 @@ for name, types in factory_info.formats.items(): formattable.addFormat(name=name, types=types) - def clonePresentation(self, perspective=None): - """Clone the default presentation of an element. - - This is similar to addPresentation() except that the formats of the - cloned presentation are used in the new presentation. - + def removePresentation(self, perspective=None): + """Remove a presentation associated to an element. """ - if perspective is None: - raise ValueError("Must specify a destination perspective") - context = self.context - relations = getRelationStorage(context) - formattable = IFormattable(context) - for r in relations.search(first=context, predicate=hasFormat): - rel = relations.get(r) - format = rel.second - formattable.setFormat(format) + formattable.removeFormats() - def removePresentation(self, perspective=None): - """Remove a presentation associated to an element. - """ - # XXX + def customizeFormat(self, name=u'', perspective=None): + raise NotImplementedError + + def decustomizeFormat(self, name=u'', perspective=None): + raise NotImplementedError Modified: cpsskins/branches/paris-sprint-2006/elements/slot.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/elements/slot.py (original) +++ cpsskins/branches/paris-sprint-2006/elements/slot.py Sat Jun 17 11:46:37 2006 @@ -29,9 +29,9 @@ class Slot(InnerNode): """Slot - >>> slot = Slot('Some slot') + >>> slot = Slot(u'slotA', u'Some slot') >>> slot - Slot('Some slot', '') + Slot('slotA', 'Some slot') >>> from cpsskins.elements.interfaces import ILeaf >>> ILeaf.providedBy(slot) @@ -40,18 +40,18 @@ """ implements(ISlot) - def __init__(self, title=u'', description=u'', name=u'', perspective=u''): + def __init__(self, name=u'', title=u'', description=u'', perspective=None): super(Slot, self).__init__() + self.name = name self.title = title self.description = description - self.name = name self.perspective = perspective def __str__(self): return self.name def __repr__(self): - return "Slot('%s', '%s')" % (self.title, str(self)) + return "Slot('%s', '%s')" % (str(self), self.title) def __getitem__(self, name): """Get a portlet by name""" Modified: cpsskins/branches/paris-sprint-2006/setup/io/README.txt ============================================================================== --- cpsskins/branches/paris-sprint-2006/setup/io/README.txt (original) +++ cpsskins/branches/paris-sprint-2006/setup/io/README.txt Sat Jun 17 11:46:37 2006 @@ -177,8 +177,9 @@ >>> slot = Slot(title=u'Some slot', name=u'slot1') >>> pageblock[u'cell1'][u'slot'] = slot - >>> print toXML(pageblock, u'elements', (u'title', u'description'), - ... (u'name',)) + >>> print toXML(pageblock, u'elements', + ... attributes=(u'title', u'description', u'perspective'), + ... ignored=(u'name',)) <?xml version="1.0" encoding="utf-8"?> <elements> <pageblock id="..." title="Some page block"> @@ -190,7 +191,6 @@ </elements> <BLANKLINE> - Export of container elements ---------------------------- @@ -198,7 +198,8 @@ >>> root = getRootFolder() >>> theme = addThemeSkeleton(tmutil) - >>> print toXML(theme, u'themes', (u'title', ), (u'slot',)) + >>> print toXML(theme, u'themes', attributes=(u'title', ), + ... ignored=(u'slot',)) <?xml version="1.0" encoding="utf-8"?> <themes> <theme id="..." title="A theme"> @@ -216,7 +217,7 @@ >>> portlet = Actions(title=u'Action portlet', category=u'zmi_views') - >>> print toXML(portlet, u'portlets', (u'title', )) + >>> print toXML(portlet, u'portlets', attributes=(u'title', )) <?xml version="1.0" encoding="utf-8"?> <portlets> <portlet id="..." title="Action portlet" type="standard.actions"> -- http://lists.nuxeo.com/mailman/listinfo/z3lab-checkins