[Zope3-checkins] CVS: Zope3/src/zope/app/apidoc/zcmlmodule -
__init__.py:1.1 browser.py:1.1 configure.zcml:1.1
index.pt:1.1 menu.pt:1.1 tests.py:1.1
Philipp von Weitershausen
philikon at philikon.de
Thu Feb 19 15:46:44 EST 2004
Update of /cvs-repository/Zope3/src/zope/app/apidoc/zcmlmodule
In directory cvs.zope.org:/tmp/cvs-serv13817/zcmlmodule
Added Files:
__init__.py browser.py configure.zcml index.pt menu.pt
tests.py
Log Message:
Bring over zope.products.apidoc to zope.app.
=== Added File Zope3/src/zope/app/apidoc/zcmlmodule/__init__.py ===
##############################################################################
#
# Copyright (c) 2004 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
#
##############################################################################
"""ZCML Documentation module
The ZCML documentation module reads all of the meta directives (but does not
execute them) and uses the collected data to generate the tree. The result of
the evaluation is stored in thread-global variables, so that we have to parse
the files only once.
$Id: __init__.py,v 1.1 2004/02/19 20:46:43 philikon Exp $
"""
import os
from zope.configuration import docutils, xmlconfig
from zope.interface import implements, Interface, Attribute
from zope.app import zapi
from zope.app.interfaces.location import ILocation
from zope.app.apidoc.interfaces import IDocumentationModule
from zope.app.apidoc.utilities import ReadContainerBase
# Caching variables, so that the meta-ZCML files need to be read only once
namespaces = None
subdirs = None
def quoteNS(ns):
"""Quotes a namespace to make it URL-secure.
Example::
>>> quoteNS('http://namespaces.zope.org/browser')
'http_co__sl__sl_namespaces.zope.org_sl_browser'
"""
ns = ns.replace(':', '_co_')
ns = ns.replace('/', '_sl_')
return ns
def unquoteNS(ns):
"""Un-quotes a namespace from a URL-secure version.
Example::
>>> unquoteNS('http_co__sl__sl_namespaces.zope.org_sl_browser')
'http://namespaces.zope.org/browser'
"""
ns = ns.replace('_sl_', '/')
ns = ns.replace('_co_', ':')
return ns
class Namespace(ReadContainerBase):
r"""Simple namespace object for the ZCML Documentation Module.
The namespace manages a particular ZCML namespace. The object always
expects the parent to be a 'ZCMLModule' instance.
Demonstration::
>>> ns = Namespace(ZCMLModule(), 'http://namespaces.zope.org/browser')
>>> ns.getShortName()
'browser'
>>> ns.getFullName()
'http://namespaces.zope.org/browser'
>>> ns.getQuotedName()
'http_co__sl__sl_namespaces.zope.org_sl_browser'
>>> ns.get('pages').__name__
'pages'
>>> ns.get('foo') is None
True
>>> print '\n'.join([name for name, dir in ns.items()][:4])
addMenuItem
addform
addview
addwizard
"""
implements(ILocation)
def __init__(self, parent, name):
self.__parent__ = parent
self.__realname__ = name
self.__name__ = self.getQuotedName()
def getShortName(self):
"""Get the short name of the namespace."""
name = self.__realname__
if name.startswith('http://namespaces.zope.org/'):
name = name[27:]
return name
def getFullName(self):
"""Get the full name of the namespace."""
name = self.__realname__
if name != 'ALL' and not name.startswith('http://namespaces.zope.org/'):
name = 'http://namespaces.zope.org/' + name
return name
def getQuotedName(self):
"""Get the full name, but quoted for a URL."""
name = self.getFullName()
name = quoteNS(name)
return name
def get(self, key, default=None):
"""See zope.app.interfaces.container.IReadContainer"""
ns = self.getFullName()
if not namespaces[ns].has_key(key):
return default
schema, info = namespaces[ns][key]
sd = subdirs.get((ns, key), [])
directive = Directive(self, key, schema, info, sd)
return directive
def items(self):
"""See zope.app.interfaces.container.IReadContainer"""
list = []
for key in namespaces[self.getFullName()].keys():
list.append((key, self.get(key)))
list.sort()
return list
class Directive(object):
"""Represents a ZCML Directive."""
implements(ILocation)
def __init__(self, ns, name, schema, info, subdirs):
self.__parent__ = ns
self.__name__ = name
self.schema = schema
self.info = info
self.subdirs = subdirs
class ZCMLModule(ReadContainerBase):
r"""Represent the Documentation of all Interfaces.
This documentation is implemented using a simply 'IReadContainer'. The
items of the container are all the interfaces listed in the closest
interface service and above.
Demonstration::
>>> module = ZCMLModule()
>>> module.get('http://namespaces.zope.org/browser').getFullName()
'http://namespaces.zope.org/browser'
>>> module.get(
... 'http_co__sl__sl_namespaces.zope.org_sl_browser').getFullName()
'http://namespaces.zope.org/browser'
>>> module.get('browser').getFullName()
'http://namespaces.zope.org/browser'
>>> module.get('foo') is None
True
>>> print '\n'.join([ns.getShortName() for n, ns in module.items()][1:4])
browser
code
dav
"""
implements(IDocumentationModule)
# See zope.app.apidoc.interfaces.IDocumentationModule
title = 'ZCML Reference'
# See zope.app.apidoc.interfaces.IDocumentationModule
description = """
This module presents you with a complete list of ZCML directives and
serves therefore well as reference. The menu provides you with a tree that
organizes the directives by namespaces.
The documentation contents for each directive tells you all the available
attributes and their semantics. It also provides a link to the interface
the directive confirms to. If available, it will even tell you the
file the directive was declared in. At the end a list of available
subdirectives is given, also listing the implemented interface and
available attributes.
"""
def __init__(self):
# Some trivial caching
global namespaces
global subdirs
if namespaces is None or subdirs is None:
from zope import app
file = os.path.join(os.path.split(app.__file__)[0], 'meta.zcml')
context = xmlconfig.file(file, execute=False)
namespaces, subdirs = docutils.makeDocStructures(context)
# Empty keys are not so good for a container
if namespaces.has_key(''):
namespaces['ALL'] = namespaces['']
del namespaces['']
def get(self, key, default=None):
"""See zope.app.interfaces.container.IReadContainer
Get the namespace by name; long and abbreviated names work.
"""
key = unquoteNS(key)
if not (key == 'ALL' or key.startswith('http://namespaces.zope.org/')):
key = 'http://namespaces.zope.org/' + key
if not namespaces.has_key(key):
return default
return Namespace(self, key)
def items(self):
"""See zope.app.interfaces.container.IReadContainer"""
list = []
for key in namespaces.keys():
namespace = Namespace(self, key)
# We need to make sure that we use the quoted URL as key
list.append((namespace.getQuotedName(), namespace))
list.sort()
return list
=== Added File Zope3/src/zope/app/apidoc/zcmlmodule/browser.py ===
##############################################################################
#
# Copyright (c) 2004 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
#
##############################################################################
"""Browser Views for ZCML Reference
$Id: browser.py,v 1.1 2004/02/19 20:46:43 philikon Exp $
"""
import urllib
from zope.proxy import removeAllProxies
from zope.schema import getFieldsInOrder
from zope.configuration.xmlconfig import ParserInfo
from zope.app import zapi
from zope.app.location import LocationProxy
from zope.app.apidoc.zcmlmodule import Directive, Namespace
from zope.app.apidoc.ifacemodule.browser import InterfaceDetails
from zope.app.apidoc.utilities import getPythonPath
__metaclass__ = type
class Menu:
"""Menu View Helper Class"""
def getMenuTitle(self, node):
"""Return the title of the node that is displayed in the menu."""
obj = removeAllProxies(node.context)
if isinstance(obj, Namespace):
name = obj.getShortName()
if name == 'ALL':
return 'All Namespaces'
return name
return zapi.name(obj)
def getMenuLink(self, node):
"""Return the HTML link of the node that is displayed in the menu."""
obj = removeAllProxies(node.context)
if isinstance(obj, Directive):
ns = zapi.getParent(obj)
return './'+zapi.name(ns) + '/' + zapi.name(obj) + '/index.html'
return None
class DirectiveDetails:
"""View class for a Directive."""
def getSchema(self):
"""Return the schema of the directive."""
schema = LocationProxy(self.context.schema,
self.context,
getPythonPath(self.context.schema))
return InterfaceDetails(schema, self.request)
def getNamespaceName(self):
"""Return the name of the namespace."""
name = zapi.getParent(self.context).getFullName()
if name == 'ALL':
return '<i>all namespaces</i>'
return name
def getFile(self):
"""Get the file where the directive was declared."""
info = removeAllProxies(self.context.info)
if isinstance(info, ParserInfo):
return info.file
return None
def getInfo(self):
"""Get info, if available."""
info = removeAllProxies(self.context.info)
if isinstance(info, ParserInfo):
return None
return info
def getSubdirectives(self):
"""Create a list of subdirectives."""
dirs = []
for ns, name, schema, info in self.context.subdirs:
schema = LocationProxy(schema, self.context, getPythonPath(schema))
schema = InterfaceDetails(schema, self.request)
dirs.append({'namespace': ns,
'name': name,
'schema': schema,
'info': info})
return dirs
=== Added File Zope3/src/zope/app/apidoc/zcmlmodule/configure.zcml ===
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser">
<class class=".ZCMLModule">
<allow interface="zope.app.apidoc.interfaces.IDocumentationModule" />
<allow interface="zope.app.interfaces.container.IReadContainer" />
</class>
<class class=".Namespace">
<allow attributes="getShortName getFullName getQuotedName" />
<allow interface="zope.app.interfaces.container.IReadContainer" />
</class>
<class class=".Directive">
<allow attributes="name schema info subdirs" />
</class>
<utility
provides="zope.app.apidoc.interfaces.IDocumentationModule"
factory=".ZCMLModule"
name="ZCML" />
<browser:page
for=".ZCMLModule"
class=".browser.Menu"
permission="zope.View"
name="menu.html"
template="menu.pt" />
<browser:page
for=".Directive"
class=".browser.DirectiveDetails"
permission="zope.View"
name="index.html"
template="index.pt" />
</configure>
=== Added File Zope3/src/zope/app/apidoc/zcmlmodule/index.pt ===
<html metal:use-macro="views/apidoc_macros/details">
<body metal:fill-slot="contents"
tal:define="schema view/getSchema">
<h1 class="details-header">
<span tal:replace="context/zope:name" />
(<span tal:replace="structure view/getNamespaceName" />)
</h1>
<div class="indent"
tal:condition="view/getFile">
<i>File:</i> <tal:block content="view/getFile"/>
</div>
<div class="indent"
tal:condition="view/getInfo">
<i>Info:</i> <tal:block content="view/getInfo"/>
</div>
<h2 class="details-section">Schema</h2>
<div class="indent">
<a href=""
tal:attributes="href
string:../../../Interface/${schema/getId}/apiindex.html">
<h3 tal:content="schema/getId">zope.fields.Schema</h3>
</a>
</div>
<div class="indent">
<div class="documentation" tal:content="structure schema/getDoc">
Here is the doc string
</div>
</div>
<div class="indent"
tal:define="fields schema/getFields">
<ul class="attr-list"
tal:condition="fields">
<li tal:repeat="field fields">
<b><code tal:content="field/name">field</code></b>
- <a href=""
tal:attributes="href
string:../../../Interface/${field/iface/id}/apiindex.html">
<code tal:content="field/iface/name">IField</code></a>
(<span tal:content="string:${field/required}, ">optional, </span>
default = <code tal:content="field/default" />)<br>
<span tal:content="field/description">field desc</span>
</li>
</ul>
<p tal:condition="not: fields">
<em>There are no fields specified.</em>
</p>
</div>
<tal:omit-tag
define="dir view/getSubdirectives"
condition="dir">
<h2 class="details-section">Subdirectives</h2>
<div class="indent"
tal:repeat="dir view/getSubdirectives">
<h3 tal:content="dir/name">
directive
</h3>
<div class="indent">
<a href=""
tal:attributes="href
string:../../../Interface/${dir/schema/getId}/apiindex.html">
<h4 tal:content="dir/schema/getId">zope.fields.Schema</h4>
</a>
</div>
<div class="indent">
<div class="documentation" tal:content="structure dir/schema/getDoc">
Here is the doc string
</div>
</div>
<div class="indent"
tal:define="fields dir/schema/getFields">
<ul class="attr-list"
tal:condition="fields">
<li tal:repeat="field fields">
<b><code tal:content="field/name">field</code></b>
- <a href=""
tal:attributes="href
string:../../../Interface/${field/iface/id}/apiindex.html">
<code tal:content="field/iface/name">IField</code></a>
(<span tal:content="string:${field/required}, ">optional, </span>
default = <code tal:content="field/default" />)<br>
<span tal:content="field/description">field desc</span>
</li>
</ul>
<p tal:condition="not: fields">
<em>There are no fields specified.</em>
</p>
</div>
</div>
</tal:omit-tag>
</body>
</html>
=== Added File Zope3/src/zope/app/apidoc/zcmlmodule/menu.pt ===
<html metal:use-macro="views/apidoc_macros/menu">
<body>
<p metal:fill-slot="pre_menu" class="small">
Namespaces that are not full URLs start with "http://namespaces.zope.org".
</p>
</body>
</html>
=== Added File Zope3/src/zope/app/apidoc/zcmlmodule/tests.py ===
##############################################################################
#
# Copyright (c) 2004 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
#
##############################################################################
"""Tests for the ZCML Documentation Module
$Id: tests.py,v 1.1 2004/02/19 20:46:43 philikon Exp $
"""
import unittest
from zope.testing.doctestunit import DocTestSuite
def test_suite():
return unittest.TestSuite((
DocTestSuite('zope.app.apidoc.zcmlmodule'),
))
if __name__ == '__main__':
unittest.main()
More information about the Zope3-Checkins
mailing list