How to install z3ext.layout
- Download and install ActivePython
- Open Command Prompt
- Type
pypm install z3ext.layout
Depended by
- z3ext.authentication
- z3ext.banner
- z3ext.batching
- z3ext.blogger
- z3ext.company
- z3ext.content.actions
- z3ext.content.activity
- z3ext.content.browser
- z3ext.content.discussion
- z3ext.content.documents
- z3ext.content.draft
- z3ext.content.ext.marker
- z3ext.content.feeds
- z3ext.content.forms
- z3ext.content.model
- z3ext.content.notifications
- z3ext.content.permissions
- z3ext.content.schema
- z3ext.content.space
- z3ext.content.type
- z3ext.content.workflow
- z3ext.contenttypes
- z3ext.contextlayout
- z3ext.controlpanel
- z3ext.error
- z3ext.extensions
- z3ext.formulator
- z3ext.forum
- z3ext.groups
- z3ext.homefolder
- z3ext.layoutform
- z3ext.members
- z3ext.memcached
- z3ext.messaging
- z3ext.pageelement
- z3ext.persistent.fields
- z3ext.persistentlayout
- z3ext.persistentresource
- z3ext.persistentviewmodel
- z3ext.personal.bar
- z3ext.personal.blogger
- z3ext.personal.content
- z3ext.personal.core
- z3ext.personal.favorites
- z3ext.personal.invitation
- z3ext.personal.messages
- z3ext.personal.photo
- z3ext.personal.profile
- z3ext.personal.space
- z3ext.photoalbum
- z3ext.portal
- z3ext.portlet
- z3ext.portletextension
- z3ext.portlets.amazonewidget
- z3ext.portlets.amazonwidget
- z3ext.portlets.recent
- z3ext.preferences
- z3ext.principal.groups
- z3ext.principal.invite
- z3ext.principal.management
- z3ext.principal.password
- z3ext.principal.profile
- z3ext.principal.registration
- z3ext.principal.roles
- z3ext.product
- z3ext.project
- z3ext.session
- z3ext.subscription
- z3ext.table
- z3ext.theme.default
- z3ext.ui.batching
- z3ext.ui.breadcrumbs
- z3ext.ui.logo
- z3ext.ui.personalbar
- z3ext.ui.portalactions
- z3ext.ui.simplettw
- z3ext.ui.skin
- z3ext.widget.checkbox
- z3ext.widget.radio
- z3ext.wiki
- z3ext.wizard
- z3ext.workflow
Lastest release
Template layouts
Layouts is different way of building skin templates without METAL.
We need load zcml file
>>> import z3ext.layout >>> from zope.configuration import xmlconfig >>> context = xmlconfig.file('meta.zcml', z3ext.layout)
>>> import os, tempfile >>> from zope import interface, component >>> from z3ext.layout import tests, interfaces >>> from z3ext.layout.pagelet import BrowserPagelet
Let's define main layout for our skin, it like 'page' macros from basicskin or rotterdam. It will contains <html>, <head> and <body> tags. It's like main_template in CMF or 'page' macro in basicskin/rotterdam
>>> temp_dir = tempfile.mkdtemp() >>> layoutportal = os.path.join(temp_dir, 'layoutportal.pt') >>> open(layoutportal, 'w').write( ... '''<html> ... <body> ... <div id="portal" tal:content="structure view/render"> ... </div> ... </body> ... </html>''')
Let's define 'portal' layout
>>> context = xmlconfig.string(""" ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext"> ... <z3ext:layout ... name="portal" ... for="zope.app.component.interfaces.ISite" ... template="%s" /> ... </configure>"""%layoutportal, context)
Here another layout.
>>> layoutworkspace = os.path.join(temp_dir, 'layoutworkspace.pt') >>> open(layoutworkspace, 'w').write(''' ... <div id="workspace" tal:content="structure view/render"></div>''')
>>> context = xmlconfig.string(""" ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext"> ... <z3ext:layout ... name="workspace" ... layout="portal" ... for="zope.app.component.interfaces.ISite" ... template="%s" /> ... </configure>"""%layoutworkspace, context)
You should notice that we used layout="portal" it indicates that 'workspace' layout uses 'portal' layout as parent. so 'workspace' will be rendered inside 'portal' layout
Now we need very simple view that uses BrowserPagelet
>>> class IMyView(interface.Interface): ... pass
>>> class MyView(BrowserPagelet): ... interface.implements(IMyView) ... ... def render(self): ... return self.context.__name__
>>> from zope.publisher.browser import TestRequest >>> request = TestRequest() >>> view = MyView(root, request)
It returns context __name__
>>> view.__call__() 'root'
By default BrowserPagelet uses layout without name, Let's create one, it will use 'workspace' layout as parent.
>>> layoutcontent = os.path.join(temp_dir, 'layoutcontent.pt') >>> open(layoutcontent, 'w').write(''' ... <div id="content" tal:content="structure view/render"></div>''')
>>> context = xmlconfig.string(""" ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext"> ... <z3ext:layout ... layout="workspace" ... for="zope.app.component.interfaces.ISite" ... template="%s" /> ... </configure>"""%layoutcontent, context)
>>> print view() <html> <body> <div id="portal"><div id="workspace"><div id="content">root</div></div></div> </body> </html>
All 3 our layout rendered. view rendered inside nameless layout then in -> 'workspace' layout -> 'portal' layout
Now let's create several more content objects
>>> folder1 = tests.Folder() >>> root['folder1'] = folder1
>>> print MyView(folder1, request)() <html> <body> <div id="portal"><div id="workspace"><div id="content">folder1</div></div></div> </body> </html>
And another one.
>>> folder1_1 = tests.Folder() >>> root['folder1']['folder1_1'] = folder1_1
>>> folder1_1_1 = tests.Folder() >>> root['folder1']['folder1_1']['folder1_1_1'] = folder1_1_1
>>> print MyView(folder1_1_1, request)() <html> <body> <div id="portal"><div id="workspace"><div id="content">folder1_1_1</div></div></div> </body> </html>
This is all quite easy. Let's use more complex example. For example later other developers decide change how portal looks for folder1 object they want that all folder1 and all it's childs(folder1_1, folder1_1_1) have same look.
Let's add '<table>' with couple columns
>>> layoutcolumns = os.path.join(temp_dir, 'layoutcolumns.pt') >>> open(layoutcolumns, 'w').write(''' ... <table id="columns"> ... <tr> ... <td id="column1">Column1</td> ... <td id="column2" tal:content="structure view/render"></td> ... <td id="column3">Column3</td> ... </tr> ... </table>''')
We register new layout for different interafce
>>> context = xmlconfig.string(""" ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext"> ... <z3ext:layout ... name="workspace" ... layout="portal" ... for="z3ext.layout.tests.IFolder1" ... template="%s" /> ... </configure>"""%layoutcolumns, context)
>>> interface.directlyProvides(folder1, tests.IFolder1)
>>> print MyView(folder1, request)() <html> <body> <div id="portal"><table id="columns"> <tr> <td id="column1">Column1</td> <td id="column2"><div id="content">folder1</div></td> <td id="column3">Column3</td> </tr> </table></div> </body> </html>
folder1 uses new 'workspace' layout, but what about other folders
>>> print MyView(folder1_1, request)() <html> <body> <div id="portal"><table id="columns"> <tr> <td id="column1">Column1</td> <td id="column2"><div id="content">folder1_1</div></td> <td id="column3">Column3</td> </tr> </table></div> </body> </html>
>>> print MyView(folder1_1_1, request)() <html> <body> <div id="portal"><table id="columns"> <tr> <td id="column1">Column1</td> <td id="column2"><div id="content">folder1_1_1</div></td> <td id="column3">Column3</td> </tr> </table></div> </body> </html>
Now we also change how folder1_1 looks, we can replace nameless layout. Also we can use nameless layout as parent with layout="."
>>> layoutcontent1_1 = os.path.join(temp_dir, 'layoutcontent1_1.pt') >>> open(layoutcontent1_1, 'w').write(''' ... <div id="content1_1"> ... <h1>Folder1_1</h1> ... <div tal:content="structure view/render"></div> ... </div>''')
>>> context = xmlconfig.string(""" ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext"> ... <z3ext:layout ... layout="." ... for="z3ext.layout.tests.IFolder1_1" ... template="%s" /> ... </configure>"""%layoutcontent1_1, context)
>>> interface.directlyProvides(folder1_1, tests.IFolder1_1)
>>> print MyView(folder1_1, request)() <html> <body> <div id="portal"><table id="columns"> <tr> <td id="column1">Column1</td> <td id="column2"><div id="content"><div id="content1_1"> <h1>Folder1_1</h1> <div>folder1_1</div> </div></div></td> <td id="column3">Column3</td> </tr> </table></div> </body> </html>
It still uses nameless layout that we defined for 'root'.
And same for folder1_1_1
>>> layoutcontent1_1_1 = os.path.join(temp_dir, 'layoutcontent1_1_1.pt') >>> open(layoutcontent1_1_1, 'w').write(''' ... <div id="content1_1_1"> ... <h1>Folder1_1_1</h1> ... <div tal:content="structure view/render"></div> ... </div>''')
>>> context = xmlconfig.string(""" ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext"> ... <z3ext:layout ... layout="." ... for="z3ext.layout.tests.IFolder1_1_1" ... template="%s" /> ... </configure>"""%layoutcontent1_1_1, context)
>>> interface.directlyProvides(folder1_1_1, tests.IFolder1_1_1)
>>> print MyView(folder1_1_1, request)() <html> <body> <div id="portal"><table id="columns"> <tr> <td id="column1">Column1</td> <td id="column2"><div id="content"><div id="content1_1"> <h1>Folder1_1</h1> <div><div id="content1_1_1"> <h1>Folder1_1_1</h1> <div>folder1_1_1</div> </div></div> </div></div></td> <td id="column3">Column3</td> </tr> </table></div> </body> </html>
CHANGES
2.2.2 (2009-09-14)
- Update tests for 64bit python
2.2.1 (2009-08-11)
- Update styles
- Copyright changed to 'Zope Foundation and Contributors'
2.2.0 (2009-07-14)
- Use chameleon for pagelets and layouts
- Added 'pagelet' chameleon expression
- Added 'queryPagelet' helper function
- Do not use metal in default layouts
- Use '+' for named pagelet instead of ';'
2.1.0 (2009-06-20)
- Allow use interface as type for z3ext:pagelet directive
- Allow use named typed pagelets with '@@pagelet' view and 'pagelet:' tales
- Added 'pageletObject' view, it doesn't call pagelet render method
2.0.8 (2009-06-03)
- Fixed next layout calculation for root object
2.0.7 (2009-04-15)
- Do not use z3c.autoinclude
2.0.6 (2009-03-11)
- Fixed discriminator for z3ext:pagelet directive
- Allow use 'layout' pagelet type as template for layout
- Update styles
2.0.5 (2009-01-26)
- Update styles
2.0.4 (2009-01-22)
- Pass permission to class required attributes
2.0.3 (2009-01-20)
- Use __parent__ for layout quering
2.0.2 (2009-01-08)
- Register layout for (view, for, layer), instead of view and for separatly
2.0.1 (2008-12-25)
- Pagelet should implement provided interfaces
2.0.0 (2008-12-22)
- Pagelet without name is not allowed
- Added 'type' attribute to 'z3ext:pagelet'
- Added 'z3ext:pageletType' directive for registering new pagelet types
- multiple params is allowed for 'for' attribute
- Removed pagelet 'manager' attribute
- 'pagelet' tales expression and 'pagelet' view checks additional context IPageletContext
if exists use it as adapter parameter
1.7.3 (2008-12-18)
- Use IPagelet instead of IPageTemplate for pagelet rendering
1.7.2 (2008-12-17)
- Update default styles
1.7.1 (2008-12-15)
- Check if context provides interface in @@pagelet view and pagelet: tales expresion
1.7.0 (2008-12-11)
- Added manager attribute to z3ext:pagelet directive
this allow use getMultiAdapter((content, request, manager1, manager2, ...), IPagelet)
- Use 'provides' schema for converting kwargs in z3ext:pagelet directive
1.6.0 (2008-11-27)
- Added 'uid' attribute to z3ext:layout directive.
Send ILayoutCreatedEvent event only if layout has uid
1.5.9 (2008-11-24)
- Fixed python2.4 compatibility
1.5.7 (2008-11-17)
- Update css styles
1.5.6 (2008-11-06)
- Register nameless pagelet only if provided interface is not
inherited from IBrowserPublisher
1.5.5 (2008-11-05)
- Add IPagelet interface to pagelet provides
1.5.4 (2008-10-30)
- Added 'pagelet' tales expression (same as @@pagelet)
- Update css styles
1.5.3 (2008-10-16)
- Update css styles
1.5.2 (2008-10-15)
- Render IPagelet adapter for @@pagelet view
1.5.1 (2008-10-14)
- Fixed missing NotFount in @@pagelet
- Log errors in @@pagelet
- Default css styles
1.5.0 (2008-10-06)
- Added @@pagelet browser view for fast access pagelets
1.4.6 (2008-10-03)
- Fixed bug with multple nameless pagelet
1.4.5 (2008-08-18)
- name attribute is optional for <z3ext:pagelet/> directive
1.4.4 (2008-07-22)
- Fix IPagelet adapter for content
1.4.3 (2008-05-22)
- Added LayoutNotFound exception
1.4.2 (2008-05-14)
- Remove unused interfaces
- Tests updated
1.4.1 (2008-04-23)
- Use newer version of z3ext.autoinclude
1.4 (2008-03-21)
- Added z3ext:pagelet directive
- Code cleanup
- Moved to svn.zope.org
1.3.2 (2008-03-06)
- Removed context layouts
1.3.1 (2008-02-21)
- Code cleanup
- Remove code related to zope.formlib
1.3.0 (2008-02-20)
- Removed code related to z3c.form
1.2.1 (2008-02-18)
- Added 'redirect' method to IBrowserPagelet, this is usefull
when we need redirect during 'update' method and we don't need render pagelet at all.
- Added adapter to IPagelet for (context, request),
this adapter gets browser:defaultView for context and if it IPagelet return it
1.2.0 (2008-02-13)
- Remove all code related to persistent templates
1.1.2 (2008-02-12)
- Added 'title' and 'description' fields layout directive
- check ILayoutTemplateTAL for ISite
1.1.0 (2008-02-08)
- Added compatibility with z3c.template layouts
- Added ILayoutTemplateTAL interface, other packages
can define adapter to this interface and change layout template TAL program (layout customization)
1.0.1 (2008-02-02)
- Added required dependencies
1.0.0 (2008-01-15)
- Initial release