[Checkins] SVN: zope3org/trunk/src/zorg/wikification/ Added a HTML parser that converts relative into absolute links

Uwe Oestermeier uwe_oestermeier at iwm-kmrc.de
Mon Apr 10 18:10:59 EDT 2006


Log message for revision 66820:
  Added a HTML parser that converts relative into absolute links

Changed:
  U   zope3org/trunk/src/zorg/wikification/browser/README.txt
  U   zope3org/trunk/src/zorg/wikification/browser/configure.zcml
  U   zope3org/trunk/src/zorg/wikification/browser/scripts/link.js
  U   zope3org/trunk/src/zorg/wikification/browser/style/main.css
  U   zope3org/trunk/src/zorg/wikification/browser/templates/linkmenu.pt
  U   zope3org/trunk/src/zorg/wikification/browser/templates/view.pt
  U   zope3org/trunk/src/zorg/wikification/browser/wikilink.py
  U   zope3org/trunk/src/zorg/wikification/browser/wikipage.py
  U   zope3org/trunk/src/zorg/wikification/tests.py

-=-
Modified: zope3org/trunk/src/zorg/wikification/browser/README.txt
===================================================================
--- zope3org/trunk/src/zorg/wikification/browser/README.txt	2006-04-10 21:40:27 UTC (rev 66819)
+++ zope3org/trunk/src/zorg/wikification/browser/README.txt	2006-04-10 22:10:58 UTC (rev 66820)
@@ -124,17 +124,62 @@
 calls and menu items. The additional menu is rendered for text links in 
 brackets and HTML links ...
 
+We have to monkey patch the isEditable method, to ensure that we really
+get modifiable links :
+
+    >>> def return_true() : return True
+    >>> index_page.isEditable = return_true
+
     >>> print index_page.renderBody()
     <BLANKLINE>
     ...
-    ...dropdownlinkmenu...>new page</a>...
+    ...PopupMenu.update...>new page</a>...
     ...
-    ...dropdownlinkmenu...>[New Subject]</a>...
+    ...PopupMenu.update...>[New Subject]</a>...
+    ...   
+    
+The menu is loaded on demand. 
+
+    >>> modified = index_page.getModificationStamp()
+    >>> print index_page.popupLinkMenu('wiki-menu5', modified)
+    <span>
+    <BLANKLINE>
+        <div style="display: true;" class="anylinkcss"
+             id="popup_items">
+            <span class="anylinkheader">Edit this Link</span>
+            <div class="anylinkitem"
+                 onclick="editPlaceholderLabel('wiki-link5', 'wiki-menu5', 'New Subject', '')">
+                Rename
+            </div>
+            <a class="anylinkitem"
+               href="http://127.0.0.1/site/@@wikiedit.html?add=NewSubject">
+                Add Page
+            </a>
+            <div class="anylinkitem"
+                 onclick="PopupMenu.showForm('create_folder5')">
+                Create Folder
+            </div>
+            <div class="anylinkitem"
+                 onclick="PopupMenu.showForm('upload_form5')">
+                Upload File
+            </div>
+        </div>
     ...
-    </div>
-    ...   
    
-   
+If the page has change after the loading the user is alerted that the page
+needs a refresh to be up to date:
+
+    >>> print index_page.popupLinkMenu('wiki-menu5', "modified-timestamp")
+    <span>
+        <div id="popup_items">
+            <form class="inline_form">
+                <span class="anylinkheader">The page has been edited. Please reloaad.
+                </span>
+                <input name="reload" id="reload" type="submit" onselect="window.reload()" value="Reload Page">
+            </form>
+        </div>
+    ...    
+
 Some of the menu items allow the user to edit the link within the view page.
 
     >>> from zorg.wikification.browser.wikipage import EditWikiPage
@@ -144,13 +189,13 @@
 quite easily:
 
     >>> request.form = dict(label='New Label')
+    >>> edit_page.isEditable = return_true
     >>> print edit_page.modifyLink(cmd='rename', link_id='wiki-link5')
     <BLANKLINE>
     ...
-    ...dropdownlinkmenu...[New Label]...
+    ...PopupMenu.update...[New Label]...
     ...
-    </div>
-    ...      
+      
     
 One of the most usefull options is to upload a new file in one step. 
 We have to consider the interesting usecase here that a wikilink with a

Modified: zope3org/trunk/src/zorg/wikification/browser/configure.zcml
===================================================================
--- zope3org/trunk/src/zorg/wikification/browser/configure.zcml	2006-04-10 21:40:27 UTC (rev 66819)
+++ zope3org/trunk/src/zorg/wikification/browser/configure.zcml	2006-04-10 22:10:58 UTC (rev 66820)
@@ -40,7 +40,23 @@
       permission="zope.View"
       title="Wiki"
       menu="zmi_views" />  
-      
+     
+    <page
+        class=".wikipage.WikiFilePage"
+        for="zope.app.file.interfaces.IFile"
+        name="popupLinkMenu"
+        attribute="popupLinkMenu"
+        permission="zope.View"
+        />
+
+    <page
+        class=".wikipage.WikiContainerPage"
+        for="zope.app.folder.interfaces.IFolder"
+        name="popupLinkMenu"
+        attribute="popupLinkMenu"
+        permission="zope.View"
+        />
+
     <pages  
       for="zorg.comment.IAttributeAnnotableComments"
       class="zorg.wikification.browser.comment.LiveComments"
@@ -76,7 +92,7 @@
       class=".wikipage.EditWikiPage"
       for="zope.app.file.interfaces.IFile"
       permission="zope.ManageContent">
-       
+               
       <page
         name="modifyLink"
         attribute="modifyLink" />
@@ -100,7 +116,7 @@
       class=".wikipage.EditWikiContainerPage"
       for="zope.app.folder.interfaces.IFolder"
       permission="zope.ManageContent">
-       
+               
       <page
         name="modifyLink"
         attribute="modifyLink" />

Modified: zope3org/trunk/src/zorg/wikification/browser/scripts/link.js
===================================================================
--- zope3org/trunk/src/zorg/wikification/browser/scripts/link.js	2006-04-10 21:40:27 UTC (rev 66819)
+++ zope3org/trunk/src/zorg/wikification/browser/scripts/link.js	2006-04-10 22:10:58 UTC (rev 66820)
@@ -1,56 +1,102 @@
-function dropdownlinkmenu(obj, e, dropmenuID)   {
-    if (window.event) 
-        event.cancelBubble=true
-    else if (e.stopPropagation) 
-        e.stopPropagation()
-    hidelinkmenu(obj, e, dropmenuID)
-    
-    return clickreturnvalue()
-}
 
-function hidelinkmenu(obj, e, dropmenuID) {
-    if (typeof dropmenuobj!="undefined") //hide previous menu
-            
-            dropmenuobj.style.visibility="hidden"
-            clearhidemenu()
-            if (ie5||ns6){
-                obj.onmouseout=delayhidemenu
-                dropmenuobj=document.getElementById(dropmenuID)
-                if (hidemenu_onclick) dropmenuobj.onclick=function(){dropmenuobj.style.visibility='hidden'}
-                dropmenuobj.onmouseover=clearhidemenu
-                dropmenuobj.onmouseout=ie5? function(){ dynamichide(event)} : function(event){ dynamichide(event)}
-                
-                
-                showhide(dropmenuobj.style, e, "visible", "hidden")
+var PopupMenu = {
 
-                var offsets = Position.cumulativeOffset(obj)
-                
-                var x = offsets[0]  // offsets[0]-clearbrowseredge(obj, "leftedge")+"px"
-                var y = offsets[1]
-                
-                if (dropmenuobj.y) {
-                    y = Math.max(Event.pointerY(e), dropmenuobj.y, y)  // -clearbrowseredge(obj, "bottomedge")+obj.offsetHeight+"px"
-                    }
-                
-                dropmenuobj.x=x
-                dropmenuobj.y=y
+    dropmenuID : "",
 
-                dropmenuobj.style.left=x + "px"
-                dropmenuobj.style.top=y + "px"
+    initialize : function() {
+        document.onmousedown = PopupMenu.onMouseDown;
+        },
+            
+    update : function (caller, dropmenuID)  {
+        document.onmousedown = PopupMenu.onMouseDown;
+        if (PopupMenu.dropmenuID != dropmenuID) {
+            PopupMenu.close();
+            var timestamp =  $('modification_stamp').innerHTML;
+            timestamp = timestamp.replace(/\+/g, '%2b');        // Obey + in datetime str format
+            timestamp = "&modification_stamp=" + timestamp;
+            
+            new Ajax.Updater('wiki_popup_menu', './@@popupLinkMenu', 
+                { parameters: 'menu_id='+ dropmenuID + timestamp});
+            PopupMenu.dropmenuID = dropmenuID  
+            PopupMenu.placeNextTo(caller);
             }
-}            
+        },
 
+    close : function (event) {
+        if ($('wiki_popup_menu').innerHTML) {
+            $('wiki_popup_menu').innerHTML = "";
+            }
+        PopupMenu.dropmenuID = "";
+        },
+        
+    alertReload : function () {
+        alert("Reload");
+        },
+        
+    editPlaceholderLabel : function (link_id, menu_id, label, extra) {
+        PopupMenu.close();
+        var newLabel = prompt('Enter a new label.',  label);
+        if (newLabel) {
+            var params = '&label=' + newLabel + extra;
+            new Ajax.Updater('main', './@@modifyLink', 
+                { parameters: 'cmd=rename&link_id='+ link_id + params,
+                    asynchronous:true});
+            }
+        },
 
-function editPlaceholderLabel(link_id, menu_id, label, extra) {
+        
+    submitForm : function (id, form) {
+        new Ajax.Updater('main', './@@modifyLink', {
+            parameters:Form.serialize(form),
+            onError: function(request) { alert("Sorry, a server error occurred."); },
+            onComplete: function(request) { PopupMenu.hideForm(id); }
+            });
+        return false;  
+        },
+        
+    showForm : function (id) {
+        Element.hide('popup_items');
+        Element.show(id);
+        },
+        
+    hideForm : function (id) {
+        Element.hide(id);
+        PopupMenu.close();
+        },
+        
+    placeNextTo : function(obj) {
+        var offsets = Position.positionedOffset(obj)
+                
+        var x = offsets[0];
+        var y = offsets[1];
+        var menu = $('wiki_popup_menu');
+        menu.style.left=x + "px";
+        menu.style.top=y + 15 + "px";
+        },
     
-     var newLabel = prompt('Enter a new label.',  label);
-   
-     if (newLabel) 
-        {
-        new Ajax.Updater('main', './@@modifyLink', { parameters: 'cmd=rename&link_id='+ link_id + '&label=' + newLabel + extra, asynchronous:true});
+    
+    onMouseDown : function (event) {
+        if (!event) var event = window.event; // IE compatibility
+        
+        if (event.target) {
+            targ = event.target;
+            }
+        else if (event.srcElement) {
+            targ = event.srcElement;
+            }
+        
+        var node = targ;
+        while (node) {
+            if (node == $('wiki_popup_menu')) {
+                return;
+                }
+            node = node.parentNode;
+            }
+            
+        PopupMenu.close();
         }
-
 }
 
 
+window.onload = PopupMenu.initialize;
 

Modified: zope3org/trunk/src/zorg/wikification/browser/style/main.css
===================================================================
--- zope3org/trunk/src/zorg/wikification/browser/style/main.css	2006-04-10 21:40:27 UTC (rev 66819)
+++ zope3org/trunk/src/zorg/wikification/browser/style/main.css	2006-04-10 22:10:58 UTC (rev 66820)
@@ -33,14 +33,16 @@
     width: 400px;
 }
 
+#wiki_popup_menu {
+    position:absolute;
+    z-index: 100;
+}
+
 .anylinkcss {
-    position:absolute;
-    visibility: hidden;
     border:1px solid #666666;
     border-bottom-width: 0;
     font:normal 10px Verdana;
     line-height: 18px;
-    z-index: 100;
     background-color: #EDF0F4;
     width: 150px;
 }

Modified: zope3org/trunk/src/zorg/wikification/browser/templates/linkmenu.pt
===================================================================
--- zope3org/trunk/src/zorg/wikification/browser/templates/linkmenu.pt	2006-04-10 21:40:27 UTC (rev 66819)
+++ zope3org/trunk/src/zorg/wikification/browser/templates/linkmenu.pt	2006-04-10 22:10:58 UTC (rev 66820)
@@ -1,5 +1,14 @@
 <span>
-    <div class="anylinkcss" tal:attributes="id view/menu_id" >
+    <div tal:condition="view/outdated" id="popup_items">
+        <form class="inline_form" >
+            <span class="anylinkheader">The page has been edited. Please reloaad.
+            </span>
+            <input name="reload" id="reload" 
+                type="submit" onselect="window.reload()" 
+                value="Reload Page">
+        </form>
+    </div>
+    <div tal:condition="not: view/outdated" style="display: true;" class="anylinkcss" id="popup_items">
         <span class="anylinkheader">Edit this Link</span>
         <div class="anylinkitem" onclick="editPlaceholderLabel();"
              tal:attributes="onclick string:editPlaceholderLabel('${view/link_id}', '${view/menu_id}', '${view/unicodeLabel}', '');">
@@ -8,10 +17,10 @@
         <a class="anylinkitem" href="#" tal:attributes="href view/link">
             Add Page
         </a>
-        <div class="anylinkitem" tal:attributes="onclick string:Toggle.display('create_folder${view/index}');">
+        <div class="anylinkitem" tal:attributes="onclick string:PopupMenu.showForm('create_folder${view/index}');">
             Create Folder
         </div>
-        <div class="anylinkitem" tal:attributes="onclick string:Toggle.display('upload_form${view/index}');">
+        <div class="anylinkitem" tal:attributes="onclick string:PopupMenu.showForm('upload_form${view/index}');">
             Upload File
         </div>
     </div>
@@ -19,7 +28,7 @@
         <form method="post"
                enctype="multipart/form-data"
                action="uploadFile"
-               tal:attributes="onreset string:Toggle.display('upload_form${view/index}');">
+               tal:attributes="onreset string:PopupMenu.hideForm('upload_form${view/index}');">
             <h4>Upload File</h4>
             <input name="link_id" type="hidden" tal:attributes="value string:${view/link_id}" />
             <table>
@@ -70,8 +79,8 @@
     <div class="inline_form" tal:attributes="id string:create_folder${view/index}" style="display:none;">
         <form method="post"
                enctype="multipart/form-data"
-               onsubmit="new Ajax.Updater('main', './@@modifyLink', {parameters:Form.serialize(this)}); return false;"  
-               tal:attributes="onreset string:Toggle.display('create_folder${view/index}');">
+               tal:attributes="onsubmit string:PopupMenu.submitForm('create_folder${view/index}', this);;;
+                               onreset string:PopupMenu.hideForm('create_folder${view/index}');;">
             <h4>Create Folder</h4>
             <input name="link_id" type="hidden" tal:attributes="value string:${view/link_id}" />
             <input name="cmd" type="hidden" value="folder" />

Modified: zope3org/trunk/src/zorg/wikification/browser/templates/view.pt
===================================================================
--- zope3org/trunk/src/zorg/wikification/browser/templates/view.pt	2006-04-10 21:40:27 UTC (rev 66819)
+++ zope3org/trunk/src/zorg/wikification/browser/templates/view.pt	2006-04-10 22:10:58 UTC (rev 66820)
@@ -65,6 +65,8 @@
 				<div id="main">
 					<div tal:content="structure view/renderBody" />
 				</div>
+				<div id="wiki_popup_menu"></div>
+				<div id="modification_stamp" tal:content="view/getModificationStamp"></div>
 			</div>
 
 			<div class="col second">

Modified: zope3org/trunk/src/zorg/wikification/browser/wikilink.py
===================================================================
--- zope3org/trunk/src/zorg/wikification/browser/wikilink.py	2006-04-10 21:40:27 UTC (rev 66819)
+++ zope3org/trunk/src/zorg/wikification/browser/wikilink.py	2006-04-10 22:10:58 UTC (rev 66820)
@@ -113,12 +113,69 @@
         
     def unicodeLabel(self) :
         return unicode(self.editableLabel(), encoding='utf-8')
+ 
+ 
+class BaseLinkProcessor(BaseHTMLProcessor) :
+    """ Implements a processor that is able to visit and modify all links. 
+    """
+
+    def isAbsoluteURL(self, link) :
+        """ Returns true if the link is a complete URL. 
+            
+            Note that an absolute URL in this sense 
+            might point to a local object.
+        """
         
+        for prefix in 'http:', 'ftp:', 'https:', 'mailto:' :
+            if link.startswith(prefix) :
+                return True
+        return False
+
+class RelativeLinkProcessor(BaseLinkProcessor) :
+    """ Implements a processor that converts all relative links
+        into absolute ones. 
+     
+        >>> html = '''<p><a href="http://www.iwm-kmrc.de">Absolute</a></p>
+        ...           <p><a href="relative">Relative</a></p>'''
         
-class BaseLinkProcessor(BaseHTMLProcessor) :
+        >>> processor = RelativeLinkProcessor("http://www.iwm-kmrc.de")
+        >>> processor.feed(html)
+        >>> print processor.output()
+        <p><a href="http://www.iwm-kmrc.de">Absolute</a></p>
+        <p><a href="http://www.iwm-kmrc.de/relative">Relative</a></p>
+       
+        
+    """
+ 
+    def __init__(self, base_url) :
+        BaseHTMLProcessor.__init__(self)
+        self.base_url = base_url
+
+    def unknown_starttag(self, tag, attrs):
+        """ Called for each tag. Wikifies links. """
+        
+        if tag == "a" :
+            href = ""
+            result = []
+            for key, value in attrs :
+                if key == "href" :
+                    if value and not self.isAbsoluteURL(value) :
+                        value = "%s/%s" % (self.base_url, value)
+                result.append((key, value))
+           
+            BaseHTMLProcessor.unknown_starttag(self, tag, result) 
+            return True
+     
+        BaseHTMLProcessor.unknown_starttag(self, tag, attrs)               
+
+       
+        
+        
+class WikiLinkProcessor(BaseLinkProcessor) :
     """ A link processor that wikifies the links by modifying the
         href and other attributes of a link.
         
+        
     """
     
     implements(ILinkProcessor)
@@ -184,18 +241,6 @@
         self.placeholder = placeholder
         return placeholder        
         
-    def isAbsoluteURL(self, link) :
-        """ Returns true if the link is a complete URL. 
-            
-            Note that an absolute URL in this sense 
-            might point to a local object.
-        """
-        
-        for prefix in 'http:', 'ftp:', 'https:', 'mailto:' :
-            if link.startswith(prefix) :
-                return True
-        return False
-
     def wikifyLink(self, link) :
         """
         Modifies dead relative links and leaves all other links untouched.
@@ -208,7 +253,7 @@
         >>> request = TestRequest()
         >>> from zorg.wikification.browser.wikipage import WikiPage
         >>> page = WikiPage(site, request)
-        >>> processor = BaseLinkProcessor(page)
+        >>> processor = WikiLinkProcessor(page)
         
         Anchors and absolute external links are left unmodified :
         
@@ -343,25 +388,25 @@
         >>> from zorg.wikification.browser.wikipage import WikiPage
         >>> page = WikiPage(site, TestRequest())
         
-        >>> link_processor = BaseLinkProcessor(page)
+        >>> link_processor = WikiLinkProcessor(page)
         >>> link_processor.handle_data('A [link]')
         >>> link_processor.pieces
         ['A <a class="wiki-link" href="...@@wikiedit.html?add=link">[link]</a>']
 
         
-        >>> link_processor = BaseLinkProcessor(page)
+        >>> link_processor = WikiLinkProcessor(page)
         >>> link_processor.handle_data('A [link] and [another one]')
         >>> link_processor.pieces
         ['A <a ...>[link]</a> and <a ...>[another one]</a>']
         
         This method also converts urls and email addresses into clickable links:
         
-        >>> link_processor = BaseLinkProcessor(page)
+        >>> link_processor = WikiLinkProcessor(page)
         >>> link_processor.handle_data('Test mailto:jim at zope.org')
         >>> link_processor.pieces
         ['Test <a href="mailto:jim at zope.org">jim at zope.org</a>']
         
-        >>> link_processor = BaseLinkProcessor(page)
+        >>> link_processor = WikiLinkProcessor(page)
         >>> link_processor.handle_data('Test http://www.iwm-kmrc.de')
         >>> link_processor.pieces
         ['Test <a href="http://www.iwm-kmrc.de">http://www.iwm-kmrc.de</a>']
@@ -420,7 +465,7 @@
     >>> site = buildSampleSite()
     
     >>> page = WikiPage(site, TestRequest())
-    >>> processor = BaseLinkProcessor(page)    
+    >>> processor = WikiLinkProcessor(page)    
     >>> placeholder1 = processor.createPlaceholder("Label", "http://link")
     >>> placeholder1.index
     0
@@ -431,15 +476,18 @@
     """
     
     _menu = ViewPageTemplateFile("./templates/linkmenu.pt")
-    _link = '<a class="wiki-link" href="%s" onmouseover="%s" onclick="return clickreturnvalue()"%s>'
+    _link = '<a class="wiki-link" href="%s" onmouseover="%s" %s>'
+    _dimmed = '<span class="dimmed-wiki-link">'
     
     wikified = False
+    outdated = False
+    enabled = True
     
     def __init__(self, processor, index, label, link) :
         super(MenuPlaceholder, self).__init__(processor, index, label, link)
+        self.enabled = processor.page.isEditable()
         self.menu_id = processor.createMenuId(index)
-        
-        self.onMouseOver = "dropdownlinkmenu(this, event, '%s');" % self.menu_id
+        self.onMouseOver = "PopupMenu.update(this, '%s');" % self.menu_id
        
     def startTag(self, attrs) :
         """ Called when a starttag for a placeholder is detected. """
@@ -449,7 +497,11 @@
         if wikified :
             self.wikified = True
             attrs.append(("id", self.link_id))
-            return self._link % (link, self.onMouseOver, self._tagAttrs(attrs))
+            if self.enabled :
+                return self._link % (link, self.onMouseOver, 
+                                                        self._tagAttrs(attrs))
+            else :
+                return self._dimmed
         else :
             pattern = '<a href="%s"%s>'
             return pattern % (self.link, self._tagAttrs(attrs))
@@ -458,12 +510,16 @@
         start = self.startTag([])
         menu = self.afterCloseTag() or ''
         if self.wikified :
-            return "%s[%s]</a>%s" % (start, self.label, menu)
+            if self.enabled :
+                return "%s[%s]</a>%s" % (start, self.label, menu)
+            else :
+                return "[%s]</span>" % self.label
         else :
             return "%s%s</a>%s" % (start, self.label, menu)
             
     def afterCloseTag(self) :
         if self.wikified :
+            return '<span id="outer%s"></span>' % self.menu_id
             menu = self._menu()
             return menu.encode("utf-8")
         return None
@@ -645,7 +701,7 @@
             link = self.link
         return '<a href="%s">' % (link)
 
-class AjaxLinkProcessor(BaseLinkProcessor) :
+class AjaxLinkProcessor(WikiLinkProcessor) :
     """ A link processor that wikifies the links by modifying the
         href of a link and additionally inserting a javascript based menu
         that allows the user to choose an edit option. 

Modified: zope3org/trunk/src/zorg/wikification/browser/wikipage.py
===================================================================
--- zope3org/trunk/src/zorg/wikification/browser/wikipage.py	2006-04-10 21:40:27 UTC (rev 66819)
+++ zope3org/trunk/src/zorg/wikification/browser/wikipage.py	2006-04-10 22:10:58 UTC (rev 66820)
@@ -32,6 +32,9 @@
 from zope.app.session.interfaces import ISession
 from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
 
+from zope.security import canAccess
+from zope.security.interfaces import ForbiddenAttribute
+
 from zope.publisher.browser import TestRequest
 from zope.i18n import MessageIDFactory
 
@@ -113,11 +116,30 @@
             return IZopeDublinCore(file).description or u""
         return u""
 
+    def isEditable(self) :
+        try :
+            return canAccess(self.container, '__setitem__')
+        except ForbiddenAttribute :
+            return False
+        
+        
     def renderAbstract(self) :
         """ Render the abstract as ReST. """
         desc = self.getAbstract()
         return zorg.restsupport.text2html(desc)
         
+    def getModificationStamp(self) :
+        """ Returns a time stamp that indicates the last modification time. 
+        
+        See browser/README.txt for a test.
+        
+        """
+        file = self.getFile()
+        dc = IZopeDublinCore(file, None)
+        if dc is not None :
+            return str(dc.modified)
+        return None
+        
     def wikify(self, body) :
         """ 
             Renders HTML with dead relative links as 'wikified' HTML,
@@ -145,6 +167,21 @@
         processor.feed(body)
         return processor.output()
      
+    def popupLinkMenu(self, menu_id, modification_stamp, current_stamp=None) :
+        """ Render the popup link menu. """
+        
+        modification_stamp = str(modification_stamp)        
+        link_id = menu_id.replace("menu", "link")
+        processor = ILinkProcessor(self)
+        processor.link_id = link_id
+        body = self.getBody()
+        processor.feed(body)
+        placeholder = processor.placeholders.get(link_id)
+        
+        if current_stamp is None :
+            current_stamp = self.getModificationStamp()
+        placeholder.outdated = modification_stamp != current_stamp
+        return placeholder._menu()
       
     def nextURL(self) :
         url = zapi.absoluteURL(self.context, self.request)
@@ -241,6 +278,7 @@
         return u"Sorry, not wikifiable at the moment."
             
 
+
 class EditOptions(PageElement) :
     """ Allows the user to switch between Kupu, Rest and 
         other edit options. 
@@ -539,7 +577,7 @@
         """
         self._modifyLink(cmd, link_id)
         return u'<div id="main">%s</div>' % self.renderBody()
-        
+    
     def updateURL(self) :
         """ The URL for the update POST. """
         url = zapi.absoluteURL(self.context, self.request)

Modified: zope3org/trunk/src/zorg/wikification/tests.py
===================================================================
--- zope3org/trunk/src/zorg/wikification/tests.py	2006-04-10 21:40:27 UTC (rev 66819)
+++ zope3org/trunk/src/zorg/wikification/tests.py	2006-04-10 22:10:58 UTC (rev 66820)
@@ -56,7 +56,7 @@
 from zorg.comment import IAttributeAnnotableComments
 from zorg.wikification.browser.interfaces import ILinkProcessor
 from zorg.wikification.browser.interfaces import IWikiPage
-from zorg.wikification.browser.wikilink import BaseLinkProcessor
+from zorg.wikification.browser.wikilink import WikiLinkProcessor
 
 
 example1 = u"""<html>
@@ -147,7 +147,7 @@
                                             IZopeDublinCore)
  
     
-    zope.component.provideAdapter(BaseLinkProcessor,
+    zope.component.provideAdapter(WikiLinkProcessor,
                                             [IWikiPage], 
                                             ILinkProcessor)
     



More information about the Checkins mailing list