Welcome, guest | Sign In | My Account | Store | Cart

Notice! PyPM is being replaced with the ActiveState Platform, which enhances PyPM’s build and deploy capabilities. Create your free Platform account to download ActivePython or customize Python with the packages you require and get automatic updates.

Download
ActivePython
INSTALL>
pypm install z3ext.layout

How to install z3ext.layout

  1. Download and install ActivePython
  2. Open Command Prompt
  3. Type pypm install z3ext.layout
 Python 2.7Python 3.2Python 3.3
Windows (32-bit)
2.2.2 Available View build log
Windows (64-bit)
2.2.2 Available View build log
Mac OS X (10.5+)
2.2.2 Available View build log
Linux (32-bit)
2.2.2 Available View build log
Linux (64-bit)
2.2.2 Available View build log
Web
 
Author
License
ZPL 2.1
Depended by
Imports
Lastest release
version 2.2.2 on Jan 5th, 2011

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)

System Message: WARNING/2 (<string>, line 306)

Title underline too short.

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

System Message: WARNING/2 (<string>, line 395)

Bullet list ends without a blank line; unexpected unindent.

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

System Message: WARNING/2 (<string>, line 420)

Bullet list ends without a blank line; unexpected unindent.

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.

System Message: WARNING/2 (<string>, line 429)

Bullet list ends without a blank line; unexpected unindent.

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

System Message: WARNING/2 (<string>, line 448)

Bullet list ends without a blank line; unexpected unindent.

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

System Message: WARNING/2 (<string>, line 565)

Bullet list ends without a blank line; unexpected unindent.

when we need redirect during 'update' method and we don't need render pagelet at all.

  • Added adapter to IPagelet for (context, request),

System Message: WARNING/2 (<string>, line 569)

Bullet list ends without a blank line; unexpected unindent.

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

System Message: WARNING/2 (<string>, line 592)

Bullet list ends without a blank line; unexpected unindent.

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

Subscribe to package updates

Last updated Jan 5th, 2011

Download Stats

Last month:2

What does the lock icon mean?

Builds marked with a lock icon are only available via PyPM to users with a current ActivePython Business Edition subscription.

Need custom builds or support?

ActivePython Enterprise Edition guarantees priority access to technical support, indemnification, expert consulting and quality-assured language builds.

Plan on re-distributing ActivePython?

Get re-distribution rights and eliminate legal risks with ActivePython OEM Edition.