[Zope3-checkins] SVN: Zope3/trunk/src/zope/app/onlinehelp/ Onlinehelp refactoring:

Roger Ineichen roger at projekt01.ch
Thu Feb 17 15:49:07 EST 2005


Log message for revision 29184:
  Onlinehelp refactoring:
  Added topic classes as replaceable components
  Changed registration of help topics
  Changed registration directive. The directive is backward compatible.
  Changed the global name 'help' to 'globalhelp' becaouse of it's conflicting
  subpackage called 'help'
  Added tree view
  Added tests

Changed:
  U   Zope3/trunk/src/zope/app/onlinehelp/__init__.py
  A   Zope3/trunk/src/zope/app/onlinehelp/browser/CHANGES.txt
  U   Zope3/trunk/src/zope/app/onlinehelp/browser/__init__.py
  U   Zope3/trunk/src/zope/app/onlinehelp/browser/configure.zcml
  U   Zope3/trunk/src/zope/app/onlinehelp/browser/contexthelp.pt
  U   Zope3/trunk/src/zope/app/onlinehelp/browser/ftests.py
  U   Zope3/trunk/src/zope/app/onlinehelp/browser/helptopic.pt
  A   Zope3/trunk/src/zope/app/onlinehelp/browser/item.gif
  A   Zope3/trunk/src/zope/app/onlinehelp/browser/minus.gif
  A   Zope3/trunk/src/zope/app/onlinehelp/browser/onlinehelp.css
  A   Zope3/trunk/src/zope/app/onlinehelp/browser/onlinehelp_macros.pt
  A   Zope3/trunk/src/zope/app/onlinehelp/browser/onlinehelp_navigation_macros.pt
  A   Zope3/trunk/src/zope/app/onlinehelp/browser/plus.gif
  U   Zope3/trunk/src/zope/app/onlinehelp/browser/topiclink.pt
  A   Zope3/trunk/src/zope/app/onlinehelp/browser/tree.css
  A   Zope3/trunk/src/zope/app/onlinehelp/browser/tree.js
  A   Zope3/trunk/src/zope/app/onlinehelp/browser/tree.py
  U   Zope3/trunk/src/zope/app/onlinehelp/configure.zcml
  U   Zope3/trunk/src/zope/app/onlinehelp/help/README.stx
  A   Zope3/trunk/src/zope/app/onlinehelp/help/__init__.py
  A   Zope3/trunk/src/zope/app/onlinehelp/help/configure.zcml
  A   Zope3/trunk/src/zope/app/onlinehelp/help/developer.txt
  U   Zope3/trunk/src/zope/app/onlinehelp/interfaces.py
  U   Zope3/trunk/src/zope/app/onlinehelp/meta.zcml
  U   Zope3/trunk/src/zope/app/onlinehelp/metaconfigure.py
  U   Zope3/trunk/src/zope/app/onlinehelp/metadirectives.py
  U   Zope3/trunk/src/zope/app/onlinehelp/onlinehelp.py
  U   Zope3/trunk/src/zope/app/onlinehelp/onlinehelptopic.py
  A   Zope3/trunk/src/zope/app/onlinehelp/tests/help.pt
  U   Zope3/trunk/src/zope/app/onlinehelp/tests/help.zcml
  A   Zope3/trunk/src/zope/app/onlinehelp/tests/output/
  A   Zope3/trunk/src/zope/app/onlinehelp/tests/output/test1.xml
  A   Zope3/trunk/src/zope/app/onlinehelp/tests/output/test2.xml
  U   Zope3/trunk/src/zope/app/onlinehelp/tests/test_helpdirectives.py
  A   Zope3/trunk/src/zope/app/onlinehelp/tests/test_treeview.py
  A   Zope3/trunk/src/zope/app/onlinehelp/tests/util.py

-=-
Modified: Zope3/trunk/src/zope/app/onlinehelp/__init__.py
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/__init__.py	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/__init__.py	2005-02-17 20:49:07 UTC (rev 29184)
@@ -32,8 +32,8 @@
 
 # Global Online Help Instance
 path = os.path.join(os.path.dirname(zope.app.__file__),
-                    'onlinehelp', 'help','welcome.stx')
-help = OnlineHelp('Online Help', path)
+                    'onlinehelp', 'help', 'welcome.stx')
+globalhelp = OnlineHelp('Online Help', path)
 
 
 class helpNamespace(object):
@@ -47,8 +47,8 @@
         Returns the global `OnlineHelp` instance with the traversal
         context.
         """
-        help.context = self.context
-        return help
+        globalhelp.context = self.context
+        return globalhelp
 
 def getTopicFor(obj, view=None):
     """Determine topic for an object and optionally a view.
@@ -61,6 +61,21 @@
     >>> import os
     >>> from tests.test_onlinehelp import testdir
     >>> from tests.test_onlinehelp import I1, Dummy1, Dummy2
+    >>> from zope.app.tests import ztapi
+    >>> from zope.component.interfaces import IFactory
+    >>> from zope.component.factory import Factory
+    >>> from zope.app.onlinehelp.onlinehelptopic import OnlineHelpTopic
+    >>> from zope.app.onlinehelp.onlinehelptopic import RESTOnlineHelpTopic
+    >>> from zope.app.onlinehelp.onlinehelptopic import STXOnlineHelpTopic
+    >>> from zope.app.onlinehelp.onlinehelptopic import ZPTOnlineHelpTopic
+    >>> default = Factory(OnlineHelpTopic)
+    >>> rest = Factory(RESTOnlineHelpTopic)
+    >>> stx = Factory(STXOnlineHelpTopic)
+    >>> zpt = Factory(ZPTOnlineHelpTopic)
+    >>> ztapi.provideUtility(IFactory, default, 'onlinehelp.topic.default')
+    >>> ztapi.provideUtility(IFactory, rest, 'onlinehelp.topic.rest')
+    >>> ztapi.provideUtility(IFactory, stx, 'onlinehelp.topic.stx')
+    >>> ztapi.provideUtility(IFactory, zpt, 'onlinehelp.topic.zpt')
     >>> path = os.path.join(testdir(), 'help.txt')
 
     Register a help topic for the interface 'I1' and the view 'view.html'
@@ -105,8 +120,8 @@
 
 
 def _clear():
-    global help
-    help.__init__(help.title, help.path)
+    global globalhelp
+    globalhelp.__init__(globalhelp.title, globalhelp.path)
 
 
 cleanup.addCleanUp(_clear)

Added: Zope3/trunk/src/zope/app/onlinehelp/browser/CHANGES.txt
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/browser/CHANGES.txt	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/browser/CHANGES.txt	2005-02-17 20:49:07 UTC (rev 29184)
@@ -0,0 +1,20 @@
+=======
+CHANGES
+=======
+
+Make the onlinehelp utility more component oriented.
+
+- Use registred page/view instead of ViewPageTemplate for rendering topic tree
+  This way we can use/register own templates for tree layout.
+
+- Add page template based topic for rendering topics which has to 
+  call other zope3 resources like javascripts and css styles sheets etc. 
+  This resources can be rendered in the header area of the onlinehelp_macros.
+
+- Enhance the API of topics and simplyfie the view part.
+
+- Implemented getSubTopics() method on topics. This way we can sublist topics.
+  
+- Remove unused onlinehelp code in rotterdam template.pt
+
+- Add type to directive, this supports registration of README.txt as 'rest' topics


Property changes on: Zope3/trunk/src/zope/app/onlinehelp/browser/CHANGES.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: Zope3/trunk/src/zope/app/onlinehelp/browser/__init__.py
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/browser/__init__.py	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/browser/__init__.py	2005-02-17 20:49:07 UTC (rev 29184)
@@ -17,61 +17,24 @@
 """
 __docformat__ = 'restructuredtext'
 
+from zope.security.proxy import removeSecurityProxy
+
 from zope.app import zapi
 from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
+from zope.app.publisher.browser import BrowserView
 from zope.app.publisher.interfaces.browser import IBrowserView
 
 from zope.app.onlinehelp.interfaces import IOnlineHelpTopic, IOnlineHelp
 from zope.app.onlinehelp import getTopicFor
 
-class TopicTreeView(object):
 
-    def __init__(self, context, request, base_url=''):
-        self.context = context
-        self.treecontext = context
-        self.request = request
-        self.base_url = base_url
-
-    def getTopicTree(self):
-        """ return the tree of help topics."""
-        # set up the root values
-        if self.base_url == '':
-            self.base_url = '/++help++'
-        self.treecontext = zapi.getUtility(IOnlineHelp,"OnlineHelp")
-        return self.subtopics()
-
-    topicTree = property(getTopicTree)
-
-    def listHelpItems(self):
-        """ recurse through the help topic tree"""
-        children=[]
-        for name, helpitem in self.treecontext.items():
-            if IOnlineHelpTopic.providedBy(helpitem):
-                info={}
-                info['title'] = helpitem.title
-                info['path'] = self.base_url+'/'+name
-                topic = TopicTreeView(
-                    helpitem,
-                    self.request,
-                    self.base_url+'/'+name)
-                
-                info['topics']=topic.subtopics()
-                children.append(info)
-
-        return children
-
-    subtopics = ViewPageTemplateFile('topiclink.pt')
-
-
-class OnlineHelpTopicView(TopicTreeView):
+class OnlineHelpTopicView(BrowserView):
     """View for one particular help topic."""
 
     def __init__(self, context, request):
         super(OnlineHelpTopicView, self).__init__(context, request)
-        self.context = context
-        self.request = request
 
-    def renderTopic(self):
+    def topicContent(self):
         """ render the source of the help topic """
         source = zapi.createObject(None,
                                    self.context.type,
@@ -80,23 +43,33 @@
         html = view.render()
         return html
 
-class ContextHelpView(TopicTreeView):
+    renderTopic = ViewPageTemplateFile('helptopic.pt')
 
+
+class ZPTOnlineHelpTopicView(BrowserView):
+    """View for a page template based help topic."""
+
     def __init__(self, context, request):
+        super(ZPTOnlineHelpTopicView, self).__init__(context, request)
+
+    def renderTopic(self):
+        """Render the registred topic."""
+        path = self.context.path
+        view = ViewPageTemplateFile(path)
+        return view(self)
+
+
+class ContextHelpView(BrowserView):
+
+    def __init__(self, context, request):
         super(ContextHelpView, self).__init__(context, request)
-        self.context = context
-        self.request = request
         self.topic = None
 
-    def renderContextTopic(self):
+    def getContextualTopicView(self):
         """ retrieve and render the source of a context help topic """
         topic = self.getContextHelpTopic()
-        source = zapi.createObject(None,
-                                   topic.type,
-                                   topic.source)
-        view = zapi.getMultiAdapter((source, self.request))
-        html = view.render()
-        return html
+        view = zapi.getMultiAdapter((topic, self.request), name='index.html')
+        return view.renderTopic()
 
     def getContextHelpTopic(self):
         """ Retrieve a help topic based on the context of the
@@ -140,4 +113,3 @@
         return self.topic
 
     contextHelpTopic = property(getContextHelpTopic)
-

Modified: Zope3/trunk/src/zope/app/onlinehelp/browser/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/browser/configure.zcml	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/browser/configure.zcml	2005-02-17 20:49:07 UTC (rev 29184)
@@ -9,23 +9,41 @@
       title="Menu for displaying help actions to be performed with popup"
       />
 
-  <pages
+  <!-- generic topic tree -->
+  <page
+      for="*"
+      name="getTopicTree"
+      permission="zope.View"
+      class=".tree.OnlineHelpTopicTreeView"
+      attribute="getTopicTree"
+      />
+
+  <!-- simply topic view -->
+  <page
+      name="index.html"
       for="zope.app.onlinehelp.interfaces.IOnlineHelpTopic"
+      class=".OnlineHelpTopicView"
       permission="zope.View"
-      class=".OnlineHelpTopicView"
-      >
+      attribute="renderTopic"
+      />
 
-      <page name="index.html" template="helptopic.pt" />
-      <page name="getTopicTree" attribute="getTopicTree" />
+  <!-- topic view for page template based topics -->
+  <page
+      name="index.html"
+      for="zope.app.onlinehelp.interfaces.IZPTOnlineHelpTopic"
+      class=".ZPTOnlineHelpTopicView"
+      permission="zope.View"
+      attribute="renderTopic"
+      />
 
-  </pages>
-
+  <!-- generic contextual topic view -->
   <page
+      name="contexthelp.html"
       for="zope.app.onlinehelp.interfaces.IOnlineHelp"
+      class=".ContextHelpView" 
       permission="zope.View"
-      class=".ContextHelpView"
-      name="contexthelp.html" 
-      template="contexthelp.pt" />
+      attribute="getContextualTopicView"
+      />
 
   <menuItem
       for="*"
@@ -34,5 +52,50 @@
       title="Help"
       action="++help++/@@contexthelp.html"
       />
+
+  <!-- resources for onlinhelp -->
+  <resource 
+      name="onlinehelp.css" 
+      file="onlinehelp.css"
+      />
+
+  <resource 
+      name="tree.css" 
+      file="tree.css"
+      />
+
+  <resource 
+      name="tree.js" 
+      file="tree.js"
+      />
+
+  <resource 
+      name="minus.gif" 
+      file="minus.gif"
+      />
+
+  <resource 
+      name="plus.gif" 
+      file="plus.gif"
+      />
+
+  <resource 
+      name="item.gif" 
+      file="item.gif"
+      />
+
+  <page
+      for="*"
+      name="onlinehelp_macros"
+      permission="zope.View"
+      template="onlinehelp_macros.pt"
+      />
+
+  <page
+      for="*"
+      name="onlinehelp_navigation_macros"
+      permission="zope.View"
+      template="onlinehelp_navigation_macros.pt"
+      />
  
 </zope:configure>

Modified: Zope3/trunk/src/zope/app/onlinehelp/browser/contexthelp.pt
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/browser/contexthelp.pt	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/browser/contexthelp.pt	2005-02-17 20:49:07 UTC (rev 29184)
@@ -1,30 +1,16 @@
-<html metal:use-macro="views/popup_macros/page">
-<head>
+<html metal:use-macro="views/onlinehelp_macros/page">
+<head><!--
   <title metal:fill-slot="title" 
       tal:content="view/contextHelpTopic/title"
-      i18n:translate="">Title</title>
+      i18n:translate="">Title</title>-->
 </head>
 <body>
 
-<div metal:fill-slot="left_slot">
-      <div class="box" id="help">
-        <h4 i18n:translate="">Online Help - TOC</h4>              
-        <div class="body">
-          <div tal:content="structure view/topicTree|nothing"
-               tal:omit-tag="">content of topicTree</div>
-          <br />
-        </div>
-      </div>
-</div>
-
 <div metal:fill-slot="body">
-
-    <h1 tal:content="view/contextHelpTopic/title"
-        i18n:translate="">Title of Help Topic</h1>
-
-    <p tal:content="structure view/renderContextTopic"
+<!--
+    <p tal:content="structure view/topicContent"
         i18n:translate="">Content of Online Help.</p>
-
+-->
 </div>
 
 </body>

Modified: Zope3/trunk/src/zope/app/onlinehelp/browser/ftests.py
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/browser/ftests.py	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/browser/ftests.py	2005-02-17 20:49:07 UTC (rev 29184)
@@ -23,51 +23,48 @@
 from zope.app.file import File
 from zope.app.testing.functional import BrowserTestCase
 from zope.app.onlinehelp.tests.test_onlinehelp import testdir
-from zope.app.onlinehelp import help
+from zope.app.onlinehelp import globalhelp
 
 class Test(BrowserTestCase):
 
     def test_contexthelp(self):
         path = os.path.join(testdir(), 'help.txt')
-        help.registerHelpTopic('ui','help','Help',path,
-             IRootFolder,
-             None)
+        globalhelp.registerHelpTopic('help', 'Help', '', path, IRootFolder)
         path = os.path.join(testdir(), 'help2.txt')
-        help.registerHelpTopic('ui','help2','Help2',path,
-             IRootFolder,
-             'contents.html')
-        root = self.getRootFolder()
-        root['file']=File()
+        globalhelp.registerHelpTopic('help2', 'Help2', '', path, IRootFolder,
+            'contents.html')
+
         transaction.commit()
 
-        response = self.publish(
-            '/contents.html',
-            basic='mgr:mgrpw')
+        response = self.publish("/+/action.html", basic='mgr:mgrpw', 
+                                form={'type_name':u'zope.app.content.File', 
+                                      'id':u'file'})
 
+        self.assertEqual(response.getStatus(), 302)
+
+        response = self.publish('/contents.html', basic='mgr:mgrpw')
+
         self.assertEqual(response.getStatus(), 200)
         body = ' '.join(response.getBody().split())
         self.assert_(body.find(
             "javascript:popup('contents.html/++help++/@@contexthelp.html") >= 0)
 
         response = self.publish(
-            '/contents.html/++help++/@@contexthelp.html',
-            basic='mgr:mgrpw')
+            '/contents.html/++help++/@@contexthelp.html', basic='mgr:mgrpw')
 
         self.assertEqual(response.getStatus(), 200)
         body = ' '.join(response.getBody().split())
         self.assert_(body.find("This is another help!") >= 0)
 
-        response = self.publish(
-            '/index.html/++help++/@@contexthelp.html',
-            basic='mgr:mgrpw')
+        response = self.publish('/index.html/++help++/@@contexthelp.html', 
+                                basic='mgr:mgrpw')
 
         self.assertEqual(response.getStatus(), 200)
         body = ' '.join(response.getBody().split())
         self.assert_(body.find("This is a help!") >= 0)
 
-        response = self.publish(
-            '/file/edit.html/++help++/@@contexthelp.html',
-            basic='mgr:mgrpw')
+        response = self.publish('/file/edit.html/++help++/@@contexthelp.html',
+                                basic='mgr:mgrpw')
 
         self.assertEqual(response.getStatus(), 200)
         body = ' '.join(response.getBody().split())
@@ -75,14 +72,11 @@
             "Welcome to the Zope 3 Online Help System.") >= 0)
 
         path = '/contents.html/++help++'
-        response = self.publish(
-            path,
-            basic='mgr:mgrpw')
+        response = self.publish(path, basic='mgr:mgrpw')
 
         self.assertEqual(response.getStatus(), 200)
         body = ' '.join(response.getBody().split())
-        self.assert_(body.find(
-            "Online Help - TOC") >= 0)
+        self.assert_(body.find("Topics") >= 0)
 
         self.checkForBrokenLinks(body, path, basic='mgr:mgrpw')
 

Modified: Zope3/trunk/src/zope/app/onlinehelp/browser/helptopic.pt
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/browser/helptopic.pt	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/browser/helptopic.pt	2005-02-17 20:49:07 UTC (rev 29184)
@@ -1,4 +1,4 @@
-<html metal:use-macro="views/popup_macros/page">
+<html metal:use-macro="views/onlinehelp_macros/page">
 <head>
   <title metal:fill-slot="title" 
       tal:content="context/title"
@@ -6,24 +6,9 @@
 </head>
 <body>
 
-<div metal:fill-slot="left_slot">
-      <div class="box" id="help">
-        <h4 i18n:translate="">Online Help - TOC</h4>              
-        <div class="body">
-          <div tal:content="structure view/getTopicTree|nothing"
-               tal:omit-tag="">content of topicTree</div>
-          <br />
-        </div>
-      </div>
-</div>
-
 <div metal:fill-slot="body">
 
-
-  <h1 tal:content="context/title"
-      i18n:translate="">Title of Help Topic</h1>
-
-  <p tal:content="structure view/renderTopic"
+  <p tal:content="structure view/topicContent"
       i18n:translate="">Content of Online Help.</p>
 
 </div>

Added: Zope3/trunk/src/zope/app/onlinehelp/browser/item.gif
===================================================================
(Binary files differ)


Property changes on: Zope3/trunk/src/zope/app/onlinehelp/browser/item.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: Zope3/trunk/src/zope/app/onlinehelp/browser/minus.gif
===================================================================
(Binary files differ)


Property changes on: Zope3/trunk/src/zope/app/onlinehelp/browser/minus.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: Zope3/trunk/src/zope/app/onlinehelp/browser/onlinehelp.css
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/browser/onlinehelp.css	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/browser/onlinehelp.css	2005-02-17 20:49:07 UTC (rev 29184)
@@ -0,0 +1,200 @@
+/*
+** Zope3 onlinehelp style sheet for CSS2-capable browsers.
+**
+*/
+
+/* Basic Elements 
+*/
+
+body {
+    font: 85% Helvetica, Arial, sans-serif;
+    background: White;
+    color: Black;
+    margin: 0;
+    padding: 0;
+}
+
+table {
+    font-size: 85%;
+}
+
+a {
+    text-decoration: none;
+    color: #369;
+    background-color: transparent;
+}
+
+a:active {
+    text-decoration: underline;
+}
+
+img {
+    border: none;
+    vertical-align: middle;
+}
+
+p {
+    margin: 0.5em 0em 1em 0em;
+    line-height: 1.5em;
+}
+
+p a:visited {
+    color: Purple;
+    background-color: transparent;
+}
+
+p a:active {
+    color: Red;
+    background-color: transparent;
+}
+
+p img {
+    border: 0;
+    margin: 0;
+}
+
+
+hr {
+    clear: both;
+    height: 1px;
+    color: #369;
+    background-color: transparent;
+}
+
+
+h1, h2, h3, h4, h5, h6 {
+    color: Black;
+    font: 80% bold Verdana, Helvetica, Arial, sans-serif;
+    margin: 0;
+    padding-top: 0.5em;
+    border-bottom: 1px solid #369;
+}
+
+h1 {
+    font-size: 160%;
+}
+
+h2 {
+    font-size: 150%;
+}
+
+h3 {
+    font-size: 140%;
+}
+
+h4 {
+    font-size: 120%;
+}
+
+h5 {
+    font-size: 100%;
+}
+
+h6 {
+    font-size: 80%;
+}
+
+ul { 
+    line-height: 1.5em;
+    /* list-style-image: url("bullet.gif"); */
+    margin-left: 2em;
+    padding:0;
+}
+
+ol {
+    line-height: 1.5em;
+    margin-left: 2em;
+    padding:0;
+}
+
+dl {
+}
+
+dt {
+    font-weight: bold;    
+}
+
+dd {
+    line-height: 1.5em;
+    margin-bottom: 1em;
+}
+
+abbr, acronym, .explain {
+    border-bottom: 1px dotted Black;
+    color: Black;
+    background-color: transparent;
+    cursor: help;
+}
+
+q {
+    font-family: Times, "Times New Roman", serif;
+    font-size: 100%;
+}
+
+blockquote {
+    font-family: Times, "Times New Roman", serif;
+    font-size: 100%;
+}
+
+code {
+    font-size: 100%;
+    color: Black;
+    background-color: #FFD900;
+}
+
+pre {
+    font-size: 90%;
+    padding: 1em;
+    border: 1px solid #A0A0A0;
+    color: Black;
+    background-color: #C7CDE4;
+}
+
+/*
+*/
+
+a.active {
+    font-weight: bold;
+}
+
+/* layout styles
+*/
+
+.headline {
+    width: 100%;
+    height: 35px;
+    font-size: 150%;
+    color: white;
+    background: #306090;
+    border-bottom: 1px solid silver;
+}
+.headline div.title {
+    padding: 5px 0px 0px 5px;
+}
+
+table.layout {
+    font: 100% Helvetica, Arial, sans-serif;
+}
+
+table.layout td.navigation {
+    vertical-align: top;
+    background: #F0F0F0;
+    border-right: 1px solid silver;
+    border-bottom: 1px solid silver;
+}
+
+table.layout td.content {
+    vertical-align: top;
+    padding: 10px 5px 5px 20px;
+}
+
+div.box div.title {
+    font-weight: bold;
+    background: #FFD900;
+    border-bottom: 1px solid silver;
+    padding: 5px 0px 5px 0px;
+}
+
+div.box div.title div {
+    padding: 0px 0px 0px 5px;
+}


Property changes on: Zope3/trunk/src/zope/app/onlinehelp/browser/onlinehelp.css
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/app/onlinehelp/browser/onlinehelp_macros.pt
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/browser/onlinehelp_macros.pt	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/browser/onlinehelp_macros.pt	2005-02-17 20:49:07 UTC (rev 29184)
@@ -0,0 +1,69 @@
+<metal:block define-macro="page"><metal:block define-slot="doctype"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"></metal:block>
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+    xml:lang="en"
+    lang="en"
+    i18n:domain="zope"
+    tal:define="sitemgmt python:'/++etc++site/' in str(request.URL)">
+
+  <head>
+    <title metal:define-slot="title"
+           tal:content="string:Z3: ${context/zope:title_or_name}">Z3 Onlinehelp</title>
+
+    <script type="text/javascript" src="tree.js"
+            tal:attributes="src string:${context/++resource++tree.js}" >
+    </script>
+
+    <style type="text/css" media="all"
+           tal:content="string:@import url(${context/++resource++onlinehelp.css});">
+      @import url(./onlinehelp.css);
+    </style>
+
+    <style type="text/css" media="all"
+           tal:content="string:@import url(${context/++resource++tree.css});">
+      @import url(./tree.css);
+    </style>
+
+    <meta http-equiv="Content-Type"
+          content="text/html;charset=utf-8" />
+
+    <metal:block define-slot="headers" />
+    <metal:block define-slot="style_slot" />
+    <metal:block define-slot="ecmascript_slot" />
+
+    <link rel="icon" type="image/png"
+          tal:attributes="href context/++resource++favicon.png" />
+  </head>
+
+  <body onload="buildTrees();">
+
+		<div class="headline">
+			<div class="title">Onlinehelp</div>
+		</div>
+
+	  <!-- get rid of the crapy divs where place the content below the tree box 
+		     if somebody has a better solution, fell free the change it. 
+				 But I don't whana see the content below the navigation box. -->
+		<table class="layout" border="0" cellspacing="0" cellpadding="0">
+			<tr>
+				<td class="navigation" nowrap="nowrap">
+					<metal:block define-slot="navigation ">
+					  <metal:navigation use-macro="views/onlinehelp_navigation_macros/navigation" />
+					</metal:block>
+				</td>
+				<td class="content">
+					<metal:block define-slot="body">
+            content
+          </metal:block>
+				</td>
+			</tr>
+		</table>
+
+    <div id="footer" metal:define-macro="footer" />
+
+  </body>
+
+</html>
+
+</metal:block>
+


Property changes on: Zope3/trunk/src/zope/app/onlinehelp/browser/onlinehelp_macros.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/app/onlinehelp/browser/onlinehelp_navigation_macros.pt
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/browser/onlinehelp_navigation_macros.pt	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/browser/onlinehelp_navigation_macros.pt	2005-02-17 20:49:07 UTC (rev 29184)
@@ -0,0 +1,16 @@
+<html>
+<body>
+
+<metal:navigation define-macro="navigation">
+	<div class="box" tal:define="topicList views/getTopicTree">
+		<div class="title">
+			<div i18n:translate="onlinehelp_navigation_box_title">Topics</div>
+		</div>
+
+		<tal:block content="structure views/getTopicTree">tree</tal:block>
+
+	</div>
+</metal:navigation>
+
+</body>
+</html>


Property changes on: Zope3/trunk/src/zope/app/onlinehelp/browser/onlinehelp_navigation_macros.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/app/onlinehelp/browser/plus.gif
===================================================================
(Binary files differ)


Property changes on: Zope3/trunk/src/zope/app/onlinehelp/browser/plus.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: Zope3/trunk/src/zope/app/onlinehelp/browser/topiclink.pt
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/browser/topiclink.pt	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/browser/topiclink.pt	2005-02-17 20:49:07 UTC (rev 29184)
@@ -1,9 +1,7 @@
-<ul>
-  <li tal:repeat="item view/listHelpItems">
+<div class="menu" tal:repeat="item view/listHelpItems">
     <a href=""
        tal:attributes="href item/path"
        tal:content="item/title"
        i18n:translate="">Title</a>
-    <div tal:replace="structure item/topics" />
-  </li>
-</ul>
+   <div tal:replace="structure item/topics">sub topics</div>
+</div>

Added: Zope3/trunk/src/zope/app/onlinehelp/browser/tree.css
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/browser/tree.css	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/browser/tree.css	2005-02-17 20:49:07 UTC (rev 29184)
@@ -0,0 +1,41 @@
+ul.tree {
+    padding-right: 20px;
+}
+
+ul.tree li {
+    list-style: none;
+} 
+
+ul.tree {
+    margin-left: 0px;
+}
+ul.tree ul , ul.tree li {
+    margin-left: 10px;
+}
+
+ul.tree li .link {
+    padding-left: 15px;
+}
+
+ul.tree li.expand .link {
+    cursor: pointer;
+    background: url(/@@/minus.gif) center left no-repeat;
+}
+
+ul.tree li.collapse .link {
+    cursor: pointer;
+    background: url(/@@/plus.gif) center left no-repeat;
+}
+
+ul.tree li.item .link {
+    cursor: default;
+    background: url(/@@/item.gif) center left no-repeat;
+}
+
+ul.tree li.expand ul {
+    display: block;
+}
+
+ul.tree li.collapse ul {
+    display: none;
+}


Property changes on: Zope3/trunk/src/zope/app/onlinehelp/browser/tree.css
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/app/onlinehelp/browser/tree.js
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/browser/tree.js	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/browser/tree.js	2005-02-17 20:49:07 UTC (rev 29184)
@@ -0,0 +1,140 @@
+//----------------------------------------------------------------------------
+// unordered list based tree
+//----------------------------------------------------------------------------
+
+var nodeCollapseClass = "collapse";
+var nodeExpandClass = "expand";
+var nodeItemClass = "item";
+var nodeLinkClass = "link";
+var activeNodeId = "activeTreeNode";
+
+//----------------------------------------------------------------------------
+// public API
+//----------------------------------------------------------------------------
+function buildTrees() {
+    if (!document.createElement) {
+        return;
+    }
+    uls = document.getElementsByTagName("ul");
+    for (var i=0; i<uls.length; i++) {
+        var ul = uls[i];
+        if (ul.nodeName == "UL" && ul.className == "tree") {
+            _renderTreeList(ul);
+            _toggleTreeList(ul, nodeExpandClass, activeNodeId);
+        }
+    }
+}
+
+function expandTree(id) {
+    var ul = document.getElementById(id);
+    if (ul == null) {
+        return false;
+    }
+    _toggleTreeList(ul, nodeExpandClass);
+}
+
+function collapseTree(id) {
+    var ul = document.getElementById(id);
+    if (ul == null) {
+        return false;
+    }
+    _toggleTreeList(ul, nodeCollapseClass);
+}
+
+function expandItem(treeId, itemId) {
+    var ul = document.getElementById(treeId);
+    if (ul == null) {
+        return false;
+    }
+    var togList = _toggleTreeList(ul, nodeExpandClass, itemId);
+    if (togList) {
+        var o = document.getElementById(itemId);
+        if (o.scrollIntoView) {
+            o.scrollIntoView(false);
+        }
+    }
+}
+
+function expandActiveItem(treeId) {
+    expandItem(treeId, activeNodeId);
+}
+
+//----------------------------------------------------------------------------
+// private methods
+//----------------------------------------------------------------------------
+function _toggleTreeList(ul, clsName, itemId) {
+    if (!ul.childNodes || ul.childNodes.length==0) {
+        return false;
+    }
+    for (var i=0; i<ul.childNodes.length; i++) {
+        var item = ul.childNodes[i];
+        if (itemId != null && item.id == itemId) { return true; }
+        if (item.nodeName == "LI") {
+            var subLists = false;
+            for (var si=0; si<item.childNodes.length; si++) {
+                var subitem = item.childNodes[si];
+                if (subitem.nodeName == "UL") {
+                    subLists = true;
+                    var togList = _toggleTreeList(subitem, clsName, itemId);
+                    if (itemId != null && togList) {
+                        item.className = clsName;
+                        return true;
+                    }
+                }
+            }
+            if (subLists && itemId == null) {
+                item.className = clsName;
+            }
+        }
+    }
+}
+
+function _renderTreeList(ul) {
+    if (!ul.childNodes || ul.childNodes.length == 0) {
+        return;
+    }
+    for (var i=0; i<ul.childNodes.length; i++) {
+        var item = ul.childNodes[i];
+        if (item.nodeName == "LI") {
+            var subLists = false;
+            for (var si=0; si<item.childNodes.length; si++) {
+                var subitem = item.childNodes[si];
+                if (subitem.nodeName == "UL") {
+                    subLists = true;
+                    _renderTreeList(subitem);
+                }
+            }
+            var span = document.createElement("SPAN");
+            var nbsp = '\u00A0'; // &nbsp;
+            span.className = nodeLinkClass;
+            if (subLists) {
+                if (item.className == null || item.className == "") {
+                    item.className = nodeCollapseClass;
+                }
+                if (item.firstChild.nodeName == "#text") {
+                    nbsp = nbsp + item.firstChild.nodeValue;
+                    item.removeChild(item.firstChild);
+                }
+                span.onclick = function () {
+                    if (this.parentNode.className == nodeExpandClass) {
+                        this.parentNode.className = nodeCollapseClass
+                    }else {
+                        this.parentNode.className = nodeExpandClass
+                    }
+                    return false;
+                }
+            }
+            else {
+                item.className = nodeItemClass;
+                span.onclick = function () {
+                    return false;
+                }
+            }
+            child = document.createTextNode(nbsp)
+            span.appendChild(child);
+            item.insertBefore(span, item.firstChild);
+        }
+    }
+}
+
+


Property changes on: Zope3/trunk/src/zope/app/onlinehelp/browser/tree.js
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/app/onlinehelp/browser/tree.py
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/browser/tree.py	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/browser/tree.py	2005-02-17 20:49:07 UTC (rev 29184)
@@ -0,0 +1,141 @@
+##############################################################################
+#
+# Copyright (c) 2002, 2003 Zope Corporation 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.
+#
+##############################################################################
+"""`OnlineHelp` tree view
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+from zope.app import zapi
+from zope.app.publisher.browser import BrowserView
+
+from zope.app.onlinehelp.interfaces import IOnlineHelp
+
+
+class OnlineHelpTopicTreeView(BrowserView):
+    """Online help topic tree view."""
+
+    def __init__(self, context, request):
+        super(OnlineHelpTopicTreeView, self).__init__(context, request)
+        self.onlinehelp = zapi.getUtility(IOnlineHelp, "OnlineHelp")
+
+    def getTopicTree(self):
+        """Return the tree of help topics.
+        
+        We build a flat list of tpoics info dict.
+        Iterate this dict oan build from the level info
+        a navigation tree in the page tmeplate.
+        Each time you get a level 0 means this is a subitem of the
+        Onlinehelp itself.
+        
+        info = [('id',{infoDict}),(),()]
+        
+        <ul class="tree" id="tree">
+          <li><a href="#">items</a>
+            <ul>
+              <li><a href="#">item</a></li>
+            </ul>
+          </li>
+          <li><a href="#">items</a>
+            <ul>
+              <li><a href="#">items</a>
+                <ul>
+                  <li><a href="#">item</a></li>
+                  <li><a href="#">item</a></li>
+                  <li><a href="#">item</a></li>
+                </ul>
+              </li>
+              <li><a href="#">items</a>
+                <ul>
+                  <li><a href="#">item</a></li>
+                  <li id="activeTreeNode"><a href="#">active item</a></li>
+                  <li><a href="#">item</a></li>
+                </ul>
+              </li>
+            </ul>
+          </li>
+        <ul>
+        """
+        return self.renderTree(self.onlinehelp, self.request)
+
+    def renderTree(self, root, request):
+        """Reder a unordered list 'ul' tree with a class name 'tree'."""
+        res=[]
+        intend = "  "
+        res.append('<ul class="tree" id="tree">')
+        for topic in root.getSubTopics():
+            title = topic.title
+            url = topic.id
+            item = self.renderLink(topic)
+
+            # expand if context is in tree
+            if self.isExpanded(topic):
+                res.append('  <li class="expand">%s' % item)
+            else:
+                res.append('  <li>%s' % item)
+
+            if len(topic.getSubTopics()) > 0:
+                res.append(self.renderItemList(topic, intend))
+            res.append('  </li>')
+
+        res.append('<ul>')
+    
+        return '\n'.join(res)
+
+    def renderItemList(self, topic, intend):
+        """Render a 'ul' elements as childs of the 'ul' tree."""
+        res=[]
+        intend = intend + "  "
+        res.append('%s<ul>' % intend)
+
+        for item in topic.getSubTopics():
+
+            # expand if context is in tree
+            if self.isExpanded(topic):
+                res.append('  %s<li class="expand">' % intend)
+            else:
+                res.append('  %s<li>' % intend)
+            
+            res.append(self.renderLink(item))
+            if len(item.getSubTopics()) > 0:
+                res.append('    %s%s' % (self.renderItemList(item, intend), 
+                    intend))
+            res.append('  %s</li>' % intend)
+        res.append('%s</ul>' % intend)
+    
+        return '\n'.join(res)
+    
+    def renderLink(self, topic):
+        """Render a href element."""
+        res = []
+        title = topic.title
+        if topic.parentPath:
+            url = topic.parentPath +'/'+ topic.id
+        else:
+            url = topic.id
+    
+        return '<a href="/++help++/%s">%s</a>\n' % (url, title)
+
+    def isExpanded(self, topic):
+        if topic.parentPath:
+            path = topic.parentPath +'/'+ topic.id
+        else:
+            path = topic.id
+        try:
+            if zapi.getPath(self.context).startswith('/'+path):
+                return True
+        except:
+            # TODO: fix it, functioanl test doesn't like zapi.getPath? ri
+            pass
+        return False


Property changes on: Zope3/trunk/src/zope/app/onlinehelp/browser/tree.py
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: Zope3/trunk/src/zope/app/onlinehelp/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/configure.zcml	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/configure.zcml	2005-02-17 20:49:07 UTC (rev 29184)
@@ -1,27 +1,54 @@
 <configure
    xmlns="http://namespaces.zope.org/zope"
-   xmlns:help="http://namespaces.zope.org/help"
    i18n_domain="zope"
    >
 
+  <content class=".onlinehelp.OnlineHelp">
+    <require
+        permission="zope.View"
+        interface=".interfaces.ISourceTextOnlineHelpTopic"
+        />
+    <require
+        permission="zope.View"
+        attributes="context"
+        />
+  </content>
+
+  <!-- this is the generic help topic implementation -->
   <content class=".onlinehelptopic.OnlineHelpTopic">
     <require
         permission="zope.View"
-        interface=".interfaces.IOnlineHelpTopic"
+        interface=".interfaces.ISourceTextOnlineHelpTopic"
         />
   </content>
 
-  <content class=".onlinehelp.OnlineHelp">
+  <!-- explicit restructured help topic implementation -->
+  <content class=".onlinehelptopic.RESTOnlineHelpTopic">
     <require
         permission="zope.View"
-        interface=".interfaces.IOnlineHelpTopic"
+        interface=".interfaces.IRESTOnlineHelpTopic"
         />
+  </content>
+
+  <!-- explicit structured help topic implementation -->
+  <content class=".onlinehelptopic.STXOnlineHelpTopic">
     <require
         permission="zope.View"
-        attributes="context"
+        interface=".interfaces.ISTXOnlineHelpTopic"
         />
   </content>
 
+  <!-- explicit page template help topic implementation -->
+  <content class=".onlinehelptopic.ZPTOnlineHelpTopic">
+    <factory
+        id="onlinehelp.topic.zpt"
+        />
+    <require
+        permission="zope.View"
+        interface=".interfaces.IZPTOnlineHelpTopic"
+        />
+  </content>
+
   <content class=".onlinehelptopic.OnlineHelpResource">
     <require
         permission="zope.View"
@@ -32,7 +59,7 @@
   <!-- Setup OnlineHelp Root as a Utility -->
   <utility
       provides=".interfaces.IOnlineHelp"
-      component="zope.app.onlinehelp.help"
+      component="zope.app.onlinehelp.globalhelp"
       name="OnlineHelp" />
 
   <!-- Help Namespace Configuration -->
@@ -51,28 +78,10 @@
       factory=".helpNamespace"
       />
 
-  <!-- Register initial Help Topics -->
-  <help:register
-      id="ui"
-      title="Zope UI Help"
-      doc_path="./help/ui.stx"
-      resources="mgmt-main-1.png"
-      />
-
-  <help:register 
-      id="welcome"
-      title="Welcome"
-      parent="ui"
-      doc_path="./help/welcome.stx"
-      />
-
-  <help:register
-      id="onlinehelp"
-      title="Online Help System"
-      doc_path="./help/README.stx"
-      />
-
   <!-- include browser package -->
   <include package=".browser" />
 
+  <!-- register help topics -->
+  <include package=".help" />
+
 </configure>

Modified: Zope3/trunk/src/zope/app/onlinehelp/help/README.stx
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/help/README.stx	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/help/README.stx	2005-02-17 20:49:07 UTC (rev 29184)
@@ -18,6 +18,8 @@
 
         - HTML documents
 
+        - Page template based content
+
     Topics are also containers and can contain further Topics or 
     resources associated with the Help Topic. 
     This way we can have
@@ -25,6 +27,11 @@
     possible to associate a topic with an interface or even 
     a particular view of an interface.
 
+    New topic classes can be easy defined and used. A new topic implementation
+    has only to provide the constructor attributes and the interface 
+    IOnlineHelpTopic. A new topic class can be used as the dotted name of the 
+    class attribute in the "help:register" directive.
+
     The Online Help System is implemented as global service.
 
 
@@ -51,6 +58,9 @@
     -  'view'     - The name of the view for wich this topic is registered.
                  Optional.
 
+    -  'class'    - The dotted path to the class which will be used for initialize
+                 a topic. Optional.
+
     -  'resources'  - A list of resources that can be referenced by the Help Topic (e.g. images). Optional.
 
 
@@ -66,19 +76,38 @@
     <!-- Register Help Topics -->
 
     <help:register
-        id="ui"
-        title="Zope UI Help"
+        id="zmi"
+        title="Zope ZMI"
         doc_path="./help/ui.stx"
         resources="mgmt-main-1.png"
         />
-
+  
     <help:register 
         id="welcome"
+        parent="onlinehelp"
         title="Welcome"
-        parent="ui"
-        for="zope.app.onlinehelp.interfaces.IOnlineHelpTopic"
-        view="index.html"
         doc_path="./help/welcome.stx"
         />
+  
+    <help:register
+        id="onlinehelp"
+        title="Online Help System"
+        doc_path="./help/README.stx"
+        />
 
+    <help:register
+        id="styleguide"
+        title="Zope Style Guide"
+        doc_path="styleguides.txt"
+        class="zope.app.onlinehelp.onlinehelptopic.RESTOnlineHelpTopic"
+        />
+  
+    <help:register
+        id="css"
+        parent="styleguide"
+        title="CSS Style Guide"
+        doc_path="index.html"
+        class="zope.app.onlinehelp.onlinehelptopic.ZPTOnlineHelpTopic"
+        />
+
     </configure>

Added: Zope3/trunk/src/zope/app/onlinehelp/help/__init__.py
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/help/__init__.py	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/help/__init__.py	2005-02-17 20:49:07 UTC (rev 29184)
@@ -0,0 +1,17 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation 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.
+#
+##############################################################################
+"""Initial help topics for OnlineHelp System.
+
+$Id:$
+"""


Property changes on: Zope3/trunk/src/zope/app/onlinehelp/help/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/app/onlinehelp/help/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/help/configure.zcml	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/help/configure.zcml	2005-02-17 20:49:07 UTC (rev 29184)
@@ -0,0 +1,35 @@
+<configure
+   xmlns="http://namespaces.zope.org/zope"
+   xmlns:help="http://namespaces.zope.org/help"
+   i18n_domain="zope"
+   >
+
+  <!-- Register initial Help Topics -->
+  <help:register 
+      id="welcome"
+      title="Welcome"
+      doc_path="welcome.stx"
+      />
+
+  <help:register
+      id="dev"
+      title="Zope Developer Info"
+      doc_path="developer.txt"
+      class="zope.app.onlinehelp.onlinehelptopic.RESTOnlineHelpTopic"
+      />
+
+  <help:register
+      id="zope.app.onlinehelp"
+      parent="dev"
+      title="Online Help"
+      doc_path="README.stx"
+      />
+
+  <help:register
+      id="ui"
+      title="User interface ZMI"
+      doc_path="ui.stx"
+      resources="mgmt-main-1.png"
+      />
+
+</configure>

Added: Zope3/trunk/src/zope/app/onlinehelp/help/developer.txt
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/help/developer.txt	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/help/developer.txt	2005-02-17 20:49:07 UTC (rev 29184)
@@ -0,0 +1,9 @@
+==============
+Developer info
+==============
+
+------------
+Introduction
+------------
+
+Here you can find developer informations found in the packges.


Property changes on: Zope3/trunk/src/zope/app/onlinehelp/help/developer.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: Zope3/trunk/src/zope/app/onlinehelp/interfaces.py
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/interfaces.py	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/interfaces.py	2005-02-17 20:49:07 UTC (rev 29184)
@@ -40,8 +40,12 @@
     The Content is stored in a file and not the Topic itself.
     The file is only read when required.
     
-    Note that all the Sub-Topic management is done by the `IContainer`
-    interface. 
+    Note that all the Sub-Topic management is done via the utility service.
+    The topic itself is stored in the IContainer implementation after add
+    the right parent topic of a child. This mechanism ensures that we don't 
+    have to take care on the registration order. 
+    The topic resources are stroed in the `IContainer` implementation of 
+    the topic too. 
     """
 
     id = TextLine(
@@ -62,26 +66,12 @@
         default = _(u"Help Topic"),
         required = True)
 
-    source = SourceText(
-        title=_(u"Source Text"),
-        description=_(u"Renderable source text of the topic."),
-        default=u"",
-        required=True,
-        readonly=True)
-
     path = TextLine(
         title = _(u"Path to the Topic"),
         description = _(u"The Path to the Definition of a Help Topic"),
         default = u"./README.TXT",
         required = True)
 
-    type = Choice(
-        title=_(u"Source Type"),
-        description=_(u"Type of the source text, e.g. structured text"),
-        default=u"zope.source.rest",
-        required = True,
-        vocabulary = "SourceTypes")
-
     interface = GlobalInterface(
         title=_(u"Object Interface"),
         description=_(u"Interface for which this Help Topic is registered."),
@@ -104,7 +94,41 @@
         """ return the presumed path to the topic, even the topic is not
         traversable from the onlinehelp. """
 
-class IOnlineHelp(IOnlineHelpTopic):
+    def getSubTopics():
+        """Returns IOnlineHelpTopic provided childs."""
+
+
+class ISourceTextOnlineHelpTopic(IOnlineHelpTopic):
+    """REstructed text based online help topic."""
+
+    source = SourceText(
+        title=_(u"Source Text"),
+        description=_(u"Renderable source text of the topic."),
+        default=u"",
+        required=True,
+        readonly=True)
+
+    type = Choice(
+        title=_(u"Source Type"),
+        description=_(u"Type of the source text, e.g. structured text"),
+        default=u"zope.source.rest",
+        required = True,
+        vocabulary = "SourceTypes")
+
+
+class IRESTOnlineHelpTopic(ISourceTextOnlineHelpTopic):
+    """REstructed text based online help topic."""
+
+
+class ISTXOnlineHelpTopic(ISourceTextOnlineHelpTopic):
+    """Structed text based online help topic."""
+
+
+class IZPTOnlineHelpTopic(IOnlineHelpTopic):
+    """Page template based online help topic."""
+
+
+class IOnlineHelp(ISourceTextOnlineHelpTopic):
     """The root of an onlinehelp hierarchy.
     Manages the registration of new topics.
     """

Modified: Zope3/trunk/src/zope/app/onlinehelp/meta.zcml
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/meta.zcml	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/meta.zcml	2005-02-17 20:49:07 UTC (rev 29184)
@@ -2,10 +2,14 @@
     xmlns="http://namespaces.zope.org/zope"
     xmlns:meta="http://namespaces.zope.org/meta">
 
-  <meta:directive 
-      namespace="http://namespaces.zope.org/help"
+  <meta:directives namespace="http://namespaces.zope.org/help">
+
+  <meta:complexDirective
       name="register"
-      schema=".metadirectives.IRegisterDirective"
-      handler=".metaconfigure.register" />
+      schema=".metadirectives.IOnlineHelpTopicDirective"
+      handler=".metaconfigure.OnlineHelpTopicDirective"
+      />
 
+  </meta:directives>
+
 </configure>

Modified: Zope3/trunk/src/zope/app/onlinehelp/metaconfigure.py
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/metaconfigure.py	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/metaconfigure.py	2005-02-17 20:49:07 UTC (rev 29184)
@@ -20,13 +20,33 @@
 """
 __docformat__ = 'restructuredtext'
 
-from zope.app.onlinehelp import help
+from zope.app.onlinehelp import globalhelp
 
-def register(_context, id, title, parent="", doc_path=None, for_=None,
-             view=None, resources=None):
-    """Register an `OnlineHelp` topic"""
 
-    _context.action(
-        discriminator = ('registerHelpTopic', parent, id),
-        callable = help.registerHelpTopic,
-        args = (parent, id, title, doc_path, for_, view, resources) )
+class OnlineHelpTopicDirective(object):
+
+    def __init__(self, _context, id, title, parent="", doc_path=None, 
+        for_=None, view=None, class_=None, resources=None):
+        self._context = _context
+        self.id = id
+        self.title = title
+        self.parent = parent
+        self.doc_path = doc_path
+        self.for_ = for_
+        self.view = view
+        self.class_ = class_
+        self.resources = resources
+        
+    def _args(self):
+        return (self.parent, self.id, self.title, self.doc_path, self.for_,
+                self.view, self.class_, self.resources)
+
+    def _discriminator(self):
+        return ('registerHelpTopic', self.parent, self.id)
+
+    def __call__(self):
+        self._context.action(
+            discriminator=self._discriminator(),
+            callable=globalhelp.registerHelpTopic,
+            args=self._args(),
+        )

Modified: Zope3/trunk/src/zope/app/onlinehelp/metadirectives.py
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/metadirectives.py	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/metadirectives.py	2005-02-17 20:49:07 UTC (rev 29184)
@@ -17,11 +17,13 @@
 """
 __docformat__ = 'restructuredtext'
 
-from zope.configuration.fields import GlobalInterface, Path, MessageID, Tokens
 from zope.interface import Interface
 from zope.schema import BytesLine, TextLine
+from zope.configuration.fields import GlobalInterface, GlobalObject
+from zope.configuration.fields import Path, MessageID, Tokens
 
-class IRegisterDirective(Interface):
+
+class IOnlineHelpTopicDirective(Interface):
     """Register an online topic.
 
     Optionally you can register a topic for a component and view.
@@ -60,6 +62,12 @@
         description=u"Path to the file that contains the Help Topic content.",
         required=True)
 
+    class_ = GlobalObject(
+        title=u"Factory",
+        description=u"The factory is the topic class used for initializeing the topic",
+        required=False,
+        )
+
     resources = Tokens(
         title=u"A list of resources.",
         description=u"""\

Modified: Zope3/trunk/src/zope/app/onlinehelp/onlinehelp.py
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/onlinehelp.py	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/onlinehelp.py	2005-02-17 20:49:07 UTC (rev 29184)
@@ -20,6 +20,8 @@
 """
 __docformat__ = 'restructuredtext'
 
+import os
+
 from zope.interface import implements
 from zope.app import zapi
 from zope.app.traversing.interfaces import IContainmentRoot
@@ -30,6 +32,9 @@
 class OnlineHelp(OnlineHelpTopic):
     """
     >>> import os
+    >>> from zope.app.tests import ztapi
+    >>> from zope.component.interfaces import IFactory
+    >>> from zope.component.factory import Factory
     >>> from zope.app.onlinehelp.tests.test_onlinehelp import testdir
     >>> from zope.app.onlinehelp.tests.test_onlinehelp import I1, Dummy1
     >>> path = os.path.join(testdir(), 'help.txt')
@@ -48,7 +53,19 @@
     True
 
     Register a new subtopic for interface 'I1' and view 'view.html'
-    
+
+    >>> from zope.app.onlinehelp.onlinehelptopic import OnlineHelpTopic
+    >>> from zope.app.onlinehelp.onlinehelptopic import RESTOnlineHelpTopic
+    >>> from zope.app.onlinehelp.onlinehelptopic import STXOnlineHelpTopic
+    >>> from zope.app.onlinehelp.onlinehelptopic import ZPTOnlineHelpTopic
+    >>> default = Factory(OnlineHelpTopic)
+    >>> rest = Factory(RESTOnlineHelpTopic)
+    >>> stx = Factory(STXOnlineHelpTopic)
+    >>> zpt = Factory(ZPTOnlineHelpTopic)
+    >>> ztapi.provideUtility(IFactory, default, 'onlinehelp.topic.default')
+    >>> ztapi.provideUtility(IFactory, rest, 'onlinehelp.topic.rest')
+    >>> ztapi.provideUtility(IFactory, stx, 'onlinehelp.topic.stx')
+    >>> ztapi.provideUtility(IFactory, zpt, 'onlinehelp.topic.zpt')
     >>> path = os.path.join(testdir(), 'help2.txt')
     >>> onlinehelp.registerHelpTopic('', 'help2', 'Help 2',
     ...     path, I1, 'view.html')
@@ -98,16 +115,21 @@
 
     def registerHelpTopic(self, parent_path, id, title,
                           doc_path, interface=None, view=None,
-                          resources=None):
+                          class_=None, resources=None):
         "See zope.app.onlineHelp.interfaces.IOnlineHelp"
-        # Create topic
-        topic = OnlineHelpTopic(id,
-                                title,
-                                doc_path,
-                                parent_path,
-                                interface,
-                                view)
 
+        if not os.path.exists(doc_path):
+            raise ConfigurationError(
+                "Help Topic definition %s does not exist" % doc_path
+                )
+
+        if class_ is None:
+            class_ = OnlineHelpTopic
+        
+        
+        # Create topic base on the custom class or OnlinHelpTopic
+        topic = class_(id, title, doc_path, parent_path, interface, view)
+
         # add resources to topic
         if resources is not None:
             topic.addResources(resources)
@@ -128,7 +150,8 @@
                 topic[t[1].id] = t[1]
 
         # Add topic to utilities registry
+        #utils = zapi.getService(Utilities)
+        #utils.provideUtility(IOnlineHelpTopic, topic, topic.getTopicPath())
+
         zapi.getGlobalSiteManager().provideUtility(
             IOnlineHelpTopic, topic, topic.getTopicPath())
-
-

Modified: Zope3/trunk/src/zope/app/onlinehelp/onlinehelptopic.py
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/onlinehelptopic.py	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/onlinehelptopic.py	2005-02-17 20:49:07 UTC (rev 29184)
@@ -28,9 +28,14 @@
 from zope.app.content_types import guess_content_type
 from zope.app.file.image import getImageInfo
 
-from zope.app.onlinehelp.interfaces import IOnlineHelpTopic, \
-     IOnlineHelpResource
+from zope.app.onlinehelp.interfaces import IOnlineHelpTopic
+from zope.app.onlinehelp.interfaces import ISourceTextOnlineHelpTopic
+from zope.app.onlinehelp.interfaces import IRESTOnlineHelpTopic
+from zope.app.onlinehelp.interfaces import ISTXOnlineHelpTopic
+from zope.app.onlinehelp.interfaces import IZPTOnlineHelpTopic
+from zope.app.onlinehelp.interfaces import IOnlineHelpResource
 
+
 class OnlineHelpResource(Persistent):
     """
     Represents a resource that is used inside
@@ -83,15 +88,108 @@
         return self._size
 
 
-class OnlineHelpTopic(SampleContainer):
+class BaseOnlineHelpTopic(SampleContainer):
     """
-    Represents a Help Topic.
+    Base class for custom Help Topic implementations.
     
     >>> from zope.app.onlinehelp.tests.test_onlinehelp import testdir
     >>> path = os.path.join(testdir(), 'help.txt')
 
     Create a Help Topic from a file
     
+    >>> topic = BaseOnlineHelpTopic('help','Help',path,'')
+
+    Test the title
+    
+    >>> topic.title
+    'Help'
+
+    Test the topic path
+    >>> topic.getTopicPath()
+    'help'
+    >>> topic.parentPath = 'parent'
+    >>> topic.getTopicPath()
+    'parent/help'
+
+    Resources can be added to an online help topic.
+    >>> topic.addResources(['test1.png', 'test2.png'])
+    >>> topic['test1.png'].contentType
+    'image/png'
+    >>> topic['test2.png'].contentType
+    'image/png'
+    """
+
+    id = u""
+    title = u""
+    path = u""
+    parentPath = u""
+    interface = None
+    view = None
+    
+    def __init__(self, id, title, path, parentPath, interface=None, view=None):
+        """Initialize object."""
+        self.id = id
+        self.parentPath = parentPath
+        self.title = title
+        self.path = path
+        self.interface = interface
+        self.view = view
+
+        if not os.path.exists(self.path):
+            raise ConfigurationError(
+                "Help Topic definition %s does not exist" % self.path
+                )
+
+        super(BaseOnlineHelpTopic, self).__init__()
+
+    def addResources(self, resources):
+        """ see IOnlineHelpTopic """
+        dirname = os.path.dirname(self.path)
+        for resource in resources:
+            resource_path=dirname+'/'+resource
+            if os.path.exists(resource_path):
+                self[resource] = OnlineHelpResource(resource_path)
+
+    def getTopicPath(self):
+        """ see IOnlineHelpTopic """
+        if self.parentPath:
+            return self.parentPath+'/'+self.id
+        else:
+            return self.id
+
+    def getSubTopics(self):
+        res = []
+        for item in self.values():
+            if IOnlineHelpTopic.providedBy(item):
+                res.append(item)
+        
+        return res
+
+
+class SourceTextOnlineHelpTopic(BaseOnlineHelpTopic):
+    """Source text methods mixin class."""
+
+    type = None
+
+    def _getSource(self):
+        return open(os.path.normpath(self.path)).read()
+
+    source = property(_getSource)
+
+
+class OnlineHelpTopic(SourceTextOnlineHelpTopic, SampleContainer):
+    """
+    Represents a Help Topic. This generic implementation uses the filename
+    extension for guess the type. This topic implementation supports plain
+    text topics, restructured and structured text topics. HTML topics get 
+    rendered as structured text. If a file doesn't have the right file 
+    extension, use a explicit topic class for representing the right format.
+    
+    >>> from zope.app.onlinehelp.tests.test_onlinehelp import testdir
+    >>> path = os.path.join(testdir(), 'help.txt')
+
+    Create a Help Topic from a file
+    
     >>> topic = OnlineHelpTopic('help','Help',path,'')
 
     Test the title
@@ -145,19 +243,14 @@
     'image/png'
     >>> topic['test2.png'].contentType
     'image/png'
+    """
 
+    implements(ISourceTextOnlineHelpTopic)
 
-    """
-    implements(IOnlineHelpTopic)
-
     def __init__(self, id, title, path, parentPath, interface=None, view=None):
         """Initialize object."""
-        self.id = id
-        self.parentPath = parentPath
-        self.title = title
-        self.path = path
-        self.interface = interface
-        self.view = view
+        super(OnlineHelpTopic, self).__init__(id, title, path, parentPath, 
+              interface, view)
 
         filename = os.path.basename(path.lower())
         file_ext = 'txt'
@@ -168,49 +261,238 @@
 
         if file_ext in ('rst', 'rest') :
             self.type = 'zope.source.rest'
-        elif file_ext == 'stx':
+        elif file_ext in ('stx', 'html', 'htm'):
             self.type = 'zope.source.stx'
-        elif file_ext in ('html', 'htm'):
-            self.type = 'zope.source.stx'
 
-        if not os.path.exists(self.path):
-            raise ConfigurationError(
-                "Help Topic definition %s does not exist" % self.path
-                )
 
-        super(OnlineHelpTopic, self).__init__()
+class RESTOnlineHelpTopic(SourceTextOnlineHelpTopic):
+    """
+    Represents a restructed text based Help Topic which has other 
+    filename extension then '.rst' or 'rest'.
+    
+    >>> from zope.app.onlinehelp.tests.test_onlinehelp import testdir
+    >>> path = os.path.join(testdir(), 'help.rst')
 
-    id = u""
+    Create a Help Topic from a file
+    
+    >>> topic = RESTOnlineHelpTopic('help','Help',path,'')
 
-    parentPath = u""
+    Test the title
+    
+    >>> topic.title
+    'Help'
 
-    title = u""
+    Test the topic path
+    >>> topic.getTopicPath()
+    'help'
+    >>> topic.parentPath = 'parent'
+    >>> topic.getTopicPath()
+    'parent/help'
 
-    path = u""
+    The type should be set to rest, since the file extension is 'rest'
+    
+    >>> topic.type
+    'zope.source.rest'
 
-    type = None
+    Test the help content.
 
-    interface = None
+    >>> topic.source
+    'This is a ReST help!'
 
-    view = None
+    Resources can be added to an online help topic.
+    >>> topic.addResources(['test1.png', 'test2.png'])
+    >>> topic['test1.png'].contentType
+    'image/png'
+    >>> topic['test2.png'].contentType
+    'image/png'
+    """
 
-    def _getSource(self):
-        return open(os.path.normpath(self.path)).read()
+    implements(IRESTOnlineHelpTopic)
 
-    source = property(_getSource)
+    type = 'zope.source.rest'
+    
+    def __init__(self, id, title, path, parentPath, interface=None, view=None):
+        """Initialize object."""
+        super(RESTOnlineHelpTopic, self).__init__(id, title, path, parentPath, 
+              interface, view)
 
-    def addResources(self, resources):
-        """ see IOnlineHelpTopic """
-        dirname = os.path.dirname(self.path)
-        for resource in resources:
-            resource_path=dirname+'/'+resource
-            if os.path.exists(resource_path):
-                self[resource] = OnlineHelpResource(resource_path)
 
-    def getTopicPath(self):
-        """ see IOnlineHelpTopic """
-        if self.parentPath != '':
-            return self.parentPath+'/'+self.id
-        else:
-            return self.id
-                
+class STXOnlineHelpTopic(SourceTextOnlineHelpTopic):
+    """
+    Represents a restructed text based Help Topic which has other 
+    filename extension then '.stx'.
+    
+    >>> from zope.app.onlinehelp.tests.test_onlinehelp import testdir
+    >>> path = os.path.join(testdir(), 'help.stx')
+
+    Create a Help Topic from a file
+    
+    >>> topic = STXOnlineHelpTopic('help','Help',path,'')
+
+    Test the title
+    
+    >>> topic.title
+    'Help'
+
+    Test the topic path
+    >>> topic.getTopicPath()
+    'help'
+    >>> topic.parentPath = 'parent'
+    >>> topic.getTopicPath()
+    'parent/help'
+
+    The type should be set to stx, since the file extension is 'stx'
+    
+    >>> topic.type
+    'zope.source.stx'
+
+    Test the help content.
+
+    >>> topic.source
+    'This is a STX help!'
+
+    Resources can be added to an online help topic.
+    >>> topic.addResources(['test1.png', 'test2.png'])
+    >>> topic['test1.png'].contentType
+    'image/png'
+    >>> topic['test2.png'].contentType
+    'image/png'
+    """
+
+    implements(ISTXOnlineHelpTopic)
+    
+    type = 'zope.source.stx'
+    
+    def __init__(self, id, title, path, parentPath, interface=None, view=None):
+        """Initialize object."""
+        super(STXOnlineHelpTopic, self).__init__(id, title, path, parentPath, 
+              interface, view)
+
+
+class ZPTOnlineHelpTopic(BaseOnlineHelpTopic):
+    """
+    Represents a page template based Help Topic which has other 
+    filename extension then '.pt'.
+    
+    
+    >>> from zope.publisher.browser import TestRequest
+    >>> from zope.app.publisher.browser import BrowserView
+    >>> from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
+    >>> from zope.app.onlinehelp.tests.test_onlinehelp import testdir
+    >>> path = os.path.join(testdir(), 'help.pt')
+
+    Create a page template bsed Help Topic from a file
+    
+    >>> topic = ZPTOnlineHelpTopic('help','Help',path,'')
+
+    Test the title
+    
+    >>> topic.title
+    'Help'
+
+    Test the topic path
+    >>> topic.getTopicPath()
+    'help'
+    >>> topic.parentPath = 'parent'
+    >>> topic.getTopicPath()
+    'parent/help'
+
+    Test the help content.
+
+    >>> class TestView(BrowserView):
+    ...     def index(self):
+    ...         path = self.context.path
+    ...         view = ViewPageTemplateFile(path)
+    ...         return view(self)
+    >>> request = TestRequest()
+    >>> view = TestView(topic, request)
+    >>> res = view.index()
+    >>> str(res).find('<body>This is a ZPT help!</body>') > 0
+    True
+
+    Resources can be added to an online help topic.
+
+    >>> topic.addResources(['test1.png', 'test2.png'])
+    >>> topic['test1.png'].contentType
+    'image/png'
+    >>> topic['test2.png'].contentType
+    'image/png'
+    """
+
+    implements(IZPTOnlineHelpTopic)
+
+    def __init__(self, id, title, path, parentPath, interface=None, view=None):
+        """Initialize object."""
+        super(ZPTOnlineHelpTopic, self).__init__(id, title, path, parentPath, 
+              interface, view)
+
+
+def OnlineHelpTopicFactory(name, schema, label, permission, layer,
+                    template, default_template, bases, for_, fields,
+                    fulledit_path=None, fulledit_label=None, menu=u''):
+    class_ = SimpleViewClass(template, used_for=schema, bases=bases)
+    class_.schema = schema
+    class_.label = label
+    class_.fieldNames = fields
+
+    class_.fulledit_path = fulledit_path
+    if fulledit_path and (fulledit_label is None):
+        fulledit_label = "Full edit"
+
+    class_.fulledit_label = fulledit_label
+
+    class_.generated_form = ViewPageTemplateFile(default_template)
+
+    defineChecker(class_,
+                  NamesChecker(("__call__", "__getitem__",
+                                "browserDefault", "publishTraverse"),
+                               permission))
+    if layer is None:
+        layer = IDefaultBrowserLayer
+
+    s = zapi.getGlobalService(zapi.servicenames.Adapters)
+    s.register((for_, layer), Interface, name, class_)
+
+
+
+import sys
+from zope.app.publisher.browser import BrowserView
+from zope.publisher.interfaces.browser import IBrowserPublisher
+from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
+from zope.publisher.interfaces import NotFound
+from zope.interface import implements
+
+class simple(BrowserView):
+
+    implements(IBrowserPublisher)
+
+    def browserDefault(self, request):
+        return self, ()
+
+    def publishTraverse(self, request, name):
+        if name == 'index.html':
+            return self.index
+
+        raise NotFound(self, name, request)
+
+    # XXX: we need some unittests for this !!!
+    def __getitem__(self, name):
+        return self.index.macros[name]
+
+    def __call__(self, *args, **kw):
+        return self.index(*args, **kw)
+
+def SimpleViewClass(src, offering=None, used_for=None, bases=()):
+    if offering is None:
+        offering = sys._getframe(1).f_globals
+
+    bases += (simple, )
+
+    class_ = type("SimpleViewClass from %s" % src, bases,
+                  {'index': ViewPageTemplateFile(src, offering)})
+
+    if used_for is not None:
+        class_.__used_for__ = used_for
+
+    return class_
+

Added: Zope3/trunk/src/zope/app/onlinehelp/tests/help.pt
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/tests/help.pt	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/tests/help.pt	2005-02-17 20:49:07 UTC (rev 29184)
@@ -0,0 +1 @@
+<html><head><title tal:content="context/title">Title</title></head><body>This is a ZPT help!</body></html>
\ No newline at end of file


Property changes on: Zope3/trunk/src/zope/app/onlinehelp/tests/help.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: Zope3/trunk/src/zope/app/onlinehelp/tests/help.zcml
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/tests/help.zcml	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/tests/help.zcml	2005-02-17 20:49:07 UTC (rev 29184)
@@ -4,14 +4,40 @@
     i18n_domain="zope"
     >
 
-  <include package="zope.app.onlinehelp" file="meta.zcml"/>
-
   <help:register 
       id = "help1"
       title = "Help"
       for = ".test_helpdirectives.I1"
       view = "view.html"
       doc_path = "help.txt" 
-      resources = "test1.png"/>
+      resources = "test1.png"
+      />
 
+  <help:register 
+      id = "help2"
+      title = "Help2"
+      doc_path = "help.txt"
+      />
+
+  <help:register 
+      id = "help3"
+      title = "Help3"
+      doc_path = "help.stx" 
+      class="zope.app.onlinehelp.onlinehelptopic.STXOnlineHelpTopic"
+      />
+
+  <help:register 
+      id = "help4"
+      title = "Help4"
+      doc_path = "help.rst"
+      class="zope.app.onlinehelp.onlinehelptopic.RESTOnlineHelpTopic"
+      />
+
+  <help:register 
+      id = "help5"
+      title = "Help5"
+      doc_path = "help.pt"
+      class="zope.app.onlinehelp.onlinehelptopic.ZPTOnlineHelpTopic"
+      />
+
 </configure>

Added: Zope3/trunk/src/zope/app/onlinehelp/tests/output/test1.xml
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/tests/output/test1.xml	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/tests/output/test1.xml	2005-02-17 20:49:07 UTC (rev 29184)
@@ -0,0 +1 @@
+<ul class="tree" id="tree"><ul>


Property changes on: Zope3/trunk/src/zope/app/onlinehelp/tests/output/test1.xml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/app/onlinehelp/tests/output/test2.xml
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/tests/output/test2.xml	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/tests/output/test2.xml	2005-02-17 20:49:07 UTC (rev 29184)
@@ -0,0 +1 @@
+<ul class="tree" id="tree"><li><a href="/++help++/topic1">Topic1</a><ul><li><a href="/++help++/topic1/topic1_1">Topic1_1</a><ul><li><a href="/++help++/topic1/topic1_1/topic1_1_1">Topic1_1_1</a></li></ul></li></ul></li><li><a href="/++help++/topic2">Topic2</a></li><ul>


Property changes on: Zope3/trunk/src/zope/app/onlinehelp/tests/output/test2.xml
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: Zope3/trunk/src/zope/app/onlinehelp/tests/test_helpdirectives.py
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/tests/test_helpdirectives.py	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/tests/test_helpdirectives.py	2005-02-17 20:49:07 UTC (rev 29184)
@@ -17,15 +17,28 @@
 """
 import unittest
 
+import zope.app.component
+import zope.app.security
+import zope.app.onlinehelp
+
+from zope.interface import Interface
+from zope.configuration import xmlconfig
+from zope.configuration.xmlconfig import XMLConfig
+from zope.component.interfaces import IFactory
+from zope.component.factory import Factory
 from zope.app.traversing.interfaces import IPhysicallyLocatable
 from zope.app.traversing.interfaces import ITraverser, ITraversable
 from zope.app.onlinehelp import tests
-from zope.app.onlinehelp import help
+from zope.app.onlinehelp import globalhelp
+from zope.app.onlinehelp.onlinehelptopic import OnlineHelpTopic
+from zope.app.onlinehelp.onlinehelptopic import RESTOnlineHelpTopic
+from zope.app.onlinehelp.onlinehelptopic import STXOnlineHelpTopic
+from zope.app.onlinehelp.onlinehelptopic import ZPTOnlineHelpTopic
+from zope.app.security.interfaces import IPermission
+from zope.app.security.permission import Permission
 from zope.app.location.traversing import LocationPhysicallyLocatable
 from zope.app.traversing.adapters import Traverser, DefaultTraversable
 from zope.app.testing import ztapi, placelesssetup
-from zope.configuration import xmlconfig
-from zope.interface import Interface
 
 
 class I1(Interface):
@@ -36,16 +49,34 @@
 
     def setUp(self):
         super(DirectivesTest, self).setUp()
+        ztapi.provideUtility(IPermission, Permission('zope.View', 'View', ''),
+                             'zope.View')
+        XMLConfig('meta.zcml', zope.app.security)()
+        XMLConfig('meta.zcml', zope.app.component)()
+        XMLConfig('meta.zcml', zope.app.onlinehelp)()
         ztapi.provideAdapter(None, ITraverser, Traverser)
         ztapi.provideAdapter(None, ITraversable, DefaultTraversable)
         ztapi.provideAdapter(None, IPhysicallyLocatable,
                              LocationPhysicallyLocatable)
 
+        default = Factory(OnlineHelpTopic)
+        rest = Factory(RESTOnlineHelpTopic)
+        stx = Factory(STXOnlineHelpTopic)
+        zpt = Factory(ZPTOnlineHelpTopic)
+        ztapi.provideUtility(IFactory, default, 'onlinehelp.topic.default')
+        ztapi.provideUtility(IFactory, rest, 'onlinehelp.topic.rest')
+        ztapi.provideUtility(IFactory, stx, 'onlinehelp.topic.stx')
+        ztapi.provideUtility(IFactory, zpt, 'onlinehelp.topic.zpt')
+
     def test_register(self):
-        self.assertEqual(help.keys(), [])
-        self.context = xmlconfig.file("help.zcml", tests)
-        self.assertEqual(help.keys(), ['help1'])
-        topic = help['help1']
+        self.assertEqual(globalhelp.keys(), [])
+        XMLConfig('help.zcml', tests)()
+        res = [u'help4', u'help5', u'help2', u'help3', u'help1']
+        res.sort()
+        helpList = globalhelp.keys()
+        helpList.sort()
+        self.assertEqual(helpList, res)
+        topic = globalhelp['help1']
         self.assert_('test1.png' in topic.keys())
 
 def test_suite():

Added: Zope3/trunk/src/zope/app/onlinehelp/tests/test_treeview.py
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/tests/test_treeview.py	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/tests/test_treeview.py	2005-02-17 20:49:07 UTC (rev 29184)
@@ -0,0 +1,88 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation 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.
+#
+##############################################################################
+"""Onlinehelp tree view Tests
+
+$Id$
+"""
+import os
+
+from unittest import TestCase, TestLoader, TextTestRunner
+
+from zope.pagetemplate.tests.util import check_xml
+from zope.publisher.browser import TestRequest
+from zope.app.site.tests.placefulsetup import PlacefulSetup
+from zope.app.tests import ztapi
+from zope.app.onlinehelp.tests import util
+from zope.app.onlinehelp.interfaces import IOnlineHelp, IOnlineHelpTopic
+from zope.app.onlinehelp.onlinehelp import OnlineHelp
+from zope.app.onlinehelp.onlinehelptopic import OnlineHelpTopic
+from zope.app.onlinehelp.browser.tree import OnlineHelpTopicTreeView
+
+
+def testdir():
+    import zope.app.onlinehelp.tests
+    return os.path.dirname(zope.app.onlinehelp.tests.__file__)
+
+
+class TestOnlineHelpTopicTreeView(PlacefulSetup, TestCase):
+    
+    def setUp(self):
+        PlacefulSetup.setUp(self, site=True)
+        path = os.path.join(testdir(), 'help.txt')
+        self.onlinehelp = OnlineHelp('Help', path)
+        ztapi.provideUtility(IOnlineHelp, self.onlinehelp, "OnlineHelp")
+
+    def test_onlinehelp(self):
+        view = OnlineHelpTopicTreeView
+        treeView = view(self.rootFolder, TestRequest()).getTopicTree
+        check_xml(treeView(), util.read_output('test1.xml'))
+
+    def test_topics(self):
+        path = os.path.join(testdir(), 'help.txt')
+        
+        id = 'topic1'
+        title = 'Topic1'
+        parentPath = ""
+        topic1 = OnlineHelpTopic(id, title, path, parentPath)
+        self.onlinehelp['topic1'] = topic1
+
+        id = 'topic1_1'
+        title = 'Topic1_1'
+        parentPath = 'topic1'
+        topic1_1 = OnlineHelpTopic(id, title, path, parentPath)
+        topic1['topic1_1']  = topic1_1
+
+        id = 'topic1_1_1'
+        title = 'Topic1_1_1'
+        parentPath = 'topic1/topic1_1'
+        topic1_1_1 = OnlineHelpTopic(id, title, path, parentPath)
+        topic1_1['topic1_1_1']  = topic1_1_1
+
+        id = 'topic2'
+        title = 'Topic2'
+        parentPath = ""
+        topic2 = OnlineHelpTopic(id, title, path, parentPath)
+        self.onlinehelp['topic2'] = topic2
+        
+        view = OnlineHelpTopicTreeView
+        treeView = view(self.rootFolder, TestRequest()).getTopicTree
+        check_xml(treeView(), util.read_output('test2.xml'))
+
+
+def test_suite():
+    loader = TestLoader()
+    return loader.loadTestsFromTestCase(TestOnlineHelpTopicTreeView)
+
+if __name__=='__main__':
+    TextTestRunner().run(test_suite())


Property changes on: Zope3/trunk/src/zope/app/onlinehelp/tests/test_treeview.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/app/onlinehelp/tests/util.py
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/tests/util.py	2005-02-17 20:42:31 UTC (rev 29183)
+++ Zope3/trunk/src/zope/app/onlinehelp/tests/util.py	2005-02-17 20:49:07 UTC (rev 29184)
@@ -0,0 +1,31 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation 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.
+#
+##############################################################################
+"""Onlinehelp test utilities
+
+$Id$
+"""
+import os
+import zope.app.onlinehelp.tests
+
+dir = os.path.dirname(zope.app.onlinehelp.tests.__file__)
+input_dir = os.path.join(dir, 'input')
+output_dir = os.path.join(dir, 'output')
+
+def read_input(filename):
+    filename = os.path.join(input_dir, filename)
+    return open(filename, 'r').read()
+
+def read_output(filename):
+    filename = os.path.join(output_dir, filename)
+    return open(filename, 'r').read()


Property changes on: Zope3/trunk/src/zope/app/onlinehelp/tests/util.py
___________________________________________________________________
Name: svn:eol-style
   + native



More information about the Zope3-Checkins mailing list