This Documentation gives a step by step guide for making Silva layouts using Silva 1.6 and Silva 2.x.
Before making the layout product download the SilvaLayout 0.5.10 product, restart your Zope instance, and then in the service_extensions tab of the Zope Management Interface (ZMI) install the SilvaLayout product.
First make a directory with the name of your layout, for this example this will be called "NameOfLayout" in either the ./Products/ directory if you are using a Silva tarball or svn, or the ./products directory if you are using a Silva buildout.
Move into the layout directory and make the following files and directories.
In this example I am placing two directories in my layout product. It is not mandatory to have these directories for a layout product.
After creating the files and directories open the __init__.py file and add the following lines of code:
import install from Products.Silva.ExtensionRegistry import extensionRegistry import install from Products.Silva.ExtensionRegistry import extensionRegistry from Products.Silva.ExtensionRegistry import extensionRegistry import install def initialize(context): extensionRegistry.register( 'NameOfLayout', 'Name Of Layout', context, [], install, depends_on='SilvaLayout')
Save the __init__.py file and now open the install.py file and add the following code:
from os import path from Globals import package_home mapping = {} installed_attr = '__name_of_layout__installed__' def is_installed(context): return hasattr(context, installed_attr) def install(context): configureMetadata(context) setattr(context, installed_attr, 1) def uninstall(context): delattr(context, installed_attr) def configureMetadata(context): product = package_home(globals()) schema = path.join(product, 'schema') collection = context.service_metadata.getCollection() for types, setids in mapping.items(): for setid in setids: if not setid in collection.objectIds(): xmlfile = path.join(schema, setid+'.xml') definition = open(xmlfile, 'r') context.service_metadata.addTypesMapping(types, setids) context.service_metadata.initializeMetadata()
Save and close the install file.
Next open the configure.zcml file and add the following code:
<configure xmlns="http://namespaces.zope.org/zope" xmlns:browser="http://namespaces.zope.org/browser" xmlns:five="http://namespaces.zope.org/five" xmlns:i18n="http://namespaces.zope.org/i18n" > <include package="Products.SilvaLayout" /> <browser:layer name="NameOfLayout" /> <browser:page name="index.html" for="Products.Silva.interfaces.IContent" class="Products.SilvaLayout.browser.silvaview.Content" template="template.pt" permission="zope2.View" layer="NameOfLayout" /> <browser:page name="index.html" for="Products.Silva.interfaces.IContainer" class="Products.Silva.browser.silvaview.Container" template="template.pt" permission="zope2.View" layer="NameOfLayout" /> <browser:resourceDirectory name="css" directory="css" permission="zope2.View" layer="NameOfLayout" /> <browser.resourceDirectory name="images" directory="images" permission="zope2.View" layer="NameOfLayout" /> <browser:skin name="NameOfLayout" layer="NameOfLayout silvadefault default" /> </configure>
Save and close the configure.zcml.
Now open the template.pt file. The template file has been reduced to only a couple of useful bits of code. The template shows how to link to the css directory using an example stylesheet called main.css. The example also uses and image coming from the images directory. The template also makes uses of the tree.py module in SilvaLayout/browser/tree.py. This is a useful module for getting access to navigation trees. It comes with built in styles which can be overridden by users making their own tree css styles. Finally the template calls content from the view/render method, the method used for getting access to Silva Documents.:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" metal:define-macro="main"> <head> <!-- title --> <title tal:content="structure view/title"/> <!-- meta data --> <meta tal:replace="structure context/@@contenttype" /> <!-- Injector for content-specific css/js inclusion --> <link tal:replace="structure here/head_inject | nothing" /> <!-- EXAMPLE LINK TAG --> <link rel="stylesheet" tal:attributes="href request/resourcebase/++resource++css/main.css"/> </head> <body> <!-- EXAMPLE IMAGE TAG --> <img tal:attributes="src request/resourcebase/++resource++images/name_of_image.gif" /> <!-- EXAMPLE TREE --> <div tal:content="structure context/@@treeview/renderHTML"> <!-- navtree goes here --> </div> <div id="contents"> <span tal:content="structure view/render" /><br /> </div> </body> </html>
Go to the Silva Management Interface (SMI) of your Silva root. Click on the properties tab, and then click on the settings... button, at the bottom of the page you can use the pulldown menu to select the newly built skin.
Follow the Setup steps in the previous example only switching the products to Silva trunk and SilvaLayout trunk.
Without going into too much detail, the main difference between a Silva 1.6 layout and a 2.x layout is the exclusion of initialization code in a single __init__.py file. I say "single __init__.py" because this example uses a much deeper directory tree, each directory using an __init__.py file to register the directory with python. Another striking difference is the lack of an install.py file. In addition to a deeper directory tree each directory comes with its own configure.zcml. Finally there there is the addition of the skin.py file, which contains a class subclassing a default SilvaLayout interface.
First make a directory with the name of your layout (NameLayout) in either the ./Products/ directory if you are using a Silva tarball or the ./products/ directory if you are using a Silva buildout.
Move into the layout directory and make the following files and directories
Open the __init__.py and add the following:
#
Save and close the file. Then open the configure.zcml file and the following directives:
<configure xmlns="http://namespaces.zope.org/zope" xmlns:browser="http://namespaces.zope.org/browser" xmlns:five="http://namespaces.zope.org/five"> <!-- make sure SilvaLayout is loaded first --> <include package="Products.SilvaLayout" /> <!-- include views --> <include package=".browser" /> </configure>
Save and close the configure.zcml. Now enter the browser directory and make the following files and directory:
open the __init__.py file and the following code:
#
Save the file and open the configure.zcml file and add:
<configure xmlns="http://namespaces.zope.org/zope" xmlns:browser="http://namespaces.zope.org/browser" xmlns:five="http://namespaces.zope.org/five"> <include package=".NameOfLayoutTemplate" /> </configure>
Now enter the NameOfLayoutTemplate directory and add the following files and directories:
- __init__.py
Open __init__.py and add the following code:
#
Save the file and open the configure.zcml and add the following code:
<configure xmlns="http://namespaces.zope.org/zope" xmlns:browser="http://namespaces.zope.org/browser" xmlns:five="http://namespaces.zope.org/five"> <browser:page name="index.html" for="Products.Silva.interfaces.IContent" class="Products.SilvaLayout.browser.silvaview.Content" template="template.pt" permission="zope2.View" layer=".skin.INameOfLayoutTemplate" /> <browser:page name="index.html" for="Products.Silva.interfaces.IContainer" class="Products.SilvaLayout.browser.silvaview.Container" template="template.pt" permission="zope2.View" layer=".skin.INameOfLayoutTemplate" /> <browser:resourceDirectory name="css" directory="css" permission="zope2.View" layer=".skin.INameOfLayoutTemplate" /> <browser:resourceDirectory name="images" directory="images" permission="zope2.View" layer=".skin.INameOfLayoutTemplate" /> <interface interface=".skin.INameOfLayoutTemplate" type="zope.publisher.interfaces.browser.IBrowserSkinType" name="NameLayout" /> </configure>
Save and close this file. Open the skin.py file and add the following code:
from Products.SilvaLayout.browser.silvadefault.skin import ISilvaDefault class INameOfLayoutTemplate(ISilvaDefault): """Default skin for SilvaLayout. """
Save the skin.py file.
The template.pt remains the same as the previous example.
Apply the layout in the same way as the previous example.
This is only one way to make a layout, it is not necessary to follow this tree structure if you do not wish to.