[Checkins] SVN: z3c.resourceinclude/ Initial import.

Malthe Borch mborch at gmail.com
Sun Mar 2 12:53:43 EST 2008


Log message for revision 84408:
  Initial import.

Changed:
  A   z3c.resourceinclude/
  A   z3c.resourceinclude/trunk/
  A   z3c.resourceinclude/trunk/AUTHOR.txt
  A   z3c.resourceinclude/trunk/README.txt
  A   z3c.resourceinclude/trunk/setup.py
  A   z3c.resourceinclude/trunk/z3c/
  A   z3c.resourceinclude/trunk/z3c/__init__.py
  A   z3c.resourceinclude/trunk/z3c/resourceinclude/
  A   z3c.resourceinclude/trunk/z3c/resourceinclude/README.txt
  A   z3c.resourceinclude/trunk/z3c/resourceinclude/__init__.py
  A   z3c.resourceinclude/trunk/z3c/resourceinclude/collector.py
  A   z3c.resourceinclude/trunk/z3c/resourceinclude/configure.zcml
  A   z3c.resourceinclude/trunk/z3c/resourceinclude/interfaces.py
  A   z3c.resourceinclude/trunk/z3c/resourceinclude/manager.py
  A   z3c.resourceinclude/trunk/z3c/resourceinclude/meta.zcml
  A   z3c.resourceinclude/trunk/z3c/resourceinclude/provider.pt
  A   z3c.resourceinclude/trunk/z3c/resourceinclude/provider.py
  A   z3c.resourceinclude/trunk/z3c/resourceinclude/testing.py
  A   z3c.resourceinclude/trunk/z3c/resourceinclude/tests/
  A   z3c.resourceinclude/trunk/z3c/resourceinclude/tests/__init__.py
  A   z3c.resourceinclude/trunk/z3c/resourceinclude/tests/test_doctests.py
  A   z3c.resourceinclude/trunk/z3c/resourceinclude/zcml.py
  A   z3c.resourceinclude/trunk/z3c/resourceinclude/zcml.txt

-=-
Added: z3c.resourceinclude/trunk/AUTHOR.txt
===================================================================
--- z3c.resourceinclude/trunk/AUTHOR.txt	                        (rev 0)
+++ z3c.resourceinclude/trunk/AUTHOR.txt	2008-03-02 17:53:42 UTC (rev 84408)
@@ -0,0 +1 @@
+Malthe Borch <mborch at gmail.com>

Added: z3c.resourceinclude/trunk/README.txt
===================================================================
--- z3c.resourceinclude/trunk/README.txt	                        (rev 0)
+++ z3c.resourceinclude/trunk/README.txt	2008-03-02 17:53:42 UTC (rev 84408)
@@ -0,0 +1,41 @@
+Overview
+--------
+
+A package that provides functionality to register resources for
+inclusion in HTML documents:
+
+* Cascading stylesheets (.css)
+* Kinetic stylesheets (.kss)
+* Javascript (.js)
+
+
+Usage
+-----
+
+The package operates with browser resources, registered individually
+or using the resource directory factory.
+
+A simple example::
+
+   <configure xmlns="http://namespaces.zope.org/zope"
+             xmlns:browser="http://namespaces.zope.org/browser">
+
+     <include package="z3c.resourceinclude" file="meta.zcml" />
+     <include package="z3c.resourceinclude" />
+
+     <browser:resource name="example.css" file="example.css" />
+
+     <browser:resourceInclude
+          layer="zope.publisher.interfaces.browser.IDefaultBrowserLayer"
+          include="example.css"
+      />
+
+   </configure>
+
+
+This registration means that whenever the request provides
+``IDefaultBrowserLayer`` the resource named 'example.css' will be
+included on the page.
+
+To actually include resources, a content provider is provided, see
+``z3c/resourceinclude/provide.py``.

Added: z3c.resourceinclude/trunk/setup.py
===================================================================
--- z3c.resourceinclude/trunk/setup.py	                        (rev 0)
+++ z3c.resourceinclude/trunk/setup.py	2008-03-02 17:53:42 UTC (rev 84408)
@@ -0,0 +1,37 @@
+from setuptools import setup, find_packages
+import sys, os
+
+version = '0.1'
+
+setup(name='z3c.resourceinclude',
+      version=version,
+      description="",
+      long_description=open('README.txt').read(),
+      classifiers=[
+        "Framework :: Zope2",
+        "License :: OSI Approved :: Zope Public License",
+        "Framework :: Zope3",
+        "Programming Language :: Python",
+        "Operating System :: OS Independent",
+        "Topic :: Internet :: WWW/HTTP",
+        "Topic :: Software Development :: Libraries :: Python Modules",
+        ],
+      keywords='',
+      author='Malthe Borch',
+      author_email='mborch at gmail.com',
+      url='',
+      license='ZPL',
+      packages=find_packages(exclude=['ez_setup']),
+      namespace_packages=['z3c'],
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=[
+          'setuptools',
+          'zope.app.publisher',
+          'z3c.pt',
+          # -*- Extra requirements: -*-
+      ],
+      entry_points="""
+      # -*- Entry points: -*-
+      """,
+      )

Added: z3c.resourceinclude/trunk/z3c/__init__.py
===================================================================
--- z3c.resourceinclude/trunk/z3c/__init__.py	                        (rev 0)
+++ z3c.resourceinclude/trunk/z3c/__init__.py	2008-03-02 17:53:42 UTC (rev 84408)
@@ -0,0 +1,6 @@
+# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)

Added: z3c.resourceinclude/trunk/z3c/resourceinclude/README.txt
===================================================================
--- z3c.resourceinclude/trunk/z3c/resourceinclude/README.txt	                        (rev 0)
+++ z3c.resourceinclude/trunk/z3c/resourceinclude/README.txt	2008-03-02 17:53:42 UTC (rev 84408)
@@ -0,0 +1,147 @@
+z3c.resourceinclude
+-------------------
+
+This package provides functionality to define web-resources for
+inclusion in HTML documents.
+
+Registering resources
+---------------------
+
+Let's set up a browser resource.
+   
+   >>> from z3c.resourceinclude.testing import MockResourceFactory
+
+   >>> from zope import component
+   >>> from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+   >>> from zope.component.interfaces import IResource
+
+Let's register a couple of resources.
+   
+   >>> component.provideAdapter(
+   ...     MockResourceFactory('text/plain'),
+   ...     (IDefaultBrowserLayer,), IResource, name='1')
+
+   >>> component.provideAdapter(
+   ...     MockResourceFactory('text/plain'),
+   ...     (IDefaultBrowserLayer,), IResource, name='2')
+   
+We'll now instantiate a resource manager and register it as an adapter
+on the default browser layer.
+
+   >>> from z3c.resourceinclude.manager import ResourceManager
+   >>> from z3c.resourceinclude.interfaces import IResourceManager
+   
+   >>> manager = ResourceManager()
+   >>> component.provideAdapter(
+   ...     manager, (IDefaultBrowserLayer,), IResourceManager, name='A')
+
+Let's register the first resource for this layer by adding it to the
+manager we just registered.
+
+   >>> manager.add('1')
+
+Now we'll introduce another layer and register the second resource for
+it.
+
+   >>> class ISpecificLayer(IDefaultBrowserLayer):
+   ...     """A specific layer."""
+   
+   >>> manager = ResourceManager()
+   >>> component.provideAdapter(
+   ...     manager, (ISpecificLayer,), IResourceManager, name='B')
+
+   >>> manager.add('2')
+
+Collecting resources
+--------------------
+
+A resource collector is responsible for gathering resources that apply
+to the current browser request.
+
+   >>> from z3c.resourceinclude.collector import ResourceCollector
+   >>> from zope.publisher.browser import TestRequest
+
+   >>> request = TestRequest()
+   >>> collector = ResourceCollector(request)
+
+Let's ask the collector to gather resources available for this
+request.
+   
+   >>> collector.collect()
+   (<MockResource type="text/plain">,)
+
+Let's confirm that if we provide the specific layer on the request,
+that we'll get the other resource as well.
+
+   >>> from zope import interface
+   >>> interface.alsoProvides(request, ISpecificLayer)
+
+   >>> collector.collect()
+   (<MockResource type="text/plain">,
+    <MockResource type="text/plain">)
+    
+Resources are only included once.
+
+   >>> manager.add('1')
+    
+   >>> collector.collect()
+   (<MockResource type="text/plain">,
+    <MockResource type="text/plain">)
+   
+Resources are sorted by their content-type.
+
+   >>> component.provideAdapter(
+   ...     MockResourceFactory('text/x-web-markup'),
+   ...     (IDefaultBrowserLayer,), IResource, name='3')
+
+   >>> component.provideAdapter(
+   ...     MockResourceFactory('text/plain'),
+   ...     (IDefaultBrowserLayer,), IResource, name='4')
+
+   >>> manager.add('3')
+   >>> manager.add('4')
+
+   >>> collector.collect()
+   (<MockResource type="text/plain">,
+    <MockResource type="text/plain">,
+    <MockResource type="text/plain">,
+    <MockResource type="text/x-web-markup">)
+
+Including resources in an HTML document
+---------------------------------------
+
+Let's register a few browser resources:
+   
+   >>> component.provideAdapter(
+   ...     MockResourceFactory('text/css'),
+   ...     (IDefaultBrowserLayer,), IResource, name='base.css')
+
+   >>> component.provideAdapter(
+   ...     MockResourceFactory('application/x-javascript'),
+   ...     (IDefaultBrowserLayer,), IResource, name='base.js')
+
+   >>> component.provideAdapter(
+   ...     MockResourceFactory('text/kss'),
+   ...     (IDefaultBrowserLayer,), IResource, name='base.kss')
+
+   >>> manager.add('base.css')
+   >>> manager.add('base.js')
+   >>> manager.add('base.kss')
+
+Let's register the resource collector as a component.
+
+   >>> component.provideAdapter(ResourceCollector)
+   
+We can now render the resource includes.
+   
+   >>> from z3c.resourceinclude.provider import ResourceIncludeProvider
+   >>> provider = ResourceIncludeProvider(None, request, None)
+
+   >>> provider.update()
+   >>> print provider.render()
+   <script type="text/javascript" src="http://nohost/site/@@/mock">      
+   </script>
+   <style media="all" type="text/css">
+       @import url(http://nohost/site/@@/mock)
+   </style>
+   <link type="text/kss" rel="kinetic-stylesheet" href="http://nohost/site/@@/mock" />

Added: z3c.resourceinclude/trunk/z3c/resourceinclude/__init__.py
===================================================================
--- z3c.resourceinclude/trunk/z3c/resourceinclude/__init__.py	                        (rev 0)
+++ z3c.resourceinclude/trunk/z3c/resourceinclude/__init__.py	2008-03-02 17:53:42 UTC (rev 84408)
@@ -0,0 +1,19 @@
+import zope.interface
+import zope.security.management
+import zope.security.interfaces
+
+from zope.publisher.interfaces import IRequest
+
+def getRequest():
+    try:
+        i = zope.security.management.getInteraction() # raises NoInteraction
+    except zope.security.interfaces.NoInteraction:
+        return
+
+    for p in i.participations:
+        if IRequest.providedBy(p):
+            return p
+
+def provide(iface):
+    request = getRequest()
+    zope.interface.alsoProvides(request, iface)

Added: z3c.resourceinclude/trunk/z3c/resourceinclude/collector.py
===================================================================
--- z3c.resourceinclude/trunk/z3c/resourceinclude/collector.py	                        (rev 0)
+++ z3c.resourceinclude/trunk/z3c/resourceinclude/collector.py	2008-03-02 17:53:42 UTC (rev 84408)
@@ -0,0 +1,52 @@
+from zope import interface
+from zope import component
+
+from zope.publisher.interfaces.browser import IBrowserRequest
+
+from interfaces import IResourceCollector
+from interfaces import IResourceManager
+
+class ResourceCollector(object):
+    interface.implements(IResourceCollector)
+    component.adapts(IBrowserRequest)
+    
+    def __init__(self, request):
+        self.request = request
+
+    def collect(self):
+        resources = []
+        names = []
+        
+        for name, manager in self._get_managers():
+            items = manager.getResources(self.request)
+
+            # filter out duplicates
+            rs = [resource for name, resource in items if name not in names]
+            names.extend((name for name, resource in items)) 
+
+            # sort
+            self.sort(rs)
+
+            # merge
+            self.merge(rs)
+
+            resources.extend(rs)
+
+        return tuple(resources)
+
+    def sort(self, resources):
+        # order resources by content type
+        resources.sort(key=lambda resource: resource.context.content_type)
+        return resources
+
+    def merge(self, resources):
+        return resources
+
+    def _get_managers(self):
+        managers = [(name, manager) for name, manager in \
+                    component.getAdapters((self.request,), IResourceManager) if \
+                    manager.available()]
+        
+        managers.sort(key=lambda (name, manager): name)
+
+        return managers

Added: z3c.resourceinclude/trunk/z3c/resourceinclude/configure.zcml
===================================================================
--- z3c.resourceinclude/trunk/z3c/resourceinclude/configure.zcml	                        (rev 0)
+++ z3c.resourceinclude/trunk/z3c/resourceinclude/configure.zcml	2008-03-02 17:53:42 UTC (rev 84408)
@@ -0,0 +1,5 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <adapter factory=".collector.ResourceCollector" />
+  
+</configure>

Added: z3c.resourceinclude/trunk/z3c/resourceinclude/interfaces.py
===================================================================
--- z3c.resourceinclude/trunk/z3c/resourceinclude/interfaces.py	                        (rev 0)
+++ z3c.resourceinclude/trunk/z3c/resourceinclude/interfaces.py	2008-03-02 17:53:42 UTC (rev 84408)
@@ -0,0 +1,31 @@
+from zope import interface
+from zope import component
+
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+   
+class IResourceCollector(interface.Interface):
+    """A resource collector is responsible for gathering resources
+    that are available for it. It's usually instantiated with a
+    browser request."""
+    
+    def collect():
+        """Returns an ordered list of resources available for this collector."""
+
+    def sort(resources):
+        """Sort resources."""
+
+    def merge(resources):
+        """Merge resources."""
+        
+class IResourceManager(interface.Interface):
+    """A resource manager is a container for resource registrations."""
+
+    names = interface.Attribute(
+        """The names of the resources that are registered with this manager.""")
+
+    def add(name):
+        """Adds a resource to the manager."""
+
+    def available():
+        """Returns a boolean value whether this manager is available."""

Added: z3c.resourceinclude/trunk/z3c/resourceinclude/manager.py
===================================================================
--- z3c.resourceinclude/trunk/z3c/resourceinclude/manager.py	                        (rev 0)
+++ z3c.resourceinclude/trunk/z3c/resourceinclude/manager.py	2008-03-02 17:53:42 UTC (rev 84408)
@@ -0,0 +1,40 @@
+from zope import interface
+from zope import component
+
+from interfaces import IResourceManager
+
+class ResourceManager(object):
+    interface.implements(IResourceManager)
+    
+    def __init__(self):
+        self.names = []
+        
+    def __call__(self, request):
+        return self
+
+    def available(self):
+        return True
+
+    def add(self, name):
+        if name not in self.names:
+            self.names.append(name)
+
+    def getResources(self, request):
+        resources = []
+        
+        for name in self.names:
+            if '/' in name:
+                name, path = name.split('/', 1)
+            else:
+                path = None
+
+            resource = component.queryAdapter(
+                request, name=name)
+
+            if path is not None:
+                resource = resource[path]
+
+            resources.append((name, resource))
+
+        return resources
+

Added: z3c.resourceinclude/trunk/z3c/resourceinclude/meta.zcml
===================================================================
--- z3c.resourceinclude/trunk/z3c/resourceinclude/meta.zcml	                        (rev 0)
+++ z3c.resourceinclude/trunk/z3c/resourceinclude/meta.zcml	2008-03-02 17:53:42 UTC (rev 84408)
@@ -0,0 +1,15 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:meta="http://namespaces.zope.org/meta">
+  
+  <meta:directives namespace="http://namespaces.zope.org/browser">
+    
+    <meta:directive
+       name="resourceInclude"
+       schema=".zcml.IResourceIncludeDirective"
+       handler=".zcml.includeDirective"
+       />
+    
+  </meta:directives>
+
+</configure>

Added: z3c.resourceinclude/trunk/z3c/resourceinclude/provider.pt
===================================================================
--- z3c.resourceinclude/trunk/z3c/resourceinclude/provider.pt	                        (rev 0)
+++ z3c.resourceinclude/trunk/z3c/resourceinclude/provider.pt	2008-03-02 17:53:42 UTC (rev 84408)
@@ -0,0 +1,24 @@
+<div xmlns="http://www.w3.org/1999/xhtml"
+     xmlns:tal="http://xml.zope.org/namespaces/tal"
+     tal:omit-tag="">
+
+  <tal:resource repeat="resource resources">
+
+    <script type="text/javascript"
+	    tal:condition="resource.content_type == 'application/x-javascript'"
+	    tal:attributes="src resource.url">      
+    </script>
+
+    <style type="text/css" media="all"
+	   tal:condition="resource.content_type == 'text/css'">
+      ${comment('@import url("%s");' % resource.url)}
+    </style>
+	    
+    <link type="text/kss"
+	  rel="kinetic-stylesheet"
+	  tal:condition="resource.content_type == 'text/kss'"
+	  tal:attributes="href resource.url" />
+    
+  </tal:resource>
+
+</div>

Added: z3c.resourceinclude/trunk/z3c/resourceinclude/provider.py
===================================================================
--- z3c.resourceinclude/trunk/z3c/resourceinclude/provider.py	                        (rev 0)
+++ z3c.resourceinclude/trunk/z3c/resourceinclude/provider.py	2008-03-02 17:53:42 UTC (rev 84408)
@@ -0,0 +1,40 @@
+from zope import interface
+from zope import component
+
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.publisher.interfaces.browser import IBrowserView
+from zope.contentprovider.interfaces import IContentProvider
+
+from z3c.resourceinclude.interfaces import IResourceCollector
+from z3c.pt import PageTemplateFile
+
+def html_comment(u):
+    return u'<!-- %s -->' % u
+
+import mimetypes
+if not '.kss' in mimetypes.types_map:
+    mimetypes.add_type('text/kss', '.kss')
+
+def guess_mimetype(resource):
+    return resource.context.content_type
+    
+class ResourceIncludeProvider(object):
+    interface.implements(IContentProvider)
+    component.adapts(interface.Interface, IBrowserRequest, IBrowserView)
+
+    template = PageTemplateFile("provider.pt")
+
+    def __init__(self, context, request, view):
+        self.context = context
+        self.request = request
+        self.__parent__ = view
+
+    def update(self):
+        self.collector = IResourceCollector(self.request)
+
+    def render(self):
+        resources = [{'content_type': guess_mimetype(resource),
+                      'url': resource()} for \
+                     resource in self.collector.collect()]
+
+        return self.template(resources=resources, comment=html_comment)

Added: z3c.resourceinclude/trunk/z3c/resourceinclude/testing.py
===================================================================
--- z3c.resourceinclude/trunk/z3c/resourceinclude/testing.py	                        (rev 0)
+++ z3c.resourceinclude/trunk/z3c/resourceinclude/testing.py	2008-03-02 17:53:42 UTC (rev 84408)
@@ -0,0 +1,49 @@
+from zope import interface
+from zope import component
+
+from zope.app.component import hooks
+from zope.app.publisher.browser.resource import Resource
+from zope.traversing.browser.interfaces import IAbsoluteURL
+from zope.publisher.interfaces.browser import IBrowserRequest
+
+def setSite():
+    hooks.setHooks()
+    hooks.setSite(MockSite())
+   
+class MockSite(object):
+    def getSiteManager(self):
+        return component.getSiteManager()
+    
+class MockSiteURL(object):
+    interface.implements(IAbsoluteURL)
+    component.adapts(MockSite, IBrowserRequest)
+
+    def __init__(self, site, request):
+        pass
+
+    def __str__(self):
+        return 'http://nohost/site'
+
+class MockResourceContext(object):
+    def __init__(self, content_type):
+        self.content_type = content_type
+
+class MockResource(Resource):
+    __name__ = 'mock'
+    
+    def __init__(self, request, content_type):
+        self.context = MockResourceContext(content_type)
+        self.request = request
+        
+    def browserDefault(self, request):
+        return self, ()
+    
+    def __repr__(self):
+        return u'<MockResource type="%s">' % self.context.content_type
+
+class MockResourceFactory(object):
+    def __init__(self, content_type):
+        self.content_type = content_type
+
+    def __call__(self, request):
+        return MockResource(request, self.content_type)

Added: z3c.resourceinclude/trunk/z3c/resourceinclude/tests/__init__.py
===================================================================
--- z3c.resourceinclude/trunk/z3c/resourceinclude/tests/__init__.py	                        (rev 0)
+++ z3c.resourceinclude/trunk/z3c/resourceinclude/tests/__init__.py	2008-03-02 17:53:42 UTC (rev 84408)
@@ -0,0 +1 @@
+#

Added: z3c.resourceinclude/trunk/z3c/resourceinclude/tests/test_doctests.py
===================================================================
--- z3c.resourceinclude/trunk/z3c/resourceinclude/tests/test_doctests.py	                        (rev 0)
+++ z3c.resourceinclude/trunk/z3c/resourceinclude/tests/test_doctests.py	2008-03-02 17:53:42 UTC (rev 84408)
@@ -0,0 +1,30 @@
+import zope.testing
+import unittest
+
+OPTIONFLAGS = (zope.testing.doctest.ELLIPSIS |
+               zope.testing.doctest.NORMALIZE_WHITESPACE)
+
+import zope.component
+import zope.component.testing
+
+import z3c.resourceinclude.testing
+
+def setUp(suite):
+    zope.component.testing.setUp(suite)
+    z3c.resourceinclude.testing.setSite()
+    zope.component.provideAdapter(z3c.resourceinclude.testing.MockSiteURL)
+
+def test_suite():
+    doctests = ('README.txt', 'zcml.txt')
+
+    return unittest.TestSuite(
+        [zope.testing.doctest.DocFileSuite(
+                doctest,
+                optionflags=OPTIONFLAGS,
+                setUp=setUp,
+                tearDown=zope.component.testing.tearDown,
+                package="z3c.resourceinclude") for doctest in doctests]
+        )
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Added: z3c.resourceinclude/trunk/z3c/resourceinclude/zcml.py
===================================================================
--- z3c.resourceinclude/trunk/z3c/resourceinclude/zcml.py	                        (rev 0)
+++ z3c.resourceinclude/trunk/z3c/resourceinclude/zcml.py	2008-03-02 17:53:42 UTC (rev 84408)
@@ -0,0 +1,64 @@
+from zope import interface
+from zope import component
+
+from zope.app.component.back35 import LayerField
+from zope.configuration.fields import Tokens, GlobalObject
+from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.schema import TextLine
+
+from manager import ResourceManager
+from interfaces import IResourceManager
+
+counter = 0
+
+class IResourceIncludeDirective(interface.Interface):
+    include = Tokens(
+        title=u"Files to include",
+        description=u"The files containing the resource data.",
+        required=True,
+        value_type=TextLine())
+
+    base = TextLine(
+        title=u"Base path for includes",
+        required=False)
+    
+    layer = LayerField(
+        title=u"The layer the resource should be found in",
+        description=u"""
+        For information on layers, see the documentation for the skin
+        directive. Defaults to "default".""",
+        required=False
+        )
+
+    manager = GlobalObject(
+        title=u"Include manager",
+        required=False)
+       
+def includeDirective(_context, include, base=u"", layer=IDefaultBrowserLayer, manager=None):
+    if base:
+        include = [base+'/'+name for name in include]
+        
+    _context.action(
+        discriminator = ('resourceInclude', IBrowserRequest, layer),
+        callable = handler,
+        args = (include, layer, manager, _context.info),
+        )
+
+def handler(include, layer, manager, info):
+    """Set up includes."""
+
+    global counter
+    
+    if manager is None:
+        manager = component.queryAdapter(layer, IResourceManager)
+
+        if manager is None:
+            manager = ResourceManager()
+            name = str(counter).rjust(3, '0') + ':' + layer.__module__ + '.' + layer.__name__
+            counter += 1
+            component.provideAdapter(
+                manager, (layer,), IResourceManager, name=name)
+
+    for path in include:
+        manager.add(path)

Added: z3c.resourceinclude/trunk/z3c/resourceinclude/zcml.txt
===================================================================
--- z3c.resourceinclude/trunk/z3c/resourceinclude/zcml.txt	                        (rev 0)
+++ z3c.resourceinclude/trunk/z3c/resourceinclude/zcml.txt	2008-03-02 17:53:42 UTC (rev 84408)
@@ -0,0 +1,31 @@
+ZCML configuration
+------------------
+
+    >>> from zope.configuration.xmlconfig import xmlconfig, XMLConfig
+    >>> from StringIO import StringIO
+
+    >>> import z3c.resourceinclude
+    >>> XMLConfig('meta.zcml', z3c.resourceinclude)()
+    
+    >>> template = """<configure
+    ... xmlns='http://namespaces.zope.org/zope'
+    ... xmlns:browser='http://namespaces.zope.org/browser'
+    ... i18n_domain='zope'>
+    ... %s
+    ... </configure>"""
+
+    >>> xmlconfig(StringIO(template % ('''\
+    ... <browser:resourceInclude
+    ...    layer="zope.publisher.interfaces.browser.IDefaultBrowserLayer"
+    ...    include="test1 test2"
+    ... />''')))
+
+    >>> from zope import component
+    >>> from z3c.resourceinclude.interfaces import IResourceManager
+    >>> from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+    
+    >>> name, manager = component.getSiteManager().adapters.lookupAll(
+    ...     (IDefaultBrowserLayer,), IResourceManager)[0]
+
+    >>> manager.names
+    [u'test1', u'test2']



More information about the Checkins mailing list