clearly separate generic link processing and docutils-spezific node and attribute access

git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@3212 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2009-02-06 11:12:28 +00:00
parent 76656cdd88
commit 553f4e3f27
5 changed files with 93 additions and 50 deletions

View file

@ -98,50 +98,47 @@ class Link(object):
class LinkProcessor(object): class LinkProcessor(object):
""" Abstract base class. """
implements(ILinkProcessor) implements(ILinkProcessor)
parent = None # parent (tree) processor source = request = None
targetName = ''
def __init__(self, context): def __init__(self, context):
self.node = self.context = context self.context = context
self.parent = context.document
def getProperties(self): def process(self):
raise ValueError("Method 'getProperties()' must be implemented by subclass.") wiki = self.source.getWiki()
def process(self, atts):
#print 'processing reference:', self.node
props = self.getProperties()
source = self.parent.context
wiki = source.getWiki()
manager = wiki.getManager() manager = wiki.getManager()
sourceUid = manager.getUid(source) sourceUid = manager.getUid(self.source)
name = props['targetName'] lmName = self.source.getConfig('linkManager')
lmName = source.getConfig('linkManager')
lm = wiki.getManager().getPlugin(ILinkManager, lmName) lm = wiki.getManager().getPlugin(ILinkManager, lmName)
existing = lm.query(source=sourceUid, name=name) existing = lm.query(source=sourceUid, name=self.targetName)
if existing: if existing:
link = existing[0] link = existing[0]
target = manager.getObject(link.target) target = manager.getObject(link.target)
else: else:
target = wiki.getPage(name) target = wiki.getPage(self.targetName)
targetUid = manager.getUid(target) targetUid = manager.getUid(target)
link = lm.createLink(name, sourceUid, targetUid) link = lm.createLink(self.targetName, sourceUid, targetUid)
if link.refuri is None: if link.refuri is None:
request = self.parent.request if self.request is not None:
if request is not None:
if target is None: if target is None:
link.refuri = '%s/create.html?linkid=%s' % ( link.refuri = '%s/create.html?linkid=%s' % (
absoluteURL(wiki, request), link.identifier) absoluteURL(wiki, self.request), link.identifier)
else: else:
link.refuri = absoluteURL(target, request) link.refuri = absoluteURL(target, self.request)
#self.setProperty('href', link.refuri) self.setURI(link.refuri)
atts['href'] = link.refuri
if target is None: if target is None:
# change CSS class, link text self.markPresentation('create')
# needs overriding of HTMLTranslator.visit_reference() self.addText('?')
#self.setProperty('class', 'create') # no direct effect
atts['class'] += ' create'
self.node.insert(0, Text('?'))
def setURI(self, uri):
raise ValueError('To be implemented by subclass.')
def markPresentation(self, feature):
raise ValueError('To be implemented by subclass.')
def addText(self, text):
raise ValueError('To be implemented by subclass.')

View file

@ -37,13 +37,13 @@ class Writer(object):
def __init__(self): def __init__(self):
self.writer = HTMLWriter() self.writer = HTMLWriter()
self.writer.translator_class = HTMLBodyTranslator self.writer.translator_class = BodyTranslator
def write(self, tree): def write(self, tree):
return publish_from_doctree(tree, writer=self.writer) return publish_from_doctree(tree, writer=self.writer)
class HTMLBodyTranslator(HTMLTranslator): class BodyTranslator(HTMLTranslator):
def astext(self): def astext(self):
return u''.join(self.body_pre_docinfo + self.docinfo + self.body) return u''.join(self.body_pre_docinfo + self.docinfo + self.body)
@ -64,18 +64,28 @@ class HTMLBodyTranslator(HTMLTranslator):
if not isinstance(node.parent, nodes.TextElement): if not isinstance(node.parent, nodes.TextElement):
assert len(node) == 1 and isinstance(node[0], nodes.image) assert len(node) == 1 and isinstance(node[0], nodes.image)
atts['class'] += ' image-reference' atts['class'] += ' image-reference'
# wiki processing: # wiki processing
node.document = self.document htmlNode = HTMLReferenceNode(self.document, node, atts)
self.processNode(node, atts) self.processNode(htmlNode)
self.body.append(self.starttag(node, 'a', '', **atts)) self.body.append(self.starttag(node, 'a', '', **atts))
def processNode(self, node, atts): def processNode(self, htmlNode):
procs = []
processorNames = self.document.context.getConfig('nodeProcessors') processorNames = self.document.context.getConfig('nodeProcessors')
procNames = processorNames.get(node.tagname, []) procNames = processorNames.get(htmlNode.node.tagname, [])
for n in procNames: for n in procNames:
proc = component.queryAdapter(node, INodeProcessor, name=n) proc = component.queryAdapter(htmlNode, INodeProcessor, name=n)
if proc is not None: if proc is not None:
procs.append(proc) proc.process()
for p in procs:
p.process(atts)
class HTMLNode(object):
def __init__(self, document, node, atts):
self.document = document
self.node = node
self.atts = atts
class HTMLReferenceNode(HTMLNode):
pass

View file

@ -19,22 +19,39 @@
""" """
Node processor implementations for docutils nodes. Node processor implementations for docutils nodes.
$Id$ $Id: process.py 3153 2009-01-17 16:51:09Z helmutm $
""" """
from docutils.nodes import reference from docutils.nodes import Text
from zope.interface import implements from zope.cachedescriptors.property import Lazy
from zope.component import adapts from zope.component import adapts
from zope.interface import implements
from cybertools.wiki.base.link import LinkProcessor from cybertools.wiki.base.link import LinkProcessor
from cybertools.wiki.dcu.html import HTMLReferenceNode
class Reference(LinkProcessor): class Reference(LinkProcessor):
adapts(reference) adapts(HTMLReferenceNode)
def getProperties(self): @Lazy
return dict(targetName=self.node['refuri']) def source(self):
return self.context.document.context
def setProperty(self, name, value): @Lazy
self.node[name] = value def request(self):
return self.context.document.request
@Lazy
def targetName(self):
return self.context.node['refuri']
def setURI(self, uri):
self.context.atts['href'] = uri
def markPresentation(self, feature):
self.context.atts['class'] += (' ' + feature)
def addText(self, text):
self.context.node.insert(0, Text(text))

View file

@ -32,7 +32,7 @@ class Parser(object):
implements(IParser) implements(IParser)
def parse(self, text, context, request=None): def parse(self, text, context=None, request=None):
tree = publish_doctree(text) tree = publish_doctree(text)
tree.context = context tree.context = context
tree.request = request tree.request = request

View file

@ -145,7 +145,7 @@ class IParser(Interface):
""" Converts from (plain text) input format to internal tree format. """ Converts from (plain text) input format to internal tree format.
""" """
def parse(text): def parse(text, context=None, request=None):
""" Return internal tree structure. """ Return internal tree structure.
""" """
@ -240,3 +240,22 @@ class ILinkProcessor(INodeProcessor):
""" A node processor specialized on links (references). """ A node processor specialized on links (references).
""" """
source = Attribute('The object from which the link originates, '
'typically a wiki page.')
request = Attribute('Optional request or environment object, necessary '
'e.g. for rendering an URI.')
targetName = Attribute('The name used for addressing the link target object.')
def setUri(uri):
""" Record the real reference URI to be used for the link on the
rendered page.
"""
def markPresentation(feature):
""" Record a presentation feature for the link on the rendered page,
for HTML rendering this would be a class name.
"""
def addText(text):
""" Add additional text to the link on the rendered page.
"""