1
##############################################################################
3
# Copyright (c) 2004 Zope Corporation and Contributors.
6
# This software is subject to the provisions of the Zope Public License,
7
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
8
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
9
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
11
# FOR A PARTICULAR PURPOSE.
13
##############################################################################
14
"""ZCML Documentation module
16
The ZCML documentation module reads all of the meta directives (but does not
17
execute them) and uses the collected data to generate the tree. The result of
18
the evaluation is stored in thread-global variables, so that we have to parse
23
__docformat__ = 'restructuredtext'
25
from zope.configuration import docutils, xmlconfig
26
from zope.i18nmessageid import ZopeMessageFactory as _
27
from zope.interface import implements
28
from zope.location.interfaces import ILocation
30
import zope.app.appsetup.appsetup
31
from zope.app.apidoc.interfaces import IDocumentationModule
32
from zope.app.apidoc.utilities import ReadContainerBase
34
# Caching variables, so that the meta-ZCML files need to be read only once
39
"""Quotes a namespace to make it URL-secure."""
40
ns = ns.replace(':', '_co_')
41
ns = ns.replace('/', '_sl_')
45
"""Un-quotes a namespace from a URL-secure version."""
46
ns = ns.replace('_sl_', '/')
47
ns = ns.replace('_co_', ':')
51
class Namespace(ReadContainerBase):
52
"""Simple namespace object for the ZCML Documentation Module."""
56
def __init__(self, parent, name):
57
self.__parent__ = parent
58
self.__realname__ = name
59
self.__name__ = self.getQuotedName()
61
def getShortName(self):
62
"""Get the short name of the namespace."""
63
name = self.__realname__
64
if name.startswith('http://namespaces.zope.org/'):
68
def getFullName(self):
69
"""Get the full name of the namespace."""
70
return self.__realname__
72
def getQuotedName(self):
73
"""Get the full name, but quoted for a URL."""
74
name = self.getFullName()
78
def get(self, key, default=None):
79
"""See zope.app.container.interfaces.IReadContainer"""
80
ns = self.getFullName()
81
if not namespaces[ns].has_key(key):
83
schema, handler, info = namespaces[ns][key]
84
sd = subdirs.get((ns, key), [])
85
directive = Directive(self, key, schema, handler, info, sd)
89
"""See zope.app.container.interfaces.IReadContainer"""
91
for key in namespaces[self.getFullName()].keys():
92
list.append((key, self.get(key)))
97
class Directive(object):
98
"""Represents a ZCML Directive."""
100
implements(ILocation)
102
def __init__(self, ns, name, schema, handler, info, subdirs):
106
self.handler = handler
108
self.subdirs = subdirs
111
class ZCMLModule(ReadContainerBase):
112
r"""Represent the Documentation of all ZCML namespaces.
114
This documentation is implemented using a simple `IReadContainer`. The
115
items of the container."""
117
implements(IDocumentationModule)
119
# See zope.app.apidoc.interfaces.IDocumentationModule
120
title = _('ZCML Reference')
122
# See zope.app.apidoc.interfaces.IDocumentationModule
124
This module presents you with a complete list of ZCML directives and
125
serves therefore well as reference. The menu provides you with a tree that
126
organizes the directives by namespaces.
128
The documentation contents for each directive tells you all the available
129
attributes and their semantics. It also provides a link to the interface
130
the directive confirms to. If available, it will even tell you the
131
file the directive was declared in. At the end a list of available
132
subdirectives is given, also listing the implemented interface and
133
available attributes.
136
def _makeDocStructure(self):
137
# Some trivial caching
140
context = zope.app.appsetup.appsetup.getConfigContext()
141
namespaces, subdirs = docutils.makeDocStructures(context)
143
# Empty keys are not so good for a container
144
if namespaces.has_key(''):
145
namespaces['ALL'] = namespaces['']
149
def get(self, key, default=None):
150
"""See zope.app.container.interfaces.IReadContainer
152
Get the namespace by name; long and abbreviated names work.
154
if namespaces is None or subdirs is None:
155
self._makeDocStructure()
158
if namespaces.has_key(key):
159
return Namespace(self, key)
161
full_key = 'http://namespaces.zope.org/' + key
162
if namespaces.has_key(full_key):
163
return Namespace(self, full_key)
169
"""See zope.app.container.interfaces.IReadContainer"""
170
if namespaces is None or subdirs is None:
171
self._makeDocStructure()
173
for key in namespaces.keys():
174
namespace = Namespace(self, key)
175
# We need to make sure that we use the quoted URL as key
176
list.append((namespace.getQuotedName(), namespace))
187
from zope.testing.cleanup import addCleanUp