[Checkins] SVN: grokcore.errorview/trunk/ arrange package
Jan-Wijbrand Kolman
janwijbrand at gmail.com
Wed Jan 19 10:15:16 EST 2011
Log message for revision 119713:
arrange package
Changed:
U grokcore.errorview/trunk/CHANGES.txt
U grokcore.errorview/trunk/README.txt
U grokcore.errorview/trunk/buildout.cfg
U grokcore.errorview/trunk/setup.py
A grokcore.errorview/trunk/src/grokcore/errorview/
D grokcore.errorview/trunk/src/grokcore/errorview/directive.py
D grokcore.errorview/trunk/src/grokcore/errorview/ftests/
D grokcore.errorview/trunk/src/grokcore/errorview/interfaces.py
D grokcore.errorview/trunk/src/grokcore/errorview/meta-minimal.zcml
D grokcore.errorview/trunk/src/grokcore/errorview/meta.zcml
D grokcore.errorview/trunk/src/grokcore/errorview/publication.py
D grokcore.errorview/trunk/src/grokcore/errorview/publication_security.zcml
D grokcore.errorview/trunk/src/grokcore/errorview/templatereg.py
D grokcore.errorview/trunk/src/grokcore/errorview/templatereg.txt
D grokcore.errorview/trunk/src/grokcore/errorview/testing.py
D grokcore.errorview/trunk/src/grokcore/errorview/util.py
D grokcore.errorview/trunk/src/grokcore/view/
-=-
Modified: grokcore.errorview/trunk/CHANGES.txt
===================================================================
--- grokcore.errorview/trunk/CHANGES.txt 2011-01-19 15:02:11 UTC (rev 119712)
+++ grokcore.errorview/trunk/CHANGES.txt 2011-01-19 15:15:15 UTC (rev 119713)
@@ -1,227 +1,7 @@
Changes
=======
-2.4 (unreleased)
+1.0 (unreleased)
----------------
-- Nothing changed yet.
-
-
-2.3 (2011-01-04)
-----------------
-
-- Removed the static directory grokker in order to make way for using
- fanstatic.
-
-
-2.2 (2010-12-16)
-----------------
-
-- Factor out a base template grokker that associate templates for
- viewish components.
-
-- Merge support for a global template registry that removes
- unnecessary warnings about unassociated templates in "shared"
- template directories.
-
-2.1 (2010-11-03)
-----------------
-
-- Use an update martian and grokcore.component.
-
-- The custom zope publication has now moved from the grok package to
- grokcore.view. The registration of the publication is optional, and is used
- by grok and the grokcore.json package.
-
-- The util function `make_checker` has been moved from the `grok`
- package to ``grokcore.view``.
-
-2.0 (2010-11-01)
-----------------
-
-- The `view` directive has been moved from ``grokcore.viewlet`` to
- ``grokcore.view``.
-
-- The `IGrokSecurityView` has been moved from ``grok`` to
- ``grokcore.view``.
-
-- Fix the url() function to behave properly while passed an empty data dict.
-
-- Fix the url() method to accept the "status" and "trusted" arguments, passed
- on to the redirect method on the response object.
-
-- ``grokcore.view`` no longer depends on ``zope.app.testing`` and
- related packages. Instead we now use ``zope.app.wsgi.testlayer`` to
- run functional tests.
-
-- Made package comply to zope.org repository policy.
-
-- Fixed launchpad bug #395061 : removed the default_fallback_to_name
- function. It can be imported from ``grokcore.security`` if needed.
-
-- ``grokcore.view`` no longer depends on ``zope.app.zcmlfiles``. We
- removed all the extra dependencies and fixed one test that used
- ``zope.app.rotterdam`` and ``zope.app.basicskin``.
-
-- Back-ported the changes of the 1.13 branch related to the directory
- resource registration, using the latest ztk packages.
-
-- Factor out generally useful methods and properties for view-ish
- components into components.ViewSupport mixin.
-
-- Works with new Martian (0.13) and grokcore.component 2.1.
-
-- Test fix: support windows paths.
-
-- Warnings are now emitted as log messages with level
- `logging.WARNING` to a logger named ``grokcore.view`` with level
- `logging.ERROR`.
-
- That means that by default no warnings are emitted anymore (while
- errors will still appear).
-
- To get the warnings back, reduce the level of logger
- ``grokcore.view`` to `logging.WARNING` or lower. This can be done in
- Python or via a logging conf file, for instance in the .ini files of
- regular grokprojects. See the Python standard lib `logging` module
- for details.
-
-1.12.1 (2009-09-17)
--------------------
-
-- A compatibility fix to support ``grokcore.viewlet``.
-
-1.12 (2009-09-17)
------------------
-
-- Use 1.0b1 versions.cfg in Grok's release info instead of a local
- copy; a local copy for all grokcore packages is just too hard to
- maintain.
-
-- Revert the splitting CodeView/View. The original reasons for the
- split have been obsoleted by the recent martain developments
- regarding inheritted module level directives. At the same time the
- split up components proved cumbersome to use and a too big a change
- between the 1.0a and 1.0b releases of Grok.
-
- View components will now again behave like it did up until the latest alpha
- release of Grok.
-
- ``CodeView`` is still available as a backwards compatibility alias
- for ``View``. Please update all references to ``CodeView`` to
- ``View``.
-
-- Fix the template registry and grokker for views to let View and
- other components using View as base class to be associated with a
- template directly by setting it as 'template' attribute on the view
- class. Example::
-
- class MyView(grokcore.view.View):
-
- template = grokcore.view.PageTemplate('<p>hello</p>')
-
- This isn't exactly *officially* supported but enough people depend
- on it and have documented it so that we don't want to just break it.
-
-1.11 (2009-09-15)
------------------
-
-- The response attribute needs to be available in CodeView as well.
-
-1.10 (2009-09-14)
------------------
-
-- Up the version requirement for grokcore.security to 1.2.
-
-- Bring versions.cfg in line with current grok versions.cfg.
-
-
-1.9 (2009-07-04)
-----------------
-
-- Fix needed for grokcore.formlib: allow a base_method'ed render() on view.
- This allows grokcore.formlib to have a render() in addition to a template.
-
-- Reverted change to checkTemplates: for some formlib edge cases it detects
- the right templates again.
-
-
-1.8 (2009-07-04)
-----------------
-
-- Add validator to templatedir directive to disallow path separator.
-
-- Splitted CodeView out of View. View only uses templates, CodeView only uses
- a render() method. So views that have a render method must subclass from
- CodeView instead of View (that should be the only change needed).
-
-- Add grok.View permissions to functional tests (requires grokcore.security 1.1)
-
-
-1.7 (2009-05-19)
-----------------
-
-- Revert dependency from zope.container back to zope.app.container.
-
-
-1.6 (2009-04-28)
-----------------
-
-- Simplify the DirectoryResource and DirectoryResourceFactory
- implementations by making better use of the hook points provided by
- zope.app.publisher.browser.directoryresource.
-
-1.5 (2009-04-10)
-----------------
-
-- Don't register a 'static' resource directory if the 'static' directory does
- not exist.
-
-- Make it possible to instantiate an ungrokked view by being slightly more
- defensive in __init__. This makes it easier to write unit tests.
-
-1.4 (2009-04-08)
-----------------
-
-* Page template reloading now also works for macros. Fixes
- https://bugs.launchpad.net/grok/+bug/162261.
-
-* Use zope.container instead of zope.app.container.
-
-* Ignore '<tpl>.cache' files when looking up template files in a
- template dir. Fix bug https://bugs.launchpad.net/grok/+bug/332747
-
-1.3 (2009-01-28)
-----------------
-
-* Adapt tests to work also from eggs not only source checkouts by
- avoiding `src` in directory comparisons.
-
-* Fix the factory for subdirectories of the DirectoryResource implementation
- by using hooks in zope.app.publisher.browser.directoryresource.
-
-* Update APIs interfaces to include the new ``path`` directive and
- new ``DirectoryResource`` component.
-
-1.2 (2008-10-16)
-----------------
-
-* Expose the ``DirectoryResource`` class as a component for registering
- directories as resources. This is accompanied by the ``path`` directive that
- is used to point to the directory holding resources by way of an relative (to
- the module) or absolute path. ``DirectoryResource`` components can be
- differentiated by name and layer.
-
-1.1 (2008-09-22)
-----------------
-
-* ``meta.py`` module containing the grokkers has been split in a
- package with separate modules for the view, template, skin and
- static resources grokkers. This allows applications to use only
- grokkers they need (and maybe redefine others).
-
-1.0 (2006-08-07)
-----------------
-
-* Created ``grokcore.view`` in July 2008 by factoring security-related
- components, grokkers and directives out of Grok.
+- Initial release
\ No newline at end of file
Modified: grokcore.errorview/trunk/README.txt
===================================================================
--- grokcore.errorview/trunk/README.txt 2011-01-19 15:02:11 UTC (rev 119712)
+++ grokcore.errorview/trunk/README.txt 2011-01-19 15:15:15 UTC (rev 119713)
@@ -1,313 +1,5 @@
-This package provides support for writing browser pages for Zope
-and registering them directly in Python (without ZCML).
+==================
+grokcore.errorview
+==================
-.. contents::
-
-Setting up ``grokcore.view``
-============================
-
-This package is essentially set up like the `grokcore.component`_
-package, please refer to its documentation for details. The
-additional ZCML line you will need is::
-
- <include package="grokcore.view" file="meta.zcml" />
- <include package="grokcore.view" />
-
-Put the first line somewhere near the top of your root ZCML file (but
-below the line where you include ``grokcore.component``'s
-configuration) and the second line somewhere next to your other
-dependency includes.
-
-
-Examples
-========
-
-Simple browser page
--------------------
-
-A browser page is implemented by subclassing the
-``grokcore.view.View`` baseclass. At a minimum, a browser page must
-have
-
-1. an associated template (or implement the ``render`` method for direct
- control)
-
-2. a context that it's registered for as a view
-
-3. a name (which is, if not specified explicitly, the class's name in
- lower case characters).
-
-A browser page that does not use a template but just outputs some
-computed data also subclasses the ``grokcore.view.View`` baseclass.
-At a minimum, such a view must have
-
-1. a render() method
-
-2. a context that it's registered for as a view
-
-3. a name (which is, if not specified explicitly, the class's name in
- lower case characters).
-
-For example, the following class defines a view that's registered for
-all objects and simply prints "Hello World!"::
-
- import grokcore.view
- import zope.interface
-
- class Hello(grokcore.view.View):
- grokcore.view.context(zope.interface.Interface)
-
- def render(self):
- self.response.setHeader("Content-Type", "text/plain")
- return "Hello World!"
-
-Here we've made use of the implicit name feature. This class will be
-available as the ``hello`` view for all objects. So for instance,
-you'll be able to invoke it with URLs like::
-
- http://localhost/some/obj/hello
-
-We could also have spelled this out explicitly::
-
- class Hello(grokcore.view.View):
- grokcore.view.context(zope.interface.Interface)
- grokcore.view.name('hello')
-
- ...
-
-Browser page with template
---------------------------
-
-Of course, more than often a view should render HTML which you would
-construct using some sort of templating engine. ``grokcore.view``
-comes with built-in support for Zope's PageTemplate engine. By
-convention, PageTemplate templates end with the ``.pt`` extension.
-
-So let our ``Hello`` view render HTML instead of plain text, we remove
-the ``render()`` method from the class and instead we create a
-template, e.g. like so::
-
- <html>
- <body>
- <p>Hello <span tal:replace="request/principal/title" />!</p>
- </body>
- </html>
-
-This will greet a logged in user with his or her actual name.
-
-Such a template-using page is a subclass of ``grokcore.view.View``.
-
- import grokcore.view
- import zope.interface
-
- class Hello(grokcore.view.View):
- grokcore.view.context(zope.interface.Interface)
-
-
-To associate the template with the view, we have to put it in a
-certain place. Let's say the ``Hello`` view class from above was in
-an ``app.py`` module. Then we create an ``app_templates`` directory
-next to it and place the template file in there (the name of this
-directory can be customized with the ``templatedir`` directive, see
-below). The file name can be anything as long as the extension is
-``.pt``. However, we can again make use of a convention here. If we
-name the template like the class (except in lower case characters),
-then the template and the class are associated automatically. If not,
-we would have to use the ``template`` directive on the view class to
-spell out the name of the template file explicitly.
-
-To cut a long story short, if we named it ``app_templates/hello.pt``,
-it would be found automatically.
-
-Static resources
-----------------
-
-Browser pages often need additional static resources like CSS and JavaScript
-files. These can be conveniently placed into a directory called ``static`` in
-the package that contains the view code. When this directory exists it will
-automatically be registered as a resource directory. It then is available as
-the ``static`` variable in all views of this package and you can refer to files
-inside this directory like so::
-
- <img src="hello.png" tal:attributes="src static/hello.png" />
-
-DirectoryResource
------------------
-
-In addition to the very convenient "static resources", one can use more
-explicitly configured and flexible DirectoryResource components.
-DirectoryResource component allow for differentiating resources based on layers
-and names and provide a way to register resources in one package and make use
-of these resources in another package's views::
-
- class FooResource(grokcore.view.DirectoryResource):
- grokcore.view.path('foo')
-
-Or with an explicit name::
-
- class BarResource(grokcore.view.DirectoryResource):
- grokcore.view.name('bar')
- grokcore.view.path('bar')
-
-Registered for a layer::
-
- class BazResource(grokcore.view.DirectoryResource):
- grokcore.view.layer(ISomeLayer)
- grokcore.view.path('baz/qux')
-
-Layers and skins
-----------------
-
-To define a browser layer, simply extend the ``IBrowserRequest``
-interface::
-
- class IGreenLayer(grokcore.view.IBrowserRequest):
- pass
-
-If you then wanted to define a skin, simply inherit from all the layer
-interfaces that should be in the skin and use the ``skin()`` directive
-to give the layer a name::
-
- class IGreenSkin(IGreenLayer, grokcore.view.IDefaultBrowserLayer):
- grokcore.view.skin('Green')
-
-To place a view on a layer, simply use the ``layer`` directive::
-
- class Hello(grokcore.view.View):
- grokcore.view.context(zope.interface.Interface)
- grokcore.view.layer(IGreenLayer)
-
- ...
-
-
-API overview
-============
-
-Base classes
-------------
-
-``View``
- Base class for browser pages. Use the ``context`` directive to
- specify the view's context. Use the ``name`` directive to set the
- view's name; if not used, the view's name will be the class's name
- in lower case characters. You may also use the ``template``
- directive to specify the name of the template file that should be
- associated with the view as well as the ``layer`` directive to
- specify which layer it should be on if not the default layer.
- Implement the ``render`` method to forgo looking up a template
- and show the result of calling the render method instead.
-
-View API
---------
-
-``grokcore.view.View`` is a regular Zope browser page, so it behaves
-exactly like a regular browser page from the outside. It provides a
-bit more to the developer using it as a base class, though:
-
-``context``
- The view's context object. This can be discriminated by using the
- ``context`` directive on the view class.
-
-``request``
- The request object, typically provides ``IBrowserRequest``.
-
-``response``
- The response object, typically provides ``IHTTPResponse``.
-
-``static``
- Directory resource representing the package's ``static`` directory or None
- if no such directory was found during grokking.
-
-``redirect(url)``
- Redirect to the given URL.
-
-``url(obj=None, name=None, data=None)``
- Constructs a URL:
-
- * If no arguments are given, the URL to the view itself is
- constructed.
-
- * If only the ``obj`` argument is given, the URL to that object is
- constructed.
-
- * If both ``obj`` and ``name`` arguments are supplied, construct
- the URL to the object and append ``name`` (presumably the name
- of a view).
-
- Optionally, ``data`` can be a dictionary whose contents is added to
- the URL as a query string.
-
-Method for developers to implement:
-
-``update(**kw)``
- This method will be called before the view's associated template
- is rendered. If you therefore want to pre-compuate values for the
- template, implement this method. You can save the values on
- ``self`` (the view object) and later access them through the
- ``view`` variable from the template. The method can take
- arbitrary keyword parameters which are filled from request values.
-
-``render(**kw)``
- Return either an encoded 8-bit string or a unicode string. The method can
- take arbitrary keyword parameters which are filled from request values.
- If not implemented, a template is looked up in the template dir instead.
-
-
-Directives
-----------
-
-``templatedir(dirname)``
- Module-level directive that tells the template machinery which
- directory to look in for templates that should associated with
- views in a particular module. If not used, it defaults to
- ``<module_name>_templates``.
-
-``template(filename_wo_ext)``
- Class-level directive that specifies the name a template file
- that's associated with a view class, *without* the file extension.
- If not used, it defaults to the class's name in lower case
- characters.
-
-``layer(layer_interface)``
- Class-level directive that defines which layer the view is
- registered on. If not used, it defaults to the
- ``IDefaultBrowserLayer``.
-
-``skin(skin_name)``
- Directive used on a layer interface to register it as skin using a
- human-readable name (``skin_name``).
-
-``path(relative_or_absolute_path)``
- Directove used in a DirectoryResource registration to point to a non-
- package directory(hierarchy) containing resources like images, css files,
- etc.
-
-Other
------
-
-``url(request, obj, name=None, data=None)``
- Generate the URL to an object, with an optional view name
- attached. The ``data`` argument can be a dictionary whose
- contents is converted into the a query string that's appended to
- the URL.
-
-``PageTemplate(template_code)``
- Create an inline PageTemplate object.
-
-``PageTemplateFile(filename)``
- Create a PageTemplate object from a file.
-
-``IBrowserRequest``
- Browser request interface from ``zope.publisher``.
-
-``IDefaultBrowserLayer``
- Default layer for browser components from ``zope.publisher``.
-
-
-In addition, the ``grokcore.view`` package exposes the
-`grokcore.component`_ and `grokcore.security`_ APIs.
-
-.. _grokcore.component: http://pypi.python.org/pypi/grokcore.component
-.. _grokcore.security: http://pypi.python.org/pypi/grokcore.security
-.. _grokcore.view: http://pypi.python.org/pypi/grokcore.view
-
+....
\ No newline at end of file
Modified: grokcore.errorview/trunk/buildout.cfg
===================================================================
--- grokcore.errorview/trunk/buildout.cfg 2011-01-19 15:02:11 UTC (rev 119712)
+++ grokcore.errorview/trunk/buildout.cfg 2011-01-19 15:15:15 UTC (rev 119713)
@@ -2,23 +2,22 @@
develop = .
extends = http://svn.zope.org/repos/main/groktoolkit/trunk/grok.cfg
parts =
- interpreter
- test
+ interpreter
+ test
versions = versions
extensions = buildout.dumppickedversions
-
[versions]
-grokcore.view =
+grokcore.errorview =
[interpreter]
recipe = zc.recipe.egg
-eggs = grokcore.view
+eggs = grokcore.errorview
interpreter = python
-
[test]
recipe = zc.recipe.testrunner
-eggs = grokcore.view
- grokcore.view[test]
-defaults = ['--tests-pattern', '^f?tests$', '-v']
+eggs =
+ grokcore.errorview
+ grokcore.view[test]
+defaults = ['--auto-color']
Modified: grokcore.errorview/trunk/setup.py
===================================================================
--- grokcore.errorview/trunk/setup.py 2011-01-19 15:02:11 UTC (rev 119712)
+++ grokcore.errorview/trunk/setup.py 2011-01-19 15:15:15 UTC (rev 119713)
@@ -12,55 +12,31 @@
install_requires = [
'setuptools',
- 'grokcore.component >= 2.1',
- 'grokcore.security >= 1.5',
- 'martian >= 0.13',
- 'zope.browserresource >= 3.9.0',
- 'zope.component',
- 'zope.interface',
- 'zope.pagetemplate',
- 'zope.ptresource >= 3.9.0',
- 'zope.publisher',
- 'zope.security',
- 'zope.traversing',
+ 'grokcore.view',
+ 'zope.errorview [browser]',
]
tests_require = [
- 'zope.app.wsgi',
- 'zope.container',
- 'zope.securitypolicy',
- 'zope.site',
- 'zope.testing',
- 'zope.login',
- 'zope.configuration',
- 'zope.app.appsetup',
- 'zope.app.publication',
- 'zope.browserpage',
- 'zope.password',
- 'zope.principalregistry',
+ 'zope.errorview [test]',
]
-publication_require = [
- 'zope.app.publication'
- ]
-
setup(
- name='grokcore.view',
- version='2.4dev',
+ name='grokcore.errorview',
+ version='1.0dev',
author='Grok Team',
author_email='grok-dev at zope.org',
url='http://grok.zope.org',
download_url='http://pypi.python.org/pypi/grok/',
- description='Grok-like configuration for Zope browser pages',
+ description='Grok-like baseclasses for exception views',
long_description=long_description,
license='ZPL',
- classifiers=['Environment :: Web Environment',
- 'Intended Audience :: Developers',
- 'License :: OSI Approved :: Zope Public License',
- 'Programming Language :: Python',
- 'Framework :: Zope3',
- ],
-
+ classifiers=[
+ 'Environment :: Web Environment',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: Zope Public License',
+ 'Programming Language :: Python',
+ 'Framework :: Zope3',
+ ],
packages=find_packages('src'),
package_dir = {'': 'src'},
namespace_packages=['grokcore'],
@@ -68,6 +44,7 @@
zip_safe=False,
install_requires=install_requires,
tests_require=tests_require,
- extras_require={'test': tests_require,
- 'security_publication': publication_require},
+ extras_require={
+ 'test': tests_require,
+ },
)
Deleted: grokcore.errorview/trunk/src/grokcore/errorview/directive.py
===================================================================
--- grokcore.errorview/trunk/src/grokcore/view/directive.py 2011-01-19 14:51:01 UTC (rev 119710)
+++ grokcore.errorview/trunk/src/grokcore/errorview/directive.py 2011-01-19 15:15:15 UTC (rev 119713)
@@ -1,98 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006-2007 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Grok directives.
-"""
-import os.path
-
-import martian
-from martian.error import GrokImportError
-from martian.directive import StoreOnce
-from zope.interface.interface import TAGGED_DATA
-from zope.publisher.interfaces.browser import IBrowserView
-
-
-def validateLocalPath(directive, value):
- martian.validateText(directive, value)
- if os.path.sep in value:
- raise GrokImportError(
- "The '%s' directive can not contain path separator."
- % directive.name)
-
-
-# Define grok directives
-
-
-class template(martian.Directive):
- scope = martian.CLASS
- store = martian.ONCE
- validate = martian.validateText
-
-
-class templatedir(martian.Directive):
- scope = martian.MODULE
- store = martian.ONCE
- validate = validateLocalPath
-
-
-class OneInterfaceOrClassOnClassOrModule(martian.Directive):
- """Convenience base class. Not for public use."""
- scope = martian.CLASS_OR_MODULE
- store = martian.ONCE
- validate = martian.validateInterfaceOrClass
-
-
-class layer(OneInterfaceOrClassOnClassOrModule):
- pass
-
-
-class TaggedValueStoreOnce(StoreOnce):
- """Stores the directive value in a interface tagged value.
- """
-
- def get(self, directive, component, default):
- return component.queryTaggedValue(directive.dotted_name(), default)
-
- def set(self, locals_, directive, value):
- already_set = locals_.get('__interface_tagged_values__', [])
- if directive.dotted_name() in already_set:
- raise GrokImportError(
- "The '%s' directive can only be called once per %s." %
- (directive.name, directive.scope.description))
- # Make use of the implementation details of interface tagged
- # values. Instead of being able to call "setTaggedValue()"
- # on an interface object, we only have access to the "locals"
- # of the interface object. We inject whatever setTaggedValue()
- # would've injected.
- taggeddata = locals_.setdefault(TAGGED_DATA, {})
- taggeddata[directive.dotted_name()] = value
-
- def setattr(self, context, directive, value):
- context.setTaggedValue(directive.dotted_name(), value)
-
-
-class skin(martian.Directive):
- # We cannot do any better than to check for a class scope. Ideally we
- # would've checked whether the context is indeed an Interface class.
- scope = martian.CLASS
- store = TaggedValueStoreOnce()
- validate = martian.validateText
-
-
-class path(martian.Directive):
- scope = martian.CLASS
- store = martian.ONCE
- validate = martian.validateText
-
-class view(OneInterfaceOrClassOnClassOrModule):
- default = IBrowserView
Deleted: grokcore.errorview/trunk/src/grokcore/errorview/interfaces.py
===================================================================
--- grokcore.errorview/trunk/src/grokcore/view/interfaces.py 2011-01-19 14:51:01 UTC (rev 119710)
+++ grokcore.errorview/trunk/src/grokcore/errorview/interfaces.py 2011-01-19 15:15:15 UTC (rev 119713)
@@ -1,223 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006-2007 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Grok interfaces
-"""
-from zope.interface import Interface, Attribute
-from zope.publisher.interfaces.browser import IBrowserPage, IBrowserView
-
-
-class IBaseClasses(Interface):
- View = Attribute("Base class for browser views.")
- DirectoryResource = Attribute("Base class to create new "
- "directory resource.")
-
-
-class IDirectives(Interface):
-
- def layer(layer):
- """Declare the layer for the view.
-
- This directive acts as a contraint on the 'request' of
- grok.View. This directive can only be used on class level."""
-
- def path(path):
- """Declare which path to use on a DirectoryResource.
-
- This directive can only be used on class level."""
-
- def skin(skin):
- """Declare this layer as a named skin.
-
- This directive can only be used on class level."""
-
- def template(template):
- """Declare the template name for a view.
-
- This directive can only be used on class level."""
-
- def templatedir(directory):
- """Declare a directory to be searched for templates.
-
- By default, grok will take the name of the module as the name
- of the directory. This can be overridden using
- ``templatedir``."""
-
- def view(view):
- """Define on which view a viewlet manager/viewlet is registered.
- """
-
-
-class IGrokcoreViewAPI(IBaseClasses, IDirectives):
-
- def url(request, obj, name=None, data=None):
- """Generate the URL to an object with optional name attached.
- An optional argument 'data' can be a dictionary that is converted
- into a query string appended to the URL."""
-
- def make_checker(factory, view_factory, permission, method_names=None):
- """Make a checker for a view_factory associated with factory.
-
- These could be one and the same for normal views, or different
- in case we make method-based views such as for JSON and XMLRPC.
- """
-
- def PageTemplate(template):
- """Create a Grok PageTemplate object from ``template`` source
- text. This can be used for inline PageTemplates."""
-
- def PageTemplateFile(filename):
- """Create a Grok PageTemplate object from a file specified by
- ``filename``. It will be treated like an inline template
- created with ``PageTemplate``."""
-
- IBrowserRequest = Attribute('Browser request interface')
- IDefaultBrowserLayer = Attribute('Default layer for browser views.')
- IGrokSecurityView = Attribute('Marker interface for permissive views.')
-
-
-class IGrokView(IBrowserPage, IBrowserView):
- """Grok views all provide this interface."""
-
- context = Attribute('context', "Object that the view presents.")
-
- request = Attribute('request', "Request that the view was looked up with.")
-
- response = Attribute('response', "Response object that is "
- "associated with the current request.")
-
- static = Attribute('static', "Directory resource containing "
- "the static files of the view's package.")
-
- def redirect(url):
- """Redirect to given URL"""
-
- def url(obj=None, name=None, data=None):
- """Construct URL.
-
- If no arguments given, construct URL to view itself.
-
- If only obj argument is given, construct URL to obj.
-
- If only name is given as the first argument, construct URL
- to context/name.
-
- If both object and name arguments are supplied, construct
- URL to obj/name.
-
- Optionally pass a 'data' keyword argument which gets added to the URL
- as a cgi query string.
- """
-
- def default_namespace():
- """Returns a dictionary of namespaces that the template
- implementation expects to always be available.
-
- This method is *not* intended to be overridden by application
- developers.
- """
-
- def namespace():
- """Returns a dictionary that is injected in the template
- namespace in addition to the default namespace.
-
- This method *is* intended to be overridden by the application
- developer.
- """
-
- def update(**kw):
- """This method is meant to be implemented by grok.View
- subclasses. It will be called *before* the view's associated
- template is rendered and can be used to pre-compute values
- for the template.
-
- update() can take arbitrary keyword parameters which will be
- filled in from the request (in that case they *must* be
- present in the request)."""
-
- def render(**kw):
- """A view can either be rendered by an associated template, or
- it can implement this method to render itself from Python.
- This is useful if the view's output isn't XML/HTML but
- something computed in Python (plain text, PDF, etc.)
-
- render() can take arbitrary keyword parameters which will be
- filled in from the request (in that case they *must* be
- present in the request)."""
-
- def __call__():
- """This is the main method called by Zope to render the
- view. You can use that method if you whish to render the
- view."""
-
-
-class ITemplateFileFactory(Interface):
- """Utility that generates templates from files in template directories.
- """
-
- def __call__(filename, _prefix=None):
- """Creates an ITemplate from a file
-
- _prefix is the directory the file is located in
- """
-
-
-class ITemplate(Interface):
- """Template objects
- """
-
- def _initFactory(factory):
- """Template language specific initializations on the view factory."""
-
- def render(view):
- """Renders the template"""
-
-class TemplateLookupError(Exception):
- pass
-
-class ITemplateRegAPI(Interface):
- """Public API for the templatereg module.
- """
- def register_inline_template(module_info, template_name, template):
- """Register an inline template with the template registry.
-
- module_info - the module_info of the module the inline template is in
- template_name - the name of the template
- template - the template itself
- """
-
- def register_directory(module_info):
- """Register a template directory for a module.
-
- module_info - the module_info of the module
- """
-
- def lookup(module_info, template_name, mark_as_associated=False):
- """Look up a template for a module.
-
- module_info - the module info for which to look up the template
- template_name - the name of the template to look up
- mark_as_associated - if a template is found, mark it as associated (disabled by default).
- """
-
-
-class IGrokSecurityView(Interface):
- """A view treated special by the Grok publisher.
-
- Views that provide this interface are treated more generously by
- the Grok publisher, as they are allowed to use attributes, which
- are not covered by permission setttings.
-
- `grok.Permission` and `grok.require` settings however, will be
- applied to such views.
- """
Deleted: grokcore.errorview/trunk/src/grokcore/errorview/meta-minimal.zcml
===================================================================
--- grokcore.errorview/trunk/src/grokcore/view/meta-minimal.zcml 2011-01-19 14:51:01 UTC (rev 119710)
+++ grokcore.errorview/trunk/src/grokcore/errorview/meta-minimal.zcml 2011-01-19 15:15:15 UTC (rev 119713)
@@ -1,11 +0,0 @@
-<configure
- xmlns="http://namespaces.zope.org/zope"
- xmlns:grok="http://namespaces.zope.org/grok">
- <include package="grokcore.component" file="meta.zcml" />
- <include package="grokcore.security" file="meta.zcml" />
-
- <!-- Only load view and template grokkers -->
- <grok:grok package=".meta.views" />
- <grok:grok package=".meta.templates" />
-
-</configure>
Deleted: grokcore.errorview/trunk/src/grokcore/errorview/meta.zcml
===================================================================
--- grokcore.errorview/trunk/src/grokcore/view/meta.zcml 2011-01-19 14:51:01 UTC (rev 119710)
+++ grokcore.errorview/trunk/src/grokcore/errorview/meta.zcml 2011-01-19 15:15:15 UTC (rev 119713)
@@ -1,7 +0,0 @@
-<configure
- xmlns="http://namespaces.zope.org/zope"
- xmlns:grok="http://namespaces.zope.org/grok">
- <include package="grokcore.component" file="meta.zcml" />
- <include package="grokcore.security" file="meta.zcml" />
- <grok:grok package=".meta" />
-</configure>
Deleted: grokcore.errorview/trunk/src/grokcore/errorview/publication.py
===================================================================
--- grokcore.errorview/trunk/src/grokcore/view/publication.py 2011-01-19 14:51:01 UTC (rev 119710)
+++ grokcore.errorview/trunk/src/grokcore/errorview/publication.py 2011-01-19 15:15:15 UTC (rev 119713)
@@ -1,86 +0,0 @@
-# -*- coding: utf-8 -*-
-from zope.security.proxy import removeSecurityProxy
-from zope.security.checker import selectChecker
-from zope.publisher.interfaces.browser import IBrowserView
-from zope.app.publication.browser import BrowserPublication
-from zope.app.publication.requestpublicationfactories import BrowserFactory
-from grokcore.view import IGrokSecurityView
-
-
-class ZopePublicationSansProxy(object):
- """Mixin that makes a publisher remove security proxies.
-
- This mixin overrides three methods from the `IPublication`
- interface (defined in `zope.publisher.interfaces`) to alter their
- security behavior. The normal Zope machinery wraps a security
- proxy around the application object returned by
- `getApplication()`, and around each of the objects returned as
- `traverseName()` is then called for each URL component. The
- versions here strip the security proxy off instead, returning the
- bare object (unless the object is a non-Grok view, in which case
- we leave the proxy installed for important security
- reasons). Non-Grok views however, are handled like Grok views, if
- they provide `grokcore.view.IGrokSecurityView`.
-
- Finally, when `callObject()` is asked to render
- the view, we quickly re-install a security proxy on the object, make
- sure that the current user is indeed allowed to invoke `__call__()`,
- then pass the bare object to the rendering machinery.
-
- The result is that, in place of the elaborate series of security
- checks made during the processing of a normal Zope request, Grok
- makes only a single security check: to see if the view can be
- permissibly rendered or not.
-
- """
- def getApplication(self, request):
- result = super(ZopePublicationSansProxy, self).getApplication(request)
- return removeSecurityProxy(result)
-
- def traverseName(self, request, ob, name):
- result = super(ZopePublicationSansProxy, self).traverseName(
- request, ob, name)
- bare_result = removeSecurityProxy(result)
- if IBrowserView.providedBy(bare_result):
- if IGrokSecurityView.providedBy(bare_result):
- return bare_result
- else:
- return result
- else:
- return bare_result
-
- def callObject(self, request, ob):
- checker = selectChecker(ob)
- if checker is not None:
- checker.check(ob, '__call__')
- return super(ZopePublicationSansProxy, self).callObject(request, ob)
-
-
-class GrokBrowserPublication(ZopePublicationSansProxy, BrowserPublication):
- """Combines `BrowserPublication` with the Grok sans-proxy mixin.
-
- In addition to the three methods that are overridden by the
- `ZopePublicationSansProxy`, this class overrides a fourth: the
- `getDefaultTraversal()` method, which strips the security proxy from
- the object being returned by the normal method.
-
- """
- def getDefaultTraversal(self, request, ob):
- obj, path = super(GrokBrowserPublication, self).getDefaultTraversal(
- request, ob)
- return removeSecurityProxy(obj), path
-
-
-class GrokBrowserFactory(BrowserFactory):
- """Returns the classes Grok uses for browser requests and publication.
-
- When an instance of this class is called, it returns a 2-element
- tuple containing:
-
- - The request class that Grok uses for browser requests.
- - The publication class that Grok uses to publish to a browser.
-
- """
- def __call__(self):
- request, publication = super(GrokBrowserFactory, self).__call__()
- return request, GrokBrowserPublication
Deleted: grokcore.errorview/trunk/src/grokcore/errorview/publication_security.zcml
===================================================================
--- grokcore.errorview/trunk/src/grokcore/view/publication_security.zcml 2011-01-19 14:51:01 UTC (rev 119710)
+++ grokcore.errorview/trunk/src/grokcore/errorview/publication_security.zcml 2011-01-19 15:15:15 UTC (rev 119713)
@@ -1,21 +0,0 @@
-<configure
- xmlns="http://namespaces.zope.org/zope"
- xmlns:grok="http://namespaces.zope.org/grok">
-
- <include package="zope.app.publication" />
- <include package="zope.app.publication" file="meta.zcml" />
-
- <!-- this overrides Zope 3's publication factories because they have
- the same name; we also need to change the priority because of
- the ZCML discriminator -->
-
- <publisher
- name="BROWSER"
- factory=".publication.GrokBrowserFactory"
- methods="GET POST HEAD"
- mimetypes="*"
- priority="11"
- />
-
- <grok:grok package=".publication" />
-</configure>
Deleted: grokcore.errorview/trunk/src/grokcore/errorview/templatereg.py
===================================================================
--- grokcore.errorview/trunk/src/grokcore/view/templatereg.py 2011-01-19 14:51:01 UTC (rev 119710)
+++ grokcore.errorview/trunk/src/grokcore/errorview/templatereg.py 2011-01-19 15:15:15 UTC (rev 119713)
@@ -1,267 +0,0 @@
-import os
-import warnings
-import zope.component
-import grokcore.component
-import grokcore.view
-from martian.error import GrokError
-from grokcore.view.interfaces import ITemplate, ITemplateFileFactory, TemplateLookupError
-from grokcore.view.components import PageTemplate
-
-
-class InlineTemplateRegistry(object):
- def __init__(self):
- self._reg = {}
- self._unassociated = set()
-
-
- def register_inline_template(self, module_info, template_name, template):
- # verify no file template got registered with the same name
- try:
- existing_template = file_template_registry.lookup(
- module_info, template_name)
- except TemplateLookupError:
- pass
- else:
- template_dir = file_template_registry.get_template_dir(module_info)
- raise GrokError("Conflicting templates found for name '%s': "
- "the inline template in module '%s' conflicts "
- "with the file template in directory '%s'" %
- (template_name, module_info.dotted_name,
- template_dir), None)
-
- # register the inline template
- self._reg[(module_info.dotted_name, template_name)] = template
- self._unassociated.add((module_info.dotted_name, template_name))
-
- def associate(self, module_info, template_name):
- # Two views in the same module should be able to use the same inline template
- try:
- self._unassociated.remove((module_info.dotted_name, template_name))
- except KeyError:
- pass
-
- def lookup(self, module_info, template_name, mark_as_associated=False):
- result = self._reg.get((module_info.dotted_name, template_name))
- if result is None:
- raise TemplateLookupError("inline template '%s' in '%s' cannot be found" % (
- template_name, module_info.dotted_name))
- if mark_as_associated:
- self.associate(module_info, template_name)
- return result
-
- def unassociated(self):
- return self._unassociated
-
-class FileTemplateRegistry(object):
- def __init__(self):
- self._reg = {}
- self._unassociated = set()
- self._registered_directories = set()
-
- def register_directory(self, module_info):
- # we cannot register a templates dir for a package
- if module_info.isPackage():
- return
-
- template_dir = self.get_template_dir(module_info)
- # we can only register for directories
- if not os.path.isdir(template_dir):
- return
-
- # we don't want associated templates become unassociated again
- if template_dir in self._registered_directories:
- return
-
- for template_file in os.listdir(template_dir):
- template_path = os.path.join(template_dir, template_file)
- self._register_template_file(module_info, template_path)
-
- self._registered_directories.add(template_dir)
-
- def _register_template_file(self, module_info, template_path):
- template_dir, template_file = os.path.split(template_path)
-
- if template_file.startswith('.') or template_file.endswith('~'):
- return
- if template_file.endswith('.cache'):
- # chameleon creates '<tpl_name>.cache' files on the fly
- return
-
- template_name, extension = os.path.splitext(template_file)
- if (template_dir, template_name) in self._reg:
- raise GrokError("Conflicting templates found for name '%s' "
- "in directory '%s': multiple templates with "
- "the same name and different extensions." %
- (template_name, template_dir), None)
- # verify no inline template exists with the same name
- try:
- inline_template_registry.lookup(module_info, template_name)
- except TemplateLookupError:
- pass
- else:
- raise GrokError("Conflicting templates found for name '%s': "
- "the inline template in module '%s' conflicts "
- "with the file template in directory '%s'" %
- (template_name, module_info.dotted_name,
- template_dir), None)
-
- extension = extension[1:] # Get rid of the leading dot.
- template_factory = zope.component.queryUtility(
- grokcore.view.interfaces.ITemplateFileFactory,
- name=extension)
-
- if template_factory is None:
- # Warning when importing files. This should be
- # allowed because people may be using editors that generate
- # '.bak' files and such.
- warnings.warn("File '%s' has an unrecognized extension in "
- "directory '%s'" %
- (template_file, template_dir), UserWarning, 2)
- return
- template = template_factory(template_file, template_dir)
- template._annotateGrokInfo(template_name, template_path)
-
- self._reg[(template_dir, template_name)] = template
- self._unassociated.add(template_path)
-
- def associate(self, template_path):
- # Two views in different module should be able to use the same template
- try:
- self._unassociated.remove(template_path)
- except KeyError:
- pass
-
- def lookup(self, module_info, template_name, mark_as_associated=False):
- template_dir = self.get_template_dir(module_info)
- result = self._reg.get((template_dir, template_name))
- if result is None:
- raise TemplateLookupError("template '%s' in '%s' cannot be found" % (
- template_name, template_dir))
- if mark_as_associated:
- registered_template_path = self._reg.get((template_dir, template_name)).__grok_location__
- self.associate(registered_template_path)
- return result
-
- def unassociated(self):
- return self._unassociated
-
- def get_template_dir(self, module_info):
- template_dir_name = grokcore.view.templatedir.bind().get(
- module_info.getModule())
- if template_dir_name is None:
- template_dir_name = module_info.name + '_templates'
-
- template_dir = module_info.getResourcePath(template_dir_name)
- return template_dir
-
-inline_template_registry = InlineTemplateRegistry()
-file_template_registry = FileTemplateRegistry()
-
-def register_inline_template(module_info, template_name, template):
- return inline_template_registry.register_inline_template(module_info, template_name, template)
-
-def register_directory(module_info):
- return file_template_registry.register_directory(module_info)
-
-def _clear():
- """Remove the registries (for use by tests)."""
- global inline_template_registry
- global file_template_registry
- inline_template_registry = InlineTemplateRegistry()
- file_template_registry = FileTemplateRegistry()
-
-try:
- from zope.testing.cleanup import addCleanUp
-except ImportError:
- # don't have that part of Zope
- pass
-else:
- addCleanUp(_clear)
- del addCleanUp
-
-def lookup(module_info, template_name, mark_as_associated=False):
- try:
- return file_template_registry.lookup(module_info, template_name, mark_as_associated)
- except TemplateLookupError, e:
- try:
- return inline_template_registry.lookup(module_info, template_name, mark_as_associated)
- except TemplateLookupError, e2:
- # re-raise first error again
- raise e
-
-def check_unassociated():
- unassociated = inline_template_registry.unassociated()
- if unassociated:
- for dotted_name, template_name in unassociated:
- msg = (
- "Found the following unassociated template "
- "after configuration in %r: %s." % (
- dotted_name, template_name))
- warnings.warn(msg, UserWarning, 1)
- unassociated = file_template_registry.unassociated()
- for template_name in unassociated:
- msg = (
- "Found the following unassociated template "
- "after configuration: %s" % (
- template_name))
- warnings.warn(msg, UserWarning, 1)
-
-
-def checkTemplates(module_info, factory, component_name,
- has_render, has_no_render):
- factory_name = factory.__name__.lower()
- template_name = grokcore.view.template.bind().get(factory)
- if template_name is None:
- template_name = factory_name
-
- # We used grok.template. Check if there is no template with the
- # same name as the view
- if factory_name != template_name:
- try:
- lookup(module_info, factory_name)
- raise GrokError("Multiple possible templates for %s %r. It "
- "uses grok.template('%s'), but there is also "
- "a template called '%s'."
- % (component_name, factory, template_name,
- factory_name), factory)
- except TemplateLookupError:
- pass
-
- # Check if view already have a template set with template =
- factory_have_template = (
- getattr(factory, 'template', None) is not None and
- ITemplate.providedBy(factory.template))
-
- # Lookup for a template in the registry
- try:
- factory.template = lookup(module_info, template_name, mark_as_associated=True)
- factory_have_template = True
- except TemplateLookupError:
- pass
-
- # Check for have both render and template
- if factory_have_template and has_render(factory):
- raise GrokError(
- "Multiple possible ways to render %s %r. "
- "It has both a 'render' method as well as "
- "an associated template." %
- (component_name, factory), factory)
-
- # Check for no render and no template
- if not factory_have_template and has_no_render(factory):
- raise GrokError("%s %r has no associated template or "
- "'render' method." %
- (component_name.title(), factory), factory)
-
- if factory_have_template:
- factory.template._initFactory(factory)
-
-
-class PageTemplateFileFactory(grokcore.component.GlobalUtility):
- grokcore.component.implements(ITemplateFileFactory)
- grokcore.component.name('pt')
-
- def __call__(self, filename, _prefix=None):
- return PageTemplate(filename=filename, _prefix=_prefix)
-
-
Deleted: grokcore.errorview/trunk/src/grokcore/errorview/templatereg.txt
===================================================================
--- grokcore.errorview/trunk/src/grokcore/view/templatereg.txt 2011-01-19 14:51:01 UTC (rev 119710)
+++ grokcore.errorview/trunk/src/grokcore/errorview/templatereg.txt 2011-01-19 15:15:15 UTC (rev 119713)
@@ -1,398 +0,0 @@
-Template registry
-=================
-
-When grokking views, there is a single global template registry that:
-
-* the grokking process can issue actions to register templates into it.
-
-* the actions that set up views can quickly look up templates from it
- to associate them with views.
-
-* the template registry keeps track of templates that are associated
- with views, or not.
-
-* an action gets registered that gets executed late in configuration
- process that reports on any unassociated templates that are left.
-
-Registration functions
-----------------------
-
-In a normal run of the application, the global registration functions
-are used to register templates. These are ``register_inline_template``
-for inline templates in Python code, and ``register_directory`` for
-templates in directories associated with a module::
-
- >>> from grokcore.view.templatereg import (register_directory,
- ... register_inline_template)
-
-Setup
------
-
-Our templates are ``.template``, so we need to register a
-``ITemplateFileFactory`` utility for them that knows how to make the
-appropriate templates::
-
- >>> from grokcore.view.interfaces import ITemplateFileFactory, ITemplate
- >>> from zope.interface import implements
- >>> class TestTemplate(object):
- ... implements(ITemplate) # we lie for testing purposes
- ... def __init__(self, filename, source):
- ... self.filename = filename
- ... self.source = source
- ... self.__grok_location__ = filename
- ... def __repr__(self):
- ... path, filename = os.path.split(self.filename)
- ... return "<Template '%s' in '%s'>" % (filename, path)
- ... def __cmp__(self, other):
- ... return cmp(self.filename, other.filename)
- ... def _annotateGrokInfo(self, template_name, template_path):
- ... pass # XXX why do we need to implement this?
-
- >>> class TestTemplateFactory(object):
- ... implements(ITemplateFileFactory)
- ... def __call__(self, filename, _prefix=None):
- ... f = open(os.path.join(_prefix, filename), 'r')
- ... data = f.read()
- ... f.close()
- ... return TestTemplate(os.path.join(_prefix, filename), data)
-
- >>> from zope import component
- >>> component.provideUtility(TestTemplateFactory(), ITemplateFileFactory,
- ... name='template')
-
-We create a way to create a fake module_info for a (actually
-nonexistent) module with a real directory that contains templates::
-
- >>> class ModuleInfo(object):
- ... def __init__(self, name, dir):
- ... self.dotted_name = name
- ... self.name = name
- ... self.dir = dir
- ... def getModule(self):
- ... return None
- ... def getResourcePath(self, template_dir_name):
- ... return os.path.join(self.dir, template_dir_name)
- ... def isPackage(self):
- ... return False
-
- >>> import os, tempfile
- >>> def create_module_info(module_name):
- ... package_dir = tempfile.mkdtemp()
- ... return ModuleInfo(module_name, package_dir)
- >>> def create_module_info_with_templates(module_name):
- ... package_dir = tempfile.mkdtemp()
- ... templates_dir = os.path.join(package_dir, module_name + '_templates')
- ... os.mkdir(templates_dir)
- ... return ModuleInfo(module_name, package_dir), templates_dir
-
-Registering a directory
------------------------
-
-We create a directory with two templates in it::
-
- >>> module_info, template_dir = create_module_info_with_templates('fake')
- >>> f = open(os.path.join(template_dir, 'foo.template'), 'w')
- >>> f.write('foo')
- >>> f.close()
- >>> f = open(os.path.join(template_dir, 'bar.template'), 'w')
- >>> f.write('bar')
- >>> f.close()
-
-We can now register the filesystem templates associated with our
-module_info with the registry::
-
- >>> register_directory(module_info)
-
-We'll also import the global template registry to do some checks::
-
- >>> from grokcore.view.templatereg import file_template_registry as reg
-
-We can look up the templates in the registry now::
-
- >>> reg.lookup(module_info, 'foo')
- <Template 'foo.template' in '...'>
- >>> reg.lookup(module_info, 'bar')
- <Template 'bar.template' in '...'>
-
-If we try to look up a template in a directory that doesn't exist, we get
-a TemplateLookupError::
-
- >>> nonexistent_module_info = create_module_info('nonexistent')
- >>> reg.lookup(nonexistent_module_info, 'foo')
- Traceback (most recent call last):
- ...
- TemplateLookupError: template 'foo' in '...' cannot be found
-
-We get this error for templates that do not exist as well::
-
- >>> reg.lookup(module_info, 'doesntexist')
- Traceback (most recent call last):
- ...
- TemplateLookupError: template 'doesntexist' in ... cannot be found
-
-Since no templates have yet been associated, retrieving the unassociated
-templates will get us all registered templates::
-
- >>> sorted(reg.unassociated())
- ['...bar.template', '...foo.template']
-
-Now we use a template, so we mark it as associated::
-
- >>> reg.associate(os.path.join(template_dir, 'foo.template'))
-
-There is only a single unassociated template left now::
-
- >>> sorted(reg.unassociated())
- ['...bar.template']
-
-Registering the templates directory again should do nothing and thus the unassociated list should be the same::
-
- >>> register_directory(module_info)
- >>> sorted(reg.unassociated())
- ['...bar.template']
-
-We can associate several times a template without error::
-
- >>> reg.associate(os.path.join(template_dir, 'foo.template'))
-
-
-Unknown template extensions
----------------------------
-
-We set up a directory with a template language that is not recognized by
-the system::
-
- >>> import os, tempfile
- >>> module_info2, template_dir2 = create_module_info_with_templates('module2')
- >>> f = open(os.path.join(template_dir2, 'foo.unknown'), 'w')
- >>> f.write('unknown')
- >>> f.close()
-
-We will now start recording all the warnings, as we will get one about the
-unknown template language when we register the directory later::
-
- >>> from grokcore.view.testing import warn
- >>> import warnings
- >>> saved_warn = warnings.warn
- >>> warnings.warn = warn
-
-We register the directory now, and we get the warning::
-
- >>> reg.register_directory(module_info2)
- From grok.testing's warn():
- ... UserWarning: File 'foo.unknown' has an unrecognized extension in directory '...'
- ...
-
-We restore the normal warnings mechanism::
-
- >>> warnings.warn = saved_warn
-
-This file will not be loaded as a template::
-
- >>> reg.lookup(module_info2, 'foo.unknown')
- Traceback (most recent call last):
- ...
- TemplateLookupError: template 'foo.unknown' in '...' cannot be found
-
-Multiple templates with the same name
--------------------------------------
-
-Let's make the template languages ``1`` and ``2`` known::
-
- >>> component.provideUtility(TestTemplateFactory(), ITemplateFileFactory,
- ... name='1')
- >>> component.provideUtility(TestTemplateFactory(), ITemplateFileFactory,
- ... name='2')
-
-We now set up a directory which contains 'foo.1' and 'foo.2'. These
-templates have the same name but use different template languages, and
-Grok won't know which one it should use::
-
- >>> module_info3, template_dir3 = create_module_info_with_templates('module3')
- >>> f = open(os.path.join(template_dir3, 'foo.1'), 'w')
- >>> f.write('1')
- >>> f.close()
- >>> f = open(os.path.join(template_dir3, 'foo.2'), 'w')
- >>> f.write('2')
- >>> f.close()
-
-We expect an error when we register this directory::
-
- >>> register_directory(module_info3)
- Traceback (most recent call last):
- ...
- GrokError: Conflicting templates found for name 'foo' in directory '...':
- multiple templates with the same name and different extensions.
-
-Inline templates
-----------------
-
-Inline templates are defined in a Python module instead of on the
-filesystem.
-
-Let's create a class for inline template and create an instance::
-
- >>> class InlineTemplate(object):
- ... def __init__(self, name):
- ... self.name = name
- ... def __repr__(self):
- ... return "<InlineTemplate '%s'>" % self.name
- >>> cavepainting = InlineTemplate('cavepainting')
-
-Let's register an inline template with the registry::
-
- >>> module_info4, template_dir4 = create_module_info_with_templates('module4')
- >>> register_inline_template(module_info4, 'cavepainting', cavepainting)
-
- >>> from grokcore.view.templatereg import inline_template_registry as inline_reg
-
-We can look it up now::
-
- >>> inline_reg.lookup(module_info4, 'cavepainting')
- <InlineTemplate 'cavepainting'>
-
-If we cannot find the template we get an error::
-
- >>> inline_reg.lookup(module_info4, 'unknown')
- Traceback (most recent call last):
- ...
- TemplateLookupError: inline template 'unknown' in 'module4' cannot be found
-
-Since no templates have yet been associated, retrieving the
-unassociated templates will get us all registered inline templates::
-
- >>> sorted(inline_reg.unassociated())
- [('module4', 'cavepainting')]
-
-Let's associate this template::
-
- >>> inline_reg.associate(module_info4, 'cavepainting')
-
-Unassociated list is now empty::
-
- >>> sorted(inline_reg.unassociated())
- []
-
-We can associate several times an inline template without error::
-
- >>> inline_reg.associate(module_info4, 'cavepainting')
-
-
-A common template lookup function
----------------------------------
-First clean up the registries::
-
- >>> from grokcore.view.templatereg import _clear
- >>> _clear()
- >>> from grokcore.view.templatereg import file_template_registry as reg
- >>> from grokcore.view.templatereg import inline_template_registry as inline_reg
-
-There is a single lookup function available that can used to look up
-both filesystem templates as well as inline templates.
-
- >>> lookuptest_info, lookuptest_template_dir = create_module_info_with_templates('lookuptest')
- >>> f = open(os.path.join(lookuptest_template_dir, 'foo.template'), 'w')
- >>> f.write('foo')
- >>> f.close()
- >>> register_directory(lookuptest_info)
-
- >>> from grokcore.view.templatereg import lookup
- >>> lookup(lookuptest_info, 'foo')
- <Template 'foo.template' in '...'>
-
-This can also be used to look up inline templates::
-
- >>> bar = InlineTemplate('bar')
- >>> register_inline_template(lookuptest_info, 'bar', bar)
- >>> lookup(lookuptest_info, 'bar')
- <InlineTemplate 'bar'>
-
-If we look up a template that doesn't exist, we get an error (about it
-missing on the filesystem)::
-
- >>> lookup(lookuptest_info, 'qux')
- Traceback (most recent call last):
- ...
- TemplateLookupError: template 'qux' in '...' cannot be found
-
-The file template and the inline template are unassociated::
-
- >>> sorted(reg.unassociated())
- ['...foo.template']
- >>> sorted(inline_reg.unassociated())
- [('lookuptest', 'bar')]
-
-We can give the parameter mark_as_associated=True to the lookup call to
-mark the returned template as associated::
-
- >>> lookup(lookuptest_info, 'foo', mark_as_associated=True)
- <Template 'foo.template' in '...'>
- >>> sorted(reg.unassociated())
- []
- >>> lookup(lookuptest_info, 'bar', mark_as_associated=True)
- <InlineTemplate 'bar'>
- >>> sorted(inline_reg.unassociated())
- []
-
-
-Conflicts between inline templates and file templates
------------------------------------------------------
-
-We construct a fake templates directory that's associated with the fictional
-``module`` module::
-
- >>> import os, tempfile
-
- >>> module_info5, template_dir5 = create_module_info_with_templates('module5')
-
-We create a template with the name ``foo`` in it::
-
- >>> f = open(os.path.join(template_dir5, 'foo.template'), 'w')
- >>> f.write('foo')
- >>> f.close()
-
-We register this directory, using the global registration functionality::
-
- >>> register_directory(module_info5)
-
-We now also try to register an inline template with the same name
-(``foo``), but this fails due to a conflict with the file template::
-
- >>> register_inline_template(module_info5, 'foo', InlineTemplate('foo'))
- Traceback (most recent call last):
- ...
- GrokError: Conflicting templates found for name 'foo': the inline template
- in module 'module5' conflicts with the file template in directory
- '...module5_templates'
-
-Let's now demonstrate the same conflict, the other way around.
-
-First we set up a fictional filesystem structure surrounding a
-``module6``::
-
- >>> module_info6, template_dir6 = create_module_info_with_templates('module6')
-
-We add a template to it::
-
- >>> f = open(os.path.join(template_dir6, 'bar.template'), 'w')
- >>> f.write('bar')
- >>> f.close()
-
-Now we first register an inline template ``bar`` before loading up that
-directory::
-
- >>> register_inline_template(module_info6, 'bar', InlineTemplate('bar'))
-
-When we now try to register the template ``bar`` in a directory, we'll
-get an error::
-
- >>> register_directory(module_info6)
- Traceback (most recent call last):
- ...
- GrokError: Conflicting templates found for name 'bar':
- the inline template in module 'module6' conflicts with the file template in directory '...'
-
-
-XXX use configuration action conflicts with module_info.dotted_name,
- name to determine conflicts between registrations?
-
Deleted: grokcore.errorview/trunk/src/grokcore/errorview/testing.py
===================================================================
--- grokcore.errorview/trunk/src/grokcore/view/testing.py 2011-01-19 14:51:01 UTC (rev 119710)
+++ grokcore.errorview/trunk/src/grokcore/errorview/testing.py 2011-01-19 15:15:15 UTC (rev 119713)
@@ -1,65 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Grok test helpers
-"""
-import sys
-import grokcore.view
-from zope.configuration.config import ConfigurationMachine
-from grokcore.component import zcml
-
-
-def grok(module_name):
- config = ConfigurationMachine()
- zcml.do_grok('grokcore.component.meta', config)
- zcml.do_grok('grokcore.security.meta', config)
- zcml.do_grok('grokcore.view.meta', config)
- zcml.do_grok('grokcore.view.templatereg', config)
- zcml.do_grok(module_name, config)
- config.execute_actions()
-
-
-lastwarning = '' # Here we collect warnings.
-
-
-def warn(message, category=None, stacklevel=1):
- """Intended to replace warnings.warn in tests.
-
- Modified copy from zope.deprecation.tests to:
-
- * make the signature identical to warnings.warn
- * to check for *.pyc and *.pyo files.
-
- When zope.deprecation is fixed, this warn function can be removed again.
- """
- print "From grok.testing's warn():"
-
- frame = sys._getframe(stacklevel)
- path = frame.f_globals['__file__']
- if path.endswith('.pyc') or path.endswith('.pyo'):
- path = path[:-1]
-
- file = open(path)
- lineno = frame.f_lineno
- for i in range(lineno):
- line = file.readline()
-
- warning = "%s:%s: %s: %s\n %s" % (
- path,
- frame.f_lineno,
- category.__name__,
- message,
- line.strip(),
- )
- grokcore.view.testing.lastwarning += warning
- print warning
Deleted: grokcore.errorview/trunk/src/grokcore/errorview/util.py
===================================================================
--- grokcore.errorview/trunk/src/grokcore/view/util.py 2011-01-19 14:51:01 UTC (rev 119710)
+++ grokcore.errorview/trunk/src/grokcore/errorview/util.py 2011-01-19 15:15:15 UTC (rev 119713)
@@ -1,55 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006-2007 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Grok utility functions.
-"""
-import urllib
-from grokcore.security.util import check_permission
-from zope.component import getMultiAdapter
-from zope.security.checker import NamesChecker, defineChecker
-from zope.traversing.browser.absoluteurl import _safe as SAFE_URL_CHARACTERS
-from zope.traversing.browser.interfaces import IAbsoluteURL
-
-
-def url(request, obj, name=None, data=None):
- url = getMultiAdapter((obj, request), IAbsoluteURL)()
- if name is not None:
- url += '/' + urllib.quote(name.encode('utf-8'), SAFE_URL_CHARACTERS)
-
- if not data:
- return url
-
- if not isinstance(data, dict):
- raise TypeError('url() data argument must be a dict.')
-
- for k, v in data.items():
- if isinstance(v, unicode):
- data[k] = v.encode('utf-8')
- if isinstance(v, (list, set, tuple)):
- data[k] = [
- isinstance(item, unicode) and item.encode('utf-8')
- or item for item in v]
-
- return url + '?' + urllib.urlencode(data, doseq=True)
-
-
-def make_checker(factory, view_factory, permission, method_names=None):
- if method_names is None:
- method_names = ['__call__']
- if permission is not None:
- check_permission(factory, permission)
- if permission is None or permission == 'zope.Public':
- checker = NamesChecker(method_names)
- else:
- checker = NamesChecker(method_names, permission)
- defineChecker(view_factory, checker)
More information about the checkins
mailing list