Skip to content

Commit

Permalink
100% coverage; minor whitespace cleanup
Browse files Browse the repository at this point in the history
Fixes #5
  • Loading branch information
jamadden committed Aug 25, 2017
1 parent d14a6d2 commit de3f69b
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 75 deletions.
31 changes: 16 additions & 15 deletions src/zope/viewlet/README.rst
@@ -1,5 +1,6 @@
Viewlets and Viewlet Managers
=============================
===============================
Viewlets and Viewlet Managers
===============================

Let's start with some motivation. Using content providers allows us to insert
one piece of HTML content. In most Web development, however, you are often
Expand All @@ -10,7 +11,7 @@ register content for those regions.


Design Notes
------------
============

As mentioned above, besides inserting snippets of HTML at places, we more
frequently want to define a region in our page and allow specialized content
Expand All @@ -31,7 +32,7 @@ framework for building pluggable user interfaces.


The Viewlet Manager
-------------------
===================

In this implementation of viewlets, those regions are just content providers
called viewlet managers that manage a special type of content providers known
Expand Down Expand Up @@ -210,7 +211,7 @@ If the viewlet is not found, then the expected behavior is provided:
True

Customizing the default Viewlet Manager
---------------------------------------
=======================================

One important feature of any viewlet manager is to be able to filter and sort
the viewlets it is displaying. The default viewlet manager that we have been
Expand Down Expand Up @@ -276,7 +277,7 @@ Of course, we also can remove a shown viewlet:


WeightOrderedViewletManager
---------------------------
===========================

The weight ordered viewlet manager offers ordering viewlets by a additional
weight argument. Viewlets which doesn't provide a weight attribute will get
Expand Down Expand Up @@ -377,7 +378,7 @@ And check the order:


ConditionalViewletManager
-------------------------
=========================

The conditional ordered viewlet manager offers ordering viewlets by a
additional weight argument and filters by the available attribute if a
Expand Down Expand Up @@ -485,7 +486,7 @@ And check the order:


Viewlet Base Classes
--------------------
====================

To make the creation of viewlets simpler, a set of useful base classes and
helper functions are provided.
Expand Down Expand Up @@ -691,10 +692,10 @@ There is also a bundle viewlet for CSS links:


A Complex Example
-----------------
=================

The Data
~~~~~~~~
--------

So far we have only demonstrated simple (maybe overly trivial) use cases of
the viewlet system. In the following example, we are going to develop a
Expand Down Expand Up @@ -744,7 +745,7 @@ Here is some sample data:


The View
~~~~~~~~
--------

The contents view of the container should iterate through the container and
represent the files in a table:
Expand All @@ -765,7 +766,7 @@ represent the files in a table:


The Viewlet Manager
~~~~~~~~~~~~~~~~~~~
-------------------

Now we have to write our own viewlet manager. In this case we cannot use the
default implementation, since the viewlets will be looked up for each
Expand Down Expand Up @@ -845,7 +846,7 @@ Since we have not defined any viewlets yet, the table is totally empty:


The Viewlets and the Final Result
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---------------------------------

Now let's create a first viewlet for the manager...

Expand Down Expand Up @@ -1025,7 +1026,7 @@ the result will be


Supporting Sorting
~~~~~~~~~~~~~~~~~~
------------------

Oftentimes you also want to batch and sort the entries in a table. Since those
two features are not part of the view logic, they should be treated with
Expand Down Expand Up @@ -1209,7 +1210,7 @@ room for extending this example:


Cleanup
-------
=======

>>> import shutil
>>> shutil.rmtree(temp_dir)
59 changes: 53 additions & 6 deletions src/zope/viewlet/directives.rst
@@ -1,8 +1,9 @@
Viewlet-related ZCML Directives
===============================
=================================
Viewlet-related ZCML Directives
=================================

The ``viewletManager`` Directive
--------------------------------
================================

The ``viewletManager`` directive allows you to quickly register a new viewlet
manager without worrying about the details of the ``adapter``
Expand Down Expand Up @@ -192,7 +193,7 @@ Finally, if a non-existent template is specified, an error is raised:


The ``viewlet`` Directive
-------------------------
=========================

Now that we have a viewlet manager, we have to register some viewlets for
it. The ``viewlet`` directive is similar to the ``viewletManager`` directive,
Expand Down Expand Up @@ -313,6 +314,32 @@ be rendered upon calling the viewlet:
>>> viewlet.render()
u'SRC $5.19'

If the class mentions that it implements any interfaces using the
old-fashioned style, the resulting viewlet will
implement ``IBrowserPublisher``:

>>> from zope.publisher.interfaces.browser import IBrowserPublisher
>>> from zope.interface import classImplements
>>> Stock.__implements__ = ()
>>> context = xmlconfig.string('''
... <configure xmlns="http://namespaces.zope.org/browser" i18n_domain="zope">
... <viewlet
... name="stock"
... for="*"
... manager="zope.viewlet.directives.ILeftColumn"
... class="zope.viewlet.directives.Stock"
... attribute="getStockTicker"
... permission="zope.Public"
... />
... </configure>
... ''', context=context)

>>> viewlet = zope.component.getMultiAdapter(
... (content, request, view, manager), interfaces.IViewlet,
... name='stock')
>>> IBrowserPublisher.providedBy(viewlet)
True

A final feature the ``viewlet`` directive is that it supports the
specification of any number of keyword arguments:

Expand All @@ -335,7 +362,7 @@ specification of any number of keyword arguments:


Error Scenarios
~~~~~~~~~~~~~~~
---------------

Neither the class or template have been specified:

Expand Down Expand Up @@ -392,8 +419,28 @@ specified attribute:
ConfigurationError: The provided class doesn't have the specified attribute


Now for a template that doesn't exist:

>>> context = xmlconfig.string('''
... <configure xmlns="http://namespaces.zope.org/browser" i18n_domain="zope">
... <viewlet
... name="weather2"
... for="*"
... manager="zope.viewlet.directives.ILeftColumn"
... template="this template is not here"
... class="zope.viewlet.directives.Weather"
... permission="zope.Public"
... />
... </configure>
... ''', context=context)
Traceback (most recent call last):
...
ZopeXMLConfigurationError: File "<string>", line 3.2-10.8
ConfigurationError: ('No such file', '...this template is not here')


Cleanup
~~~~~~~
-------

>>> import shutil
>>> shutil.rmtree(temp_dir)
24 changes: 11 additions & 13 deletions src/zope/viewlet/manager.py
Expand Up @@ -32,6 +32,7 @@ class ViewletManagerBase(object):
A generic manager class which can be instantiated
"""
template = None
viewlets = None

def __init__(self, context, request, view):
self.__updated = False
Expand All @@ -49,14 +50,14 @@ def __getitem__(self, name):
# If the viewlet was not found, then raise a lookup error
if viewlet is None:
raise zope.component.interfaces.ComponentLookupError(
'No provider with name `%s` found.' %name)
'No provider with name `%s` found.' % name)

# If the viewlet cannot be accessed, then raise an
# unauthorized error
if not zope.security.canAccess(viewlet, 'render'):
raise zope.security.interfaces.Unauthorized(
'You are not authorized to access the provider '
'called `%s`.' %name)
'called `%s`.' % name)

# Return the viewlet.
return viewlet
Expand Down Expand Up @@ -102,7 +103,7 @@ def update(self):
viewlets = self.filter(viewlets)
viewlets = self.sort(viewlets)
# Just use the viewlets from now on
self.viewlets=[]
self.viewlets = []
for name, viewlet in viewlets:
if ILocation.providedBy(viewlet):
viewlet.__name__ = name
Expand All @@ -120,8 +121,7 @@ def render(self):
# Now render the view
if self.template:
return self.template(viewlets=self.viewlets)
else:
return u'\n'.join([viewlet.render() for viewlet in self.viewlets])
return u'\n'.join([viewlet.render() for viewlet in self.viewlets])


def ViewletManager(name, interface, template=None, bases=()):
Expand All @@ -137,14 +137,14 @@ def ViewletManager(name, interface, template=None, bases=()):
interfaces.IViewletManager.implementedBy(bases[0])):
bases = bases + (ViewletManagerBase,)

ViewletManager = type(
ViewletManagerCls = type(
'<ViewletManager providing %s>' % interface.getName(), bases, attrDict)
zope.interface.classImplements(ViewletManager, interface)
return ViewletManager
zope.interface.classImplements(ViewletManagerCls, interface)
return ViewletManagerCls


def getWeight(item):
name, viewlet = item
_name, viewlet = item
try:
return int(viewlet.weight)
except AttributeError:
Expand All @@ -162,10 +162,9 @@ def render(self):
# do not render a manager template if no viewlets are avaiable
if not self.viewlets:
return u''
elif self.template:
if self.template:
return self.template(viewlets=self.viewlets)
else:
return u'\n'.join([viewlet.render() for viewlet in self.viewlets])
return u'\n'.join([viewlet.render() for viewlet in self.viewlets])


def isAvailable(viewlet):
Expand All @@ -185,4 +184,3 @@ def filter(self, viewlets):
"""
return [(name, viewlet) for name, viewlet in viewlets
if isAvailable(viewlet)]

0 comments on commit de3f69b

Please sign in to comment.