<?xml version="1.0" encoding="UTF-8" ?>
<rdf:RDF xmlns="http://usefulinc.com/ns/doap#" xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><Project><name>plone.browserlayer</name>
<shortdesc>Browser layer management for Zope 2 applications</shortdesc>
<description>Introduction
============

This package aims to make it easier to register visual components (e.g. views
and viewlets) so that they only show up in a Plone site where they have been
explicitly installed.

It requires GenericSetup 1.4 later.

Basic usage
-----------

To use this feature, you should:

 - declare plone.browserlayer as a dependency, e.g. in setup.py::
 
    install_requires=[
          'plone.browserlayer',
      ],
 
 - ensure that its ZCML is loaded, e.g. with an include from your own package::
 
    &lt;include package="plone.browserlayer" /&gt;
    
 - create a layer marker interface unique to your product::
 
    from zope.interface import Interface
    class IMyProductLayer(Interface):
        """A layer specific to my product 
        """
        
 - register this with GenericSetup, in a browserlayer.xml file::
 
    &lt;layers&gt;
        &lt;layer name="my.product" 
               interface="my.product.interfaces.IMyProductLayer" /&gt;
    &lt;/layers&gt;
    
 - register visual components in ZCML for this layer, e.g.::
 
    &lt;browser:page
        name="my-view"
        for="*"
        layer=".interfaces.IMyProductLayer"
        permission="zope.Public"
        template="my-view.pt"
        /&gt;

No seriously, it works, just look here
--------------------------------------

In testing.zcml we have registered a view, layer-test-view, available only for
the layer plone.browserlayer.tests.interfaces.IMyProductLayer.

Before the product is installed, we cannot view this:

    &gt;&gt;&gt; from plone.browserlayer.tests.interfaces import IMyProductLayer
    &gt;&gt;&gt; from plone.browserlayer import utils
    &gt;&gt;&gt; IMyProductLayer in utils.registered_layers()
    False

    &gt;&gt;&gt; from Products.Five.testbrowser import Browser
    &gt;&gt;&gt; browser = Browser()
    &gt;&gt;&gt; browser.open(self.portal.absolute_url() + '/@@layer-test-view')
    Traceback (most recent call last):
    ...
    HTTPError: HTTP Error 404: Not Found
    
We can view a view registered for the default layer, though:

    &gt;&gt;&gt; browser.open(self.portal.absolute_url() + '/@@standard-test-view')
    &gt;&gt;&gt; print browser.contents
    A standard view
    
However, if we install the product the interface is registered in the local
site manager. Here we use the utility method directly, though we could also
use GenericSetup.
    
    &gt;&gt;&gt; utils.register_layer(IMyProductLayer, name='my.product')
    &gt;&gt;&gt; IMyProductLayer in utils.registered_layers()
    True
    
And if we now traverse over the site root and render the view, it should be
there.

    &gt;&gt;&gt; browser.open(self.portal.absolute_url() + '/@@layer-test-view')
    &gt;&gt;&gt; print browser.contents
    A local view
    
Unlike when applying a new skin, layers installed in this way do not override
views registered for the default layer.

    &gt;&gt;&gt; browser.open(self.portal.absolute_url() + '/@@standard-test-view')
    &gt;&gt;&gt; print browser.contents
    A standard view
    
It is also possible to uninstall a layer:

    &gt;&gt;&gt; IMyProductLayer in utils.registered_layers()
    True
    &gt;&gt;&gt; utils.unregister_layer(name='my.product')
    &gt;&gt;&gt; IMyProductLayer in utils.registered_layers()
    False
    
    &gt;&gt;&gt; browser.open(self.portal.absolute_url() + '/@@layer-test-view')
    Traceback (most recent call last):
    ...
    HTTPError: HTTP Error 404: Not Found
    
GenericSetup support
--------------------

Most of the time, you will be registering layers using GenericSetup. Here
is how that looks.

    &gt;&gt;&gt; from Products.CMFCore.utils import getToolByName
    &gt;&gt;&gt; portal_setup = getToolByName(self.portal, 'portal_setup')

We should be able to install our product's profile. For the purposes of
this test, the profile is defined in tests/profiles/default/testing and 
registered in testing.zcml. It has a file called browserlayer.xml which
contains::

    &lt;layers&gt;
        &lt;layer name="plone.browserlayer.tests" 
               interface="plone.browserlayer.tests.interfaces.IMyProductLayer" /&gt;
    &lt;/layers&gt;

Let's import it:

    &gt;&gt;&gt; IMyProductLayer in utils.registered_layers()
    False
    &gt;&gt;&gt; _ = portal_setup.runAllImportStepsFromProfile('profile-plone.browserlayer:testing')
    &gt;&gt;&gt; IMyProductLayer in utils.registered_layers()
    True

And just to prove that everything still works:

    &gt;&gt;&gt; browser.open(self.portal.absolute_url() + '/@@layer-test-view')
    &gt;&gt;&gt; print browser.contents
    A local view

    &gt;&gt;&gt; browser.open(self.portal.absolute_url() + '/@@standard-test-view')
    &gt;&gt;&gt; print browser.contents
    A standard view


Changelog
=========

1.0.0 - April 20th 2008
-----------------------

- Unchanged from 1.0rc4

1.0rc4
------

- Register the GenericSetup import and export steps using zcml. This means
  you will no longer need to install this package manually.
  [wichert]

1.0rc3
------

* Include README.txt and HISTORY.txt in the package's long description.
  [wichert]

* Add metadata.xml to the GenericSetup profile. This fixes a deprecation
  warning for Plone 3.1 and later.
  [wichert]

1.0b1
-----

* Initial package structure.
  [zopeskel]</description>
<homepage rdf:resource="http://plone.org" />
<maintainer><foaf:Person><foaf:name>Martin Aspeli</foaf:name>
<foaf:mbox_sha1sum>8261a008e2af96a6a1cb735bed91bc943ef465b5</foaf:mbox_sha1sum></foaf:Person></maintainer>
<release><Version><revision>1.0.0</revision></Version></release>
</Project></rdf:RDF>