<?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.1 - 2009-09-09
------------------

- Be more robust against broken layer registrations. These can occur when
  packages with registered layers are removed.
  [wichert]

- Clarified license and copyright.
  [hannosch]

- Register ourselves for the more generic ISiteRoot from CMFCore and not
  IPloneSiteRoot.
  [hannosch]

- Declare test dependencies in an extra.
  [hannosch]

- Specify package dependencies.
  [hannosch]

1.0.0 - 2008-04-20
------------------

- 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>Plone Foundation</foaf:name>
<foaf:mbox_sha1sum>7a7fecc394759b12e477801b9a3b3df2747d421c</foaf:mbox_sha1sum></foaf:Person></maintainer>
<release><Version><revision>1.0.1</revision></Version></release>
</Project></rdf:RDF>