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):
""" Abstract base class. """
implements(ILinkProcessor)
parent = None # parent (tree) processor
source = request = None
targetName = ''
def __init__(self, context):
self.node = self.context = context
self.parent = context.document
self.context = context
def getProperties(self):
raise ValueError("Method 'getProperties()' must be implemented by subclass.")
def process(self, atts):
#print 'processing reference:', self.node
props = self.getProperties()
source = self.parent.context
wiki = source.getWiki()
def process(self):
wiki = self.source.getWiki()
manager = wiki.getManager()
sourceUid = manager.getUid(source)
name = props['targetName']
lmName = source.getConfig('linkManager')
sourceUid = manager.getUid(self.source)
lmName = self.source.getConfig('linkManager')
lm = wiki.getManager().getPlugin(ILinkManager, lmName)
existing = lm.query(source=sourceUid, name=name)
existing = lm.query(source=sourceUid, name=self.targetName)
if existing:
link = existing[0]
target = manager.getObject(link.target)
else:
target = wiki.getPage(name)
target = wiki.getPage(self.targetName)
targetUid = manager.getUid(target)
link = lm.createLink(name, sourceUid, targetUid)
link = lm.createLink(self.targetName, sourceUid, targetUid)
if link.refuri is None:
request = self.parent.request
if request is not None:
if self.request is not None:
if target is None:
link.refuri = '%s/create.html?linkid=%s' % (
absoluteURL(wiki, request), link.identifier)
absoluteURL(wiki, self.request), link.identifier)
else:
link.refuri = absoluteURL(target, request)
#self.setProperty('href', link.refuri)
atts['href'] = link.refuri
link.refuri = absoluteURL(target, self.request)
self.setURI(link.refuri)
if target is None:
# change CSS class, link text
# needs overriding of HTMLTranslator.visit_reference()
#self.setProperty('class', 'create') # no direct effect
atts['class'] += ' create'
self.node.insert(0, Text('?'))
self.markPresentation('create')
self.addText('?')
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):
self.writer = HTMLWriter()
self.writer.translator_class = HTMLBodyTranslator
self.writer.translator_class = BodyTranslator
def write(self, tree):
return publish_from_doctree(tree, writer=self.writer)
class HTMLBodyTranslator(HTMLTranslator):
class BodyTranslator(HTMLTranslator):
def astext(self):
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):
assert len(node) == 1 and isinstance(node[0], nodes.image)
atts['class'] += ' image-reference'
# wiki processing:
node.document = self.document
self.processNode(node, atts)
# wiki processing
htmlNode = HTMLReferenceNode(self.document, node, atts)
self.processNode(htmlNode)
self.body.append(self.starttag(node, 'a', '', **atts))
def processNode(self, node, atts):
procs = []
def processNode(self, htmlNode):
processorNames = self.document.context.getConfig('nodeProcessors')
procNames = processorNames.get(node.tagname, [])
procNames = processorNames.get(htmlNode.node.tagname, [])
for n in procNames:
proc = component.queryAdapter(node, INodeProcessor, name=n)
proc = component.queryAdapter(htmlNode, INodeProcessor, name=n)
if proc is not None:
procs.append(proc)
for p in procs:
p.process(atts)
proc.process()
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.
$Id$
$Id: process.py 3153 2009-01-17 16:51:09Z helmutm $
"""
from docutils.nodes import reference
from zope.interface import implements
from docutils.nodes import Text
from zope.cachedescriptors.property import Lazy
from zope.component import adapts
from zope.interface import implements
from cybertools.wiki.base.link import LinkProcessor
from cybertools.wiki.dcu.html import HTMLReferenceNode
class Reference(LinkProcessor):
adapts(reference)
adapts(HTMLReferenceNode)
def getProperties(self):
return dict(targetName=self.node['refuri'])
@Lazy
def source(self):
return self.context.document.context
def setProperty(self, name, value):
self.node[name] = value
@Lazy
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)
def parse(self, text, context, request=None):
def parse(self, text, context=None, request=None):
tree = publish_doctree(text)
tree.context = context
tree.request = request

View file

@ -145,7 +145,7 @@ class IParser(Interface):
""" Converts from (plain text) input format to internal tree format.
"""
def parse(text):
def parse(text, context=None, request=None):
""" Return internal tree structure.
"""
@ -240,3 +240,22 @@ class ILinkProcessor(INodeProcessor):
""" 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.
"""