From 7ec9bbdc1552eb5fbbfa1d0d4e318d8aa46b3467 Mon Sep 17 00:00:00 2001 From: helmutm Date: Sun, 10 Feb 2008 09:56:27 +0000 Subject: [PATCH] merged Dojo 1.0 branch git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@2387 fd906abe-77d9-0310-91a1-e0d9ade77398 --- ajax/dojo/__init__.py | 4 + ajax/dojo/configure.zcml | 1 - ajax/dojo/macros.pt | 8 +- browser/README.txt | 34 +++---- browser/action.py | 117 +++++++++++++++++++++++ browser/action_macros.pt | 21 ++++ browser/base_macros.pt | 29 ++++-- browser/configurator.py | 50 ++++------ browser/configure.zcml | 10 +- browser/controller.py | 30 +++--- browser/icons/user.png | Bin 0 -> 741 bytes browser/liquid/base.css | 73 +------------- browser/liquid/configure.zcml | 2 + browser/liquid/controller.py | 17 +++- browser/liquid/presentation.css | 21 ++++ browser/liquid/zope3_tablelayout.css | 34 ++----- browser/main.pt | 3 +- browser/member.py | 111 +++++++++++++++++++++ browser/view.py | 14 ++- composer/schema/README.txt | 5 +- composer/schema/browser/schema_macros.pt | 31 ++++-- composer/schema/factory.py | 8 +- composer/schema/field.py | 75 ++++++++++++++- composer/schema/instance.py | 6 +- composer/schema/interfaces.py | 5 +- composer/schema/schema.py | 2 + organize/browser/report.py | 73 +++++++++++--- organize/browser/service.py | 8 +- pyscript/plot.py | 4 +- text/html.py | 2 +- text/ppt.py | 3 +- util/config.txt | 27 ++++++ 32 files changed, 597 insertions(+), 231 deletions(-) create mode 100644 browser/action.py create mode 100644 browser/action_macros.pt create mode 100644 browser/icons/user.png create mode 100644 browser/liquid/presentation.css create mode 100644 browser/member.py diff --git a/ajax/dojo/__init__.py b/ajax/dojo/__init__.py index 38314f3..78f52e6 100644 --- a/ajax/dojo/__init__.py +++ b/ajax/dojo/__init__.py @@ -1,3 +1,7 @@ """ $Id$ """ + +from zope.app.pagetemplate import ViewPageTemplateFile + +dojoMacroTemplate = ViewPageTemplateFile('macros.pt') diff --git a/ajax/dojo/configure.zcml b/ajax/dojo/configure.zcml index 32a8366..61bf51b 100644 --- a/ajax/dojo/configure.zcml +++ b/ajax/dojo/configure.zcml @@ -6,7 +6,6 @@ i18n_domain="zope"> - - - diff --git a/browser/README.txt b/browser/README.txt index 184056b..5b5dc74 100644 --- a/browser/README.txt +++ b/browser/README.txt @@ -1,3 +1,4 @@ +================== Browser View Tools ================== @@ -5,8 +6,9 @@ Browser View Tools >>> from zope.interface import Interface, implements >>> from zope.publisher.interfaces.browser import IBrowserRequest + The Generic View class ----------------------- +====================== GenericView is intended as the base class for application-specific views. The GenericView class itself provides only basic functionality, so you @@ -64,7 +66,7 @@ bodyTemplate attribute. The View Controller -------------------- +=================== There is a special view class that does not directly adapt to a real context (i.e. typically a content) object but to a view instead. Thus it can provide @@ -131,10 +133,11 @@ Calling a macro provided by Controller.macros[] returns the real ZPT macro: The pre-set collection of macros for a certain slot may be extended (this may be done by overriding the view's setupController() method, e.g.): - >>> controller.macros.register('css', 'node.css', resourceName='node.css', media='all') + >>> controller.macros.register('css', 'node.css', resourceName='node.css', + ... media='all', priority=110) >>> len(controller.macros['css']) 5 - >>> m5 = cssMacros[4] + >>> m5 = controller.macros['css'][4] >>> print m5.name, m5.media, m5.resourceName css all node.css @@ -158,7 +161,7 @@ We can also access slots that are not predefined: The View Configurator ---------------------- +===================== A view configurator is typically a multiadapter for a content object that provides a set of properties to be used for setting up special presentation @@ -167,9 +170,9 @@ characteristics of a page. Typical examples for such characteristics are - the skin to be used - the logo to show in the corner of the page -The default configurator uses attribute annotations for retrieving view -properties; that means that there could be a form somewhere to edit those -properties and store them in the content object's annotations. +There is a standard configurator that uses attribute annotations for +retrieving view properties; that means that there could be a form somewhere +to edit those properties and store them in the content object's annotations. >>> from zope.annotation.interfaces import IAttributeAnnotatable, IAnnotations >>> from zope.annotation.attribute import AttributeAnnotations @@ -179,8 +182,8 @@ The configurator is called automatically from the controller if there is an appropriate adapter: >>> from cybertools.browser.configurator import IViewConfigurator - >>> from cybertools.browser.configurator import ViewConfigurator - >>> component.provideAdapter(ViewConfigurator, (SomeObject, IBrowserRequest), + >>> from cybertools.browser.configurator import AnnotationViewConfigurator + >>> component.provideAdapter(AnnotationViewConfigurator, (SomeObject, IBrowserRequest), ... IViewConfigurator) >>> controller = Controller(view, request) @@ -197,18 +200,9 @@ stored in the attribute annotations. So let's set a 'skinName' attribute: >>> controller.skinName.value 'SuperSkin' -Another way of providing view configurations is using a view configurator -as a utility, this can be used for setting view properties by certain -packages. - - >>> from cybertools.browser.configurator import GlobalViewConfigurator - >>> component.provideUtility(GlobalViewConfigurator()) - - >>> gvc = component.getUtility(IViewConfigurator) - Processing form input ---------------------- +===================== GenericView also provides an update() method that may be called from templates that might receive form information. diff --git a/browser/action.py b/browser/action.py new file mode 100644 index 0000000..b1de302 --- /dev/null +++ b/browser/action.py @@ -0,0 +1,117 @@ +# +# Copyright (c) 2008 Helmut Merz helmutm@cy55.de +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +Base classes (sort of views) for action portlet items. + +$Id$ +""" + +from copy import copy +from urllib import urlencode +from zope import component +from zope.app.pagetemplate import ViewPageTemplateFile +from zope.cachedescriptors.property import Lazy + +action_macros = ViewPageTemplateFile('action_macros.pt') + + +class Action(object): + + template = action_macros + macroName = 'action' + priority = 50 + condition = True + permission = None + url = '.' + viewName = '' + targetWindow = '' + title = '' + description = '' + icon = '' + cssClass = '' + onClick = '' + innerHtmlId = '' + prerequisites = [] + + def __init__(self, view, **kw): + self.view = view + for k, v in kw.items(): + setattr(self, k, v) + + @Lazy + def macro(self): + return self.template.macros[self.macroName] + + @Lazy + def url(self): + return self.getActionUrl(self.view.url) + + def getActionUrl(self, baseUrl): + if self.viewName: + return '/'.join((baseUrl, self.viewName)) + else: + return baseUrl + + +class ActionRegistry(object): + """ Use this object (probably as a global utility) to collect all kinds + of action definitions that should be available on the system. + """ + + def __init__(self): + self.actionsByName = {} + self.actionsByCategory = {} + + def register(self, name, category='object', cls=Action, **kw): + action = cls(None, name=name, category=category, **kw) + nameItem = self.actionsByName.setdefault(name, []) + nameItem.append(action) + catItem = self.actionsByCategory.setdefault(category, []) + catItem.append(action) + + def get(self, category=None, names=[], view=None, **kw): + if view is None: + raise ValueError("The 'view' argument is missing.") + if names: + result = [] + for n in names: + result.extend(self.actionsByName.get(n, [])) + if category is not None: + result = [r for r in result if r.category == category] + elif category is not None: + result = self.actionsByCategory.get(category, []) + else: + raise ValueError("One of 'name' or 'category' arguments must be given.") + for action in sorted(result, key=lambda x: x.priority): + action = copy(action) + action.view = view + for k, v in kw.items(): + setattr(action, k, v) + for p in action.prerequisites: + method = p + if isinstance(method, str): + method = getattr(view, p, None) + if method is not None: + method() + yield action + + +# TODO: register as a global utility +actions = ActionRegistry() + diff --git a/browser/action_macros.pt b/browser/action_macros.pt new file mode 100644 index 0000000..f411c5d --- /dev/null +++ b/browser/action_macros.pt @@ -0,0 +1,21 @@ + + + +
+ icon + Action Title +
+ +
diff --git a/browser/base_macros.pt b/browser/base_macros.pt index d7403fe..c9bfd74 100644 --- a/browser/base_macros.pt +++ b/browser/base_macros.pt @@ -29,12 +29,7 @@ - - - - - - +
@@ -45,11 +40,27 @@ -
-

Navigation

+
+

+ + Navigation +

+ + + + + + + + diff --git a/browser/configurator.py b/browser/configurator.py index 8c0096a..5401438 100644 --- a/browser/configurator.py +++ b/browser/configurator.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2006 Helmut Merz helmutm@cy55.de +# Copyright (c) 2008 Helmut Merz helmutm@cy55.de # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -22,12 +22,11 @@ A view configurator provides configuration data for a view controller. $Id$ """ -from zope.app import zapi +from zope import component from zope.annotation.interfaces import IAttributeAnnotatable, IAnnotations from zope.annotation.attribute import AttributeAnnotations from zope.cachedescriptors.property import Lazy from zope.interface import Interface, Attribute, implements -from zope.component import adapts # interfaces @@ -64,15 +63,28 @@ class IMacroViewProperty(IViewProperty): #default implementations -ANNOTATION_KEY = 'cybertools.browser.configurator.ViewConfigurator' - class ViewConfigurator(object): - """ Simple/basic default adapter using attribute annotations as storage - for view properties. + """ An base class for adapters that allow the registration of view properties. """ implements(IViewConfigurator) + def __init__(self, context, request): + self.context = context + self.request = request + self.viewProperties = [] + + def getActiveViewProperties(self): + return self.viewProperties + + +ANNOTATION_KEY = 'cybertools.browser.configurator.ViewConfigurator' + +class AnnotationViewConfigurator(ViewConfigurator): + """ Simple adapter using attribute annotations as storage + for view properties. + """ + def __init__(self, context, request): self.context = context self.request = request @@ -83,19 +95,12 @@ class ViewConfigurator(object): propDefs = ann.get(ANNOTATION_KEY, {}) return [self.setupViewProperty(prop, propDef) for prop, propDef in propDefs.items() if propDef] - # idea: include properties from GlobalViewConfigurator; - # there also may be other view configurators e.g. based on - # the class (or some sort of type) of the context object. - # Also the view properties may be filtered by permission - # or other conditions. - # Note: collecting configurators may be solved by getting - # multiple configurators (+ utilities) in the controller! def getActiveViewProperties(self): return self.viewProperties def setupViewProperty(self, prop, propDef): - vp = zapi.queryMultiAdapter((self.context, self.request), + vp = component.queryMultiAdapter((self.context, self.request), IViewProperty, name=prop) if vp is None: vp = ViewProperty(self.context, self.request) @@ -104,19 +109,6 @@ class ViewConfigurator(object): return vp -class GlobalViewConfigurator(object): - """ A global utility that allows the registration of view properties. - """ - - implements(IViewConfigurator) - - def __init__(self): - self.viewProperties = [] - - def getActiveViewProperties(self): - return self.viewProperties - - class ViewProperty(object): implements(IViewProperty) @@ -136,7 +128,7 @@ class ViewProperty(object): self.params = params -class MacroViewProperty(object): +class MacroViewProperty(ViewProperty): implements(IMacroViewProperty) diff --git a/browser/configure.zcml b/browser/configure.zcml index df80f1e..04e3994 100644 --- a/browser/configure.zcml +++ b/browser/configure.zcml @@ -6,6 +6,8 @@ i18n_domain="zope" > + + - --> + + diff --git a/browser/controller.py b/browser/controller.py index f710248..6b54462 100644 --- a/browser/controller.py +++ b/browser/controller.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2006 Helmut Merz helmutm@cy55.de +# Copyright (c) 2008 Helmut Merz helmutm@cy55.de # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -27,6 +27,8 @@ from zope.app.pagetemplate import ViewPageTemplateFile from zope.cachedescriptors.property import Lazy from cybertools.browser.configurator import IViewConfigurator, IMacroViewProperty +from cybertools.browser.member import IMemberInfoProvider +from cybertools.util.jeep import Jeep # layout controller: collects information about head elements, skins, portlets, etc @@ -54,15 +56,11 @@ class Controller(object): return self.request.URL[0] + skinSetter + '/@@/' def configure(self): - #configurator = component.queryMultiAdapter((self.context, self.request), - # IViewConfigurator) - # idea: collect multiple configurators: + # collect multiple configurators: configurators = component.getAdapters((self.context, self.request), IViewConfigurator) for conf in configurators: configurator = conf[1] - #if configurator is not None: - #for item in configurator.viewProperties: for item in configurator.getActiveViewProperties(): if IMacroViewProperty.providedBy(item): self.macros.register(item.slot, item.idenitifier, @@ -71,6 +69,12 @@ class Controller(object): else: setattr(self, item.slot, item) + @Lazy + def memberInfo(self): + provider = component.queryMultiAdapter((self.context, self.request), + IMemberInfoProvider) + return provider is not None and provider.data or None + class Macros(dict): @@ -81,7 +85,7 @@ class Macros(dict): self.identifiers = set() def register(self, slot, identifier=None, template=None, name=None, - position=None, **kw): + priority=50, **kw): if identifier: # make sure a certain resource is only registered once if identifier in self.identifiers: @@ -91,22 +95,20 @@ class Macros(dict): template = self.standardTemplate if name is None: name = slot - macro = Macro(template, name, **kw) + macro = Macro(template, name, priority, **kw) entry = self.setdefault(slot, []) - if position is None: - entry.append(macro) - else: - entry.insert(position, macro) + entry.append(macro) def __getitem__(self, key): - return self.get(key, []) + return list(sorted(self.get(key, []), key=lambda x: x.priority)) class Macro(object): - def __init__(self, template, name, **kw): + def __init__(self, template, name, priority, **kw): self.template = template self.name = name + self.priority = priority for k in kw: setattr(self, k, kw[k]) diff --git a/browser/icons/user.png b/browser/icons/user.png new file mode 100644 index 0000000000000000000000000000000000000000..79f35ccbdad44489dbf07d1bf688c411aa3b612c GIT binary patch literal 741 zcmVz1iyEv%?$mbQ(# zwJpuiQJP8?X_`#S8b+U_G6=ziYB!xPAcq{)ZJ0bECH@ zYx#`n8^Wzn^J!4>=q^bltNO15ry?0ecSLkjpT@vlid!jk)Fjf7&)q_V5zGs#3N%6* zbW~7Hg=&P0&~Y(|g>$hC9FL?;ttzPDZbpZu9OLb33^e2;FNTGJxScp1&q4M+y2ntQ z?C(=hpU$3~`Thx0eHwi0x`q+!d5k@|0_WHe%sG3e-s^MM`xM-ig!VcIA7H}X1ot~L zg=MLB4w-Q;Bi!!u2|I+Qb;0{{4Q53YX6+4_aXena{nmt*!YG7ua~`qc>o=?@U?rOU znS7%>klzi*muXnbM6i@4FR@s^8vTjDgy&%J?w?`u>NYMDFa_2%0SQ(qJE<3=<8Bzo zfdU60e*y(^$RF%r$kl)p7=7tlCDa$+J7w>}DU(O#~fk>pYuRvHi1E9^msg{tLeV XM&GIRvfA7%00000NkvXXu0mjf&%8>| literal 0 HcmV?d00001 diff --git a/browser/liquid/base.css b/browser/liquid/base.css index 22e8199..0d89884 100644 --- a/browser/liquid/base.css +++ b/browser/liquid/base.css @@ -28,75 +28,4 @@ body { #menu {width:20%} #content {width:62%} #sub-section {width:17%} -#footer {clear:left} - -/* more general stuff */ - -.top image { - margin-top: -1px; -} - -div.box { - margin: 12px 12px 8px 10px; - border: 1px solid #ccc; - border-bottom: none; -} - -div.box h4 { - font: 110% Verdana, Tahoma, Arial, Helvetica, sans-serif; - color: #000040; - border: none; - border-bottom: 1px solid #ccc; - padding: 4px; - padding-top: 1px; - padding-bottom: 3px; - background-color: #ddd; - height: auto; -} - -table.listing { - margin: 1px; - margin-top: 6px; -} - -table.listing th { - font-family: Verdana, Tahoma, Arial, Helvetica, sans-serif; - color: #000040; -} - -.footer { - text-align: center; - border-top: 1px solid #ccc; - border-bottom: none; - margin-top: 12px; - padding-top: 6px; -} - -.itemViews { - border-bottom-width: 2px; -} - -.button { - margin: 1em 0 1em 0; -} - -.button a, .button a:visited { - padding: 2px 4px 2px 4px; - background-color: #e8e8e8; - text-decoration: None; - color: Black; - border-width: 2px; - border-style: solid; - border-color: #f4f4f4 #989898 #989898 #f4f4f4; -} - -.button a:active { - border-color: #989898 #f4f4f4 #f4f4f4 #989898; -} - -pre { - background-color: #f4f4f4; -} - -#footer { border-bottom: none; } - +#footer {clear:left; float:left} diff --git a/browser/liquid/configure.zcml b/browser/liquid/configure.zcml index f3c7656..0c9c604 100644 --- a/browser/liquid/configure.zcml +++ b/browser/liquid/configure.zcml @@ -43,6 +43,8 @@ layer="cybertools.browser.liquid.Liquid" /> + diff --git a/browser/liquid/controller.py b/browser/liquid/controller.py index e98cf6b..a2d7dc0 100644 --- a/browser/liquid/controller.py +++ b/browser/liquid/controller.py @@ -28,19 +28,26 @@ from cybertools.browser.controller import Controller as BaseController class Controller(BaseController): def __init__(self, context, request): + self.view = view = context # the controller is adapted to a view + self.context = context.context + self.request = request self.setupCss() self.setupJs() super(Controller, self).__init__(context, request) def setupCss(self): macros = self.macros - params = [('zope3_tablelayout.css', 'all'), - ('base.css', 'screen'), - ('print.css', 'print'), - ('custom.css', 'all')] + presentationMode = self.request.get('liquid.viewmode') == 'presentation' + params = [('zope3_tablelayout.css', 'all', 20), + ('base.css', 'screen', 25), + ('print.css', 'print', 30), + ('custom.css', 'all', 100)] + if presentationMode: + params.append(('presentation.css', 'all', 30)) for param in params: macros.register('css', identifier=param[0], - resourceName=param[0], media=param[1]) + resourceName=param[0], media=param[1], + priority=param[2]) def setupJs(self): return diff --git a/browser/liquid/presentation.css b/browser/liquid/presentation.css new file mode 100644 index 0000000..7846861 --- /dev/null +++ b/browser/liquid/presentation.css @@ -0,0 +1,21 @@ +/* + $Id$ + +*/ + +.body { + margin: 4em; +} + +.top, #header, #menu, #sub-section, #footer, #xedit_icon { + display: none; +} + +#content { + width: 100%; + color: #000077; +} + +h1, h2, h3, h4, h5 { + color: #005599; +} diff --git a/browser/liquid/zope3_tablelayout.css b/browser/liquid/zope3_tablelayout.css index 70aceb6..4a0ef28 100644 --- a/browser/liquid/zope3_tablelayout.css +++ b/browser/liquid/zope3_tablelayout.css @@ -1,10 +1,8 @@ /* ** Zope3 style sheet for CSS2-capable browsers. -** For future skin see zope.app.boston. -*/ - -/* -* { border: 1px dotted red } +** +** $Id$ +** */ @@ -31,7 +29,7 @@ table { font-size: 100%; } -a { +a[href] { text-decoration: none; color: #369; background-color: transparent; @@ -46,11 +44,6 @@ img { vertical-align: middle; } -p { - margin: 0.5em 0em 1em 0em; - line-height: 1.5em; -} - p a:visited { color: Purple; background-color: transparent; @@ -80,7 +73,7 @@ h1, h2, h3, h4, h5, h6 { clear: left; font: 100% bold Verdana, Helvetica, Arial, sans-serif; margin: 0; - padding-top: 0.5em; + padding-top: 0; border-bottom: 1px solid #369; } @@ -109,7 +102,7 @@ h6 { } ul { - line-height: 1.5em; + line-height: 1.2em; /* list-style-image: url("bullet.gif"); */ margin-left: 2em; padding:0; @@ -411,9 +404,6 @@ div.box h4 { } -#content { -} - #context_information { padding-top: 1em; width: 15%; @@ -425,18 +415,6 @@ div.box h4 { width: 100%; } -#helpers { -} - -#inspectors { -} - -#footer { - border-bottom: 1px solid black; - float: left; - clear: both; -} - input.textType { width: 88%; /* Same as textarea */ } diff --git a/browser/main.pt b/browser/main.pt index 43929c2..87d58a1 100644 --- a/browser/main.pt +++ b/browser/main.pt @@ -32,7 +32,8 @@ - + diff --git a/browser/member.py b/browser/member.py new file mode 100644 index 0000000..ad43487 --- /dev/null +++ b/browser/member.py @@ -0,0 +1,111 @@ +# +# Copyright (c) 2008 Helmut Merz helmutm@cy55.de +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +A member information provider is used to collect user/member/person attributes. + +$Id$ +""" + +from zope import component +from zope.app.security.interfaces import IAuthentication +from zope.cachedescriptors.property import Lazy +from zope.interface import Interface, Attribute, implements + +from cybertools.util.jeep import Jeep + + +# interfaces + +class IMemberInfoProvider(Interface): + """ Usually implemented by an adapter; provides a set of + user/member/person properties. + """ + + priority = Attribute('A number denoting the priority of the provider; ' + 'a provider with a high number may be overriden with a lower number.') + + data = Attribute('A collection/ordered mapping of member property objects ' + 'for the currently logged-in user.') + + def getData(principalId): + """ Return the member properties for the principal identified by + the principal id given. + """ + + def getDataForCategory(category, principalId=None): + """ Return a collection of the properties for the category given. + If no principal id is given use the currently logged-in user. + """ + + +class IMemberProperty(Interface): + + name = Attribute('The name/identifier of the property.') + title = Attribute('A short and descriptive title.') + category = Attribute('A string denoting a category or classification.') + + +#default implementation + +class MemberProperty(object): + + implements(IMemberProperty) + + def __init__(self, name, value, title=None, category='default'): + self.name = name + self.value = value + self.title = title or name + self.category = category + + +class MemberInfoProvider(object): + + implements(IMemberInfoProvider) + + defaultData = Jeep((MemberProperty('id', '???', u'ID'), + MemberProperty('title', u'unknown', u'Title'), + MemberProperty('description', u'', + u'Description'), + )) + + def __init__(self, context, request): + self.context = context + self.request = request + + @Lazy + def data(self): + return self.getData() + + def getData(self, principalId=None): + if principalId is None: + principal = self.request.principal + else: + pau = component.getUtility(IAuthentication) + principal = pau.getPrincipal(principalId) + if principal is not None: + return self.getPrincipalData(principal) + else: + return self.defaultData + + def getPrincipalData(self, principal): + return Jeep((MemberProperty('id', principal.id, u'ID'), + MemberProperty('title', principal.title, u'Title'), + MemberProperty('description', principal.description, + u'Description'), + )) diff --git a/browser/view.py b/browser/view.py index f4f2493..7d73c83 100644 --- a/browser/view.py +++ b/browser/view.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2006 Helmut Merz helmutm@cy55.de +# Copyright (c) 2008 Helmut Merz helmutm@cy55.de # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -58,14 +58,19 @@ class GenericView(object): # make the (one and only controller) available via the request viewAnnotations = self.request.annotations.setdefault('cybertools.browser', {}) viewAnnotations['controller'] = controller - if getattr(controller, 'skinName', None) and controller.skinName.value: - self.setSkin(controller.skinName.value) + #if getattr(controller, 'skinName', None) and controller.skinName.value: + # self.setSkin(controller.skinName.value) controller.skin = self.skin # this is the place to register special macros with the controller: self.setupController() def getController(self): viewAnnotations = self.request.annotations.setdefault('cybertools.browser', {}) - return viewAnnotations.get('controller', None) + cont = viewAnnotations.get('controller', None) + if cont is None: + cont = component.queryMultiAdapter((self, self.request), name='controller') + if cont is not None: + self.setController(cont) + return cont controller = property(getController, setController) def __init__(self, context, request): @@ -119,4 +124,3 @@ class GenericView(object): applySkin(self.request, skin) self.skin = skin - diff --git a/composer/schema/README.txt b/composer/schema/README.txt index 77ddccd..aea0013 100644 --- a/composer/schema/README.txt +++ b/composer/schema/README.txt @@ -167,5 +167,6 @@ Macros / renderers >>> fieldRenderers = form.fieldRenderers >>> sorted(fieldRenderers.keys()) - [u'field', u'field_spacer', u'fields', u'form', u'input_date', u'input_dropdown', - u'input_fileupload', u'input_password', u'input_textarea', u'input_textline'] + [u'field', u'field_spacer', u'fields', u'form', u'input_checkbox', + u'input_date', u'input_dropdown', u'input_fileupload', u'input_html', + u'input_password', u'input_textarea', u'input_textline'] diff --git a/composer/schema/browser/schema_macros.pt b/composer/schema/browser/schema_macros.pt index a3c43e2..708f4dd 100755 --- a/composer/schema/browser/schema_macros.pt +++ b/composer/schema/browser/schema_macros.pt @@ -80,20 +80,27 @@ + value data/?name|string:; + required field/required_js;" /> - + value data/?name|string:; + required field/required_js" /> + @@ -120,12 +127,24 @@ + + + + + + + + + +