finished registration of macros (for resources, global js calls, etc.) on new view structure with main.pt
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1315 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
		
							parent
							
								
									173fe3bd0c
								
							
						
					
					
						commit
						f0110c70dc
					
				
					 7 changed files with 125 additions and 45 deletions
				
			
		|  | @ -1,15 +1,68 @@ | ||||||
| Browser View Tools | Browser View Tools | ||||||
| ================== | ================== | ||||||
| 
 | 
 | ||||||
| We first set up a test and working environment: |  | ||||||
| 
 |  | ||||||
|   >>> from zope.app import zapi |  | ||||||
|   >>> from zope.app.testing import ztapi |  | ||||||
| 
 |  | ||||||
|   >>> from zope import component, interface |   >>> from zope import component, interface | ||||||
|   >>> from zope.publisher.browser import TestRequest |   >>> from zope.interface import Interface, implements | ||||||
|   >>> from zope.publisher.interfaces.browser import IBrowserRequest |   >>> 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 | ||||||
|  | will have to subclass it. (An example can be found in loops.browser - see | ||||||
|  | the common and node modules there.) | ||||||
|  | 
 | ||||||
|  | Let's start with a dummy content object and create a view on it: | ||||||
|  | 
 | ||||||
|  |   >>> class SomeObject(object): | ||||||
|  |   ...     implements(Interface) | ||||||
|  |   >>> obj = SomeObject() | ||||||
|  | 
 | ||||||
|  |   >>> from cybertools.browser.view import GenericView | ||||||
|  |   >>> class View(GenericView): pass | ||||||
|  | 
 | ||||||
|  |   >>> from zope.publisher.browser import TestRequest | ||||||
|  |   >>> request = TestRequest() | ||||||
|  |   >>> view = View(obj, request) | ||||||
|  | 
 | ||||||
|  | Via the `template` and `macro` attributes one may control the presentation of | ||||||
|  | the view - in fact the rendering of a certain content object is achieved | ||||||
|  | by providing an appropriate macro for its view. | ||||||
|  | 
 | ||||||
|  | The view also may provide a special skin and a menu. | ||||||
|  | 
 | ||||||
|  | All these attributes default to None: | ||||||
|  | 
 | ||||||
|  |   >>> view.template is None | ||||||
|  |   True | ||||||
|  |   >>> view.macro is None | ||||||
|  |   True | ||||||
|  |   >>> view.skin is None | ||||||
|  |   True | ||||||
|  |   >>> view.menu is None | ||||||
|  |   True | ||||||
|  | 
 | ||||||
|  | The `item` attribute may be used to delegate to another view; it defaults to | ||||||
|  | self: | ||||||
|  | 
 | ||||||
|  |   >>> view.item is view | ||||||
|  |   True | ||||||
|  | 
 | ||||||
|  | There is a method for setting the skin that will be called when the controller | ||||||
|  | attribute is set, see below: | ||||||
|  | 
 | ||||||
|  |   >>> view.setSkin(None) | ||||||
|  | 
 | ||||||
|  | When the view is called, the standard main template (main.pt) is rendered; | ||||||
|  | this template in turn calls the view's pageBody() method to render the | ||||||
|  | body. | ||||||
|  | 
 | ||||||
|  | This pageBody() method returns the rendered body by accessing another view | ||||||
|  | (default: BodyTemplateView) that provides a corresponding template in its | ||||||
|  | bodyTemplate attribute. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| The View Controller | The View Controller | ||||||
| ------------------- | ------------------- | ||||||
| 
 | 
 | ||||||
|  | @ -24,18 +77,6 @@ because this already provides some predefined stuff: | ||||||
| 
 | 
 | ||||||
|   >>> from cybertools.browser.liquid.controller import Controller |   >>> from cybertools.browser.liquid.controller import Controller | ||||||
| 
 | 
 | ||||||
| Before creating a controller we have to set up a context object and |  | ||||||
| a view: |  | ||||||
| 
 |  | ||||||
|   >>> class SomeObject(object): pass |  | ||||||
|   >>> obj = SomeObject() |  | ||||||
|   >>> from cybertools.browser.view import GenericView |  | ||||||
|   >>> class View(GenericView): |  | ||||||
|   ...     pass |  | ||||||
|   >>> from zope.publisher.browser import TestRequest |  | ||||||
|   >>> request = TestRequest() |  | ||||||
|   >>> view = View(obj, request) |  | ||||||
| 
 |  | ||||||
|   >>> controller = Controller(view, request) |   >>> controller = Controller(view, request) | ||||||
|   >>> controller.view is view |   >>> controller.view is view | ||||||
|   True |   True | ||||||
|  | @ -72,7 +113,7 @@ controller object to get an updated setting: | ||||||
|   >>> controller.resourceBase |   >>> controller.resourceBase | ||||||
|   'http://127.0.0.1/++skin++dummy/@@/' |   'http://127.0.0.1/++skin++dummy/@@/' | ||||||
| 
 | 
 | ||||||
| The controller may be used as a provider for content elements using | The controller may be used as a provider for HTML elements using | ||||||
| ZPT macros: | ZPT macros: | ||||||
| 
 | 
 | ||||||
|   >>> cssMacros = controller.macros['css'] |   >>> cssMacros = controller.macros['css'] | ||||||
|  | @ -87,15 +128,34 @@ Calling a macro provided by Controller.macros[] returns the real ZPT macro: | ||||||
|   >>> m1() |   >>> m1() | ||||||
|   [...base_macros.pt...css...] |   [...base_macros.pt...css...] | ||||||
| 
 | 
 | ||||||
| The pre-set collection of macros for a certain slot may be extended: | 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', resourceName='node.css', media='all') |   >>> controller.macros.register('css', 'node.css', resourceName='node.css', media='all') | ||||||
|   >>> len(controller.macros['css']) |   >>> len(controller.macros['css']) | ||||||
|   5 |   5 | ||||||
|   >>> m5 = cssMacros[4] |   >>> m5 = cssMacros[4] | ||||||
|   >>> print m5.name, m5.media, m5.resourceName |   >>> print m5.name, m5.media, m5.resourceName | ||||||
|   css all node.css |   css all node.css | ||||||
| 
 | 
 | ||||||
|  | If an identifier is given (the second parameter) a certain macro is only | ||||||
|  | registered once; note: the first setting will not be overridden! | ||||||
|  | 
 | ||||||
|  |   >>> controller.macros.register('css', 'node.css', resourceName='node.css') | ||||||
|  |   >>> len(controller.macros['css']) | ||||||
|  |   5 | ||||||
|  | 
 | ||||||
|  | We can also access slots that are not predefined: | ||||||
|  | 
 | ||||||
|  |   >>> controller.macros['js.execute'] | ||||||
|  |   [] | ||||||
|  | 
 | ||||||
|  |   >>> jsCall = 'dojo.require("dojo.widget.Editor")' | ||||||
|  |   >>> controller.macros.register('js-execute', jsCall, jsCall=jsCall) | ||||||
|  |   >>> dojoCall = controller.macros['js-execute'][0] | ||||||
|  |   >>> dojoCall() | ||||||
|  |   [...base_macros.pt...macro/jsCall...] | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| The View Configurator | The View Configurator | ||||||
| --------------------- | --------------------- | ||||||
|  |  | ||||||
|  | @ -23,3 +23,8 @@ | ||||||
|   </script> |   </script> | ||||||
| </metal:js> | </metal:js> | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | <metal:js define-macro="js-execute"> | ||||||
|  |     <script tal:content="macro/jsCall"></script> | ||||||
|  | </metal:js> | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | @ -21,7 +21,7 @@ | ||||||
| 
 | 
 | ||||||
|   <page for="*" |   <page for="*" | ||||||
|         name="body.html" |         name="body.html" | ||||||
|         class="cybertools.browser.view.GenericView" |         class="cybertools.browser.view.BodyTemplateView" | ||||||
|         permission="zope.View"/> |         permission="zope.View"/> | ||||||
| 
 | 
 | ||||||
|   <page name="controller" |   <page name="controller" | ||||||
|  |  | ||||||
|  | @ -69,12 +69,10 @@ class Macros(dict): | ||||||
| 
 | 
 | ||||||
|     def __init__(self, controller): |     def __init__(self, controller): | ||||||
|         self.controller = controller |         self.controller = controller | ||||||
|         self['css'] = [] |  | ||||||
|         self['js'] = [] |  | ||||||
|         self.identifiers = set() |         self.identifiers = set() | ||||||
| 
 | 
 | ||||||
|     def register(self, slot, template=None, name=None, position=None, |     def register(self, slot, identifier=None, template=None, name=None, | ||||||
|                  identifier=None, **kw): |                  position=None, **kw): | ||||||
|         if identifier: |         if identifier: | ||||||
|             # make sure a certain resource is only registered once |             # make sure a certain resource is only registered once | ||||||
|             if identifier in self.identifiers: |             if identifier in self.identifiers: | ||||||
|  | @ -85,12 +83,15 @@ class Macros(dict): | ||||||
|         if name is None: |         if name is None: | ||||||
|             name = slot |             name = slot | ||||||
|         macro = Macro(template, name, **kw) |         macro = Macro(template, name, **kw) | ||||||
|         if slot not in self: |         entry = self.setdefault(slot, []) | ||||||
|             self[slot] = [] |  | ||||||
|         if position is None: |         if position is None: | ||||||
|             self[slot].append(macro) |             entry.append(macro) | ||||||
|         else: |         else: | ||||||
|             self[slot].insert(position, macro) |             entry.insert(position, macro) | ||||||
|  | 
 | ||||||
|  |     def __getitem__(self, key): | ||||||
|  |         return self.get(key, []) | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class Macro(object): | class Macro(object): | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -36,11 +36,12 @@ class Controller(BaseController): | ||||||
|         macros = self.macros |         macros = self.macros | ||||||
|         params = [('zope3_tablelayout.css', 'all'), |         params = [('zope3_tablelayout.css', 'all'), | ||||||
|                   ('base.css', 'screen'), |                   ('base.css', 'screen'), | ||||||
|                   ('custom.css', 'all'), ('print.css', 'print')] |                   ('custom.css', 'all'), | ||||||
|  |                   ('print.css', 'print')] | ||||||
|         for param in params: |         for param in params: | ||||||
|             macros.register('css', resourceName=param[0], media=param[1]) |             macros.register('css', identifier=param[0], | ||||||
|  |                             resourceName=param[0], media=param[1]) | ||||||
| 
 | 
 | ||||||
|     def setupJs(self): |     def setupJs(self): | ||||||
|         return |         return | ||||||
|         #self.macros['js'] = [] |         #self.macros.register('js', resourceName='zope3.js') | ||||||
|         self.macros.register('js', resourceName='zope3.js') |  | ||||||
|  |  | ||||||
|  | @ -20,11 +20,15 @@ | ||||||
|       <metal:js use-macro="macro" /> |       <metal:js use-macro="macro" /> | ||||||
|     </tal:js> |     </tal:js> | ||||||
| 
 | 
 | ||||||
|  |     <tal:js repeat="macro controller/macros/js-execute"> | ||||||
|  |       <metal:js use-macro="macro" /> | ||||||
|  |     </tal:js> | ||||||
|  | 
 | ||||||
|     <link rel="icon" type="image/png" |     <link rel="icon" type="image/png" | ||||||
|           tal:attributes="href string:${resourceBase}favicon.png" /> |           tal:attributes="href string:${resourceBase}favicon.png" /> | ||||||
|   </head> |   </head> | ||||||
| 
 | 
 | ||||||
|   <body tal:content="structure body"/> |   <body tal:content="structure body" /> | ||||||
| 
 | 
 | ||||||
| </html> | </html> | ||||||
| </metal:block> | </metal:block> | ||||||
|  |  | ||||||
|  | @ -29,18 +29,27 @@ from zope.publisher.interfaces.browser import ISkin | ||||||
| from zope.app.pagetemplate import ViewPageTemplateFile | from zope.app.pagetemplate import ViewPageTemplateFile | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | mainTemplate = ViewPageTemplateFile('main.pt') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| class UnboundTemplateFile(ViewPageTemplateFile): | class UnboundTemplateFile(ViewPageTemplateFile): | ||||||
| 
 | 
 | ||||||
|     def __get__(self, instance, type): |     def __get__(self, instance, type): | ||||||
|         return self |         return self | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class GenericView(object): | class BodyTemplateView(object): | ||||||
|  |     """ Dummy view used for providing a body template. | ||||||
|  |     """ | ||||||
| 
 | 
 | ||||||
|     index = ViewPageTemplateFile('main.pt') |  | ||||||
|     bodyTemplate = UnboundTemplateFile('liquid/body.pt') |     bodyTemplate = UnboundTemplateFile('liquid/body.pt') | ||||||
| 
 | 
 | ||||||
|     menu = macro = skin = None | 
 | ||||||
|  | class GenericView(object): | ||||||
|  | 
 | ||||||
|  |     index = mainTemplate | ||||||
|  | 
 | ||||||
|  |     template = macro = menu = skin = None | ||||||
| 
 | 
 | ||||||
|     def setController(self, controller): |     def setController(self, controller): | ||||||
|         # make the (one and only controller) available via the request |         # make the (one and only controller) available via the request | ||||||
|  | @ -66,10 +75,14 @@ class GenericView(object): | ||||||
|     def setupController(self): |     def setupController(self): | ||||||
|         pass |         pass | ||||||
| 
 | 
 | ||||||
|  |     @Lazy | ||||||
|  |     def item(self): | ||||||
|  |         return self | ||||||
|  | 
 | ||||||
|     def pageBody(self): |     def pageBody(self): | ||||||
|         template = component.getMultiAdapter((self.context, self.request), |         bodyTemplate = component.getMultiAdapter((self.context, self.request), | ||||||
|                                                  name='body.html').bodyTemplate |                                                  name='body.html').bodyTemplate | ||||||
|         return template(self) |         return bodyTemplate(self) | ||||||
| 
 | 
 | ||||||
|     def setSkin(self, skinName): |     def setSkin(self, skinName): | ||||||
|         skin = None |         skin = None | ||||||
|  | @ -79,8 +92,4 @@ class GenericView(object): | ||||||
|                 applySkin(self.request, skin) |                 applySkin(self.request, skin) | ||||||
|         self.skin = skin |         self.skin = skin | ||||||
| 
 | 
 | ||||||
|     @Lazy |  | ||||||
|     def item(self): |  | ||||||
|         return self |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 helmutm
						helmutm