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:
parent
76656cdd88
commit
553f4e3f27
5 changed files with 93 additions and 50 deletions
|
@ -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.')
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
"""
|
||||||
|
|
Loading…
Add table
Reference in a new issue