diff --git a/browser/README.txt b/browser/README.txt
index b99d1ec..d97648b 100644
--- a/browser/README.txt
+++ b/browser/README.txt
@@ -6,3 +6,88 @@ We first set up a test and working environment:
>>> from zope.app import zapi
>>> from zope.app.testing import ztapi
+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
+additional functionality e.g. for templates without the view being aware
+of it.
+
+This view controller (or controller view) is typically provided by the
+Controller class. Let's use the Controller sub-class from the Liquid skin
+because this already provides some predefined stuff:
+
+ >>> 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()
+ >>> class View(object):
+ ... def __init__(self, context, request):
+ ... self.context = context
+ ... self.request = request
+ >>> from zope.publisher.browser import TestRequest
+ >>> request = TestRequest()
+ >>> view = View(obj, request)
+
+ >>> controller = Controller(view, request)
+ >>> controller.view is view
+ True
+ >>> controller.context is obj
+ True
+ >>> controller.request is request
+ True
+
+The controller registers itself with the view:
+
+ >>> view.controller is controller
+ True
+
+The resourceBase attribute gives a base URL to which one can simply append
+the name of a resource.
+
+ >>> controller.resourceBase
+ 'http://127.0.0.1/@@/'
+
+If necessary, a ++skin++xxx path element is provided
+with the resourceBase to care for proper skin setting. This will work only
+(and is only necessary) when the skin is set programmatically
+
+ >>> class DummySkin(object): pass
+ >>> skin = DummySkin; skin.__name__ = 'dummy'
+
+Note that we make heavy use of Lazy attributes, so we have to get a new
+controller object to get an updated setting:
+
+ >>> controller = Controller(view, request)
+ >>> controller.skin = skin
+ >>> controller.resourceBase
+ 'http://127.0.0.1/++skin++dummy/@@/'
+
+The controller may be used as a provider for content elements using
+ZPT macros:
+
+ >>> cssMacros = controller.macros['css']
+ >>> len(cssMacros)
+ 4
+ >>> m1 = cssMacros[0]
+ >>> print m1.name, m1.media, m1.resourceName
+ css all zope3_tablelayout.css
+
+Calling a macro provided by Controller.macros[] returns the real ZPT macro:
+
+ >>> m1()
+ [...base_macros.pt...css...]
+
+The pre-set collection of macros for a certain slot may be extended:
+
+ >>> controller.macros.register('css', resourceName='node.css', media='all')
+ >>> len(controller.macros['css'])
+ 5
+ >>> m5 = cssMacros[4]
+ >>> print m5.name, m5.media, m5.resourceName
+ css all node.css
+
diff --git a/browser/base_macros.pt b/browser/base_macros.pt
new file mode 100644
index 0000000..3e33b80
--- /dev/null
+++ b/browser/base_macros.pt
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/browser/configure.zcml b/browser/configure.zcml
index 2ec65cf..6f9c0ff 100644
--- a/browser/configure.zcml
+++ b/browser/configure.zcml
@@ -6,7 +6,8 @@
i18n_domain="zope"
>
-
diff --git a/browser/controller.py b/browser/controller.py
index 2bca433..ba842c6 100644
--- a/browser/controller.py
+++ b/browser/controller.py
@@ -23,24 +23,63 @@ $Id$
"""
from zope.app import zapi
+from zope.app.pagetemplate import ViewPageTemplateFile
from zope.cachedescriptors.property import Lazy
class Controller(object):
+ def __init__(self, context, request):
+ self.view = context # the controller is adapted to a view
+ self.context = context.context
+ self.request = request
+ self.skin = None # may be overwritten by the view
+ context.controller = self # notify the view
+
@Lazy
def macros(self):
return Macros(self)
+ @Lazy
+ def resourceBase(self):
+ skinSetter = self.skin and ('/++skin++' + self.skin.__name__) or ''
+ # TODO: put '/@@' etc after path to site instead of directly after URL0
+ return self.request.URL[0] + skinSetter + '/@@/'
-class Macros(object):
+
+class Macros(dict):
+
+ # TODO: move to namedTemplate
+ standardTemplate = ViewPageTemplateFile('base_macros.pt')
def __init__(self, controller):
self.controller = controller
- self.context = controller.context
- self.request = controller.request
+
+ def register(self, slot, template=None, name=None, position=None, **kw):
+ if template is None:
+ template = self.standardTemplate
+ if name is None:
+ name = slot
+ macro = Macro(template, name, **kw)
+ if slot not in self:
+ self[slot] = []
+ if position is None:
+ self[slot].append(macro)
+ else:
+ self[slot].insert(position, macro)
+
+class Macro(object):
+
+ def __init__(self, template, name, **kw):
+ self.template = template
+ self.name = name
+ for k in kw:
+ setattr(self, k, kw[k])
@Lazy
- def css(self):
- return 'Here comes the CSS stuff...'
-
+ def macro(self):
+ return self.template.macros[self.name]
+
+ def __call__(self):
+ return self.macro
+
diff --git a/browser/ftests.py b/browser/ftests.py
index 8b54f89..6aaa6f2 100755
--- a/browser/ftests.py
+++ b/browser/ftests.py
@@ -7,7 +7,7 @@ from zope.app.testing.functional import FunctionalDocFileSuite
def test_suite():
flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
- browser = FunctionalDocFileSuite('liquid.txt', optionflags=flags)
+ browser = FunctionalDocFileSuite('liquid/README.txt', optionflags=flags)
return unittest.TestSuite((browser,))
if __name__ == '__main__':
diff --git a/browser/liquid.txt b/browser/liquid/README.txt
similarity index 92%
rename from browser/liquid.txt
rename to browser/liquid/README.txt
index db04b70..5343faa 100644
--- a/browser/liquid.txt
+++ b/browser/liquid/README.txt
@@ -11,7 +11,7 @@ We first set up a test and working environment:
>>> browser = Browser()
>>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
-We can now open a page using the CyberView skin:
+We can now open a page using the Liquid skin:
>>> browser.addHeader('Accept-Language', 'en-US')
>>> browser.open('http://localhost/++skin++Liquid')
diff --git a/browser/liquid/configure.zcml b/browser/liquid/configure.zcml
index 8186869..8cebc26 100644
--- a/browser/liquid/configure.zcml
+++ b/browser/liquid/configure.zcml
@@ -22,13 +22,15 @@
permission="zope.View"
layer="liquid" />
-
+
-
-
-
+
+
+
diff --git a/browser/liquid/controller.py b/browser/liquid/controller.py
new file mode 100644
index 0000000..9c24a3b
--- /dev/null
+++ b/browser/liquid/controller.py
@@ -0,0 +1,45 @@
+#
+# Copyright (c) 2006 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
+#
+
+"""
+View controller for the Liquid skin.
+
+$Id$
+"""
+
+from cybertools.browser.controller import Controller as BaseController
+
+
+class Controller(BaseController):
+
+ def __init__(self, context, request):
+ super(Controller, self).__init__(context, request)
+ self.setupCss()
+ self.setupJs()
+
+ def setupCss(self):
+ macros = self.macros
+ params = [('zope3_tablelayout.css', 'all'),
+ ('base.css', 'screen'),
+ ('custom.css', 'all'), ('print.css', 'print')]
+ for param in params:
+ macros.register('css', resourceName=param[0], media=param[1])
+
+ def setupJs(self):
+ #self.macros['js'] = []
+ self.macros.register('js', resourceName='zope3.js')
diff --git a/browser/liquid/view_macros.pt b/browser/liquid/view_macros.pt
index 08b27c5..e7b9618 100644
--- a/browser/liquid/view_macros.pt
+++ b/browser/liquid/view_macros.pt
@@ -1,46 +1,39 @@
+ tal:define="controller nocall:view/@@controller;
+ resourceBase controller/resourceBase">
+
+
Powered by Zope 3
-
+
+
+
+
+
+
-
+
+
+
-
-
-
-
+
-