Link rewriter
The problem
For linking to some kinds of resources, it would be nice if we had a shortcut mechanism so that we don't have to use the full URL.
An example will help understand what I mean. Suppose you want to link to issues in Daisy's issue database. You could do this by using the full URL to the issue, for example:
http://issues.cocoondev.org/browse/DSY-255
Now what if, intead of this URL, you could simply write the following:
issues:DSY-255
This has a number of advantages:
- the URL format is easy to remember. With the first one, you'll almost always have to copy-and-paste it, while the short format can be done from memory.
- if for some reason the location of the issue database changes, it's easy to update references to it. Well, this shouldn't happen of course, since this would break links for everyone. However, a better example for this might be javadocs: the javadocs of each release of your software could be located at a different URL, and you want links to javadocs to always point to those of the latest release (or maybe even to some release corresponding to the branch of the docs in Daisy).
The solution
Due to the fact that the Daisy Wiki is based on Cocoon, a pipeline based XML publishing and webapplication framework, it is easy to put a new transformer into the document-publishing-pipeline to transform these links. Cocoon has exactly the transformer we need: the linkrewriter transformer.
Basically, you need to tell the linkrewriter transformer which schemes it should handle (here we'll do it for "issues" and "javadoc") and for each such scheme you need to have a Cocoon input module which maps the input string to the target URL. If this sounds like latin to you, don't worry, the cookbook steps follow below. For the particular thing we want to achieve, we need an input module which is not included by default in Cocoon, but one from another Apache project, Forrest. Therefore we'll need to download Forrest too.
The cookbook steps:
Download forrest 0.7 from http://forrest.apache.org/. Extract the download and copy the file build/xml-forrest.jar to daisywiki/webapp/WEB-INF/lib/forrest-0.7.jar
Download http://www.ibiblio.org/maven/cocoon/jars/cocoon-linkrewriter-2.1.8.jar and put it in daisywiki/webapp/WEB-INF/lib
Add in WEB-INF/cocoon.xconf as child of the <input-modules> element the following (as sibling of the other input modules that are defined there):
<component-instance name="issues"
class="org.apache.forrest.locationmap.LocationMapModule"
logger="sitemap.modules.locationmap">
<file src="context://daisy/issues_locationmap.xml"/>
</component-instance>
<component-instance name="javadoc"
class="org.apache.forrest.locationmap.LocationMapModule"
logger="sitemap.modules.locationmap">
<file src="context://daisy/javadoc_locationmap.xml"/>
</component-instance>
This declares two input modules, issues and javadoc, based on the LocationMapModule, with two different configuration files which we'll create in the next step.
An input module, in Cocoon, is a component which simply maps some key to some value.
Create a file webapp/daisy/issues_locationmap.xml
<?xml version="1.0"?>
<locationmap xmlns="http://apache.org/forrest/locationmap/1.0">
<components>
<matchers default="lm">
<matcher
name="lm"
src="org.apache.forrest.locationmap.WildcardLocationMapHintMatcher"/>
</matchers>
</components>
<locator>
<match pattern="*">
<location src="http://issues.cocoondev.org/browse/{1}"/>
</match>
</locator>
</locationmap>
Create a file webapp/daisy/javadoc_locationmap.xml
<?xml version="1.0"?>
<locationmap xmlns="http://apache.org/forrest/locationmap/1.0">
<components>
<matchers default="lm">
<matcher
name="lm"
src="org.apache.forrest.locationmap.WildcardLocationMapHintMatcher"/>
</matchers>
</components>
<locator>
<!-- Note: we're using the 'flow-attr' input module below to translates dots to slashes,
though of course this is not at all related to flow attributes, we're just using
the JXPath-support of that input module. Don't know if there's a nicer way to do
this -->
<match pattern="org.apache.cocoon.*">
<location
src="http://cocoon.apache.org/2.1/apidocs/{flow-attr:translate('{0}', '.', '/')}.html"/>
</match>
<match pattern="java.*">
<location
src="http://java.sun.com/j2se/1.5.0/docs/api/{flow-attr:translate('{0}', '.', '/')}.html"/>
</match>
<match pattern="javax.*">
<location
src="http://java.sun.com/j2se/1.5.0/docs/api/{flow-attr:translate('{0}', '.', '/')}.html"/>
</match>
<match pattern="org.w3c.dom.*">
<location
src="http://java.sun.com/j2se/1.5.0/docs/api/{flow-attr:translate('{0}', '.', '/')}.html"/>
</match>
<match pattern="org.xml.sax.*">
<location
src="http://java.sun.com/j2se/1.5.0/docs/api/{flow-attr:translate('{0}', '.', '/')}.html"/>
</match>
</locator>
</locationmap>
Restart the Daisy Wiki at this point, as the new jars and the changes to cocoon.xconf only have effect after restarting. The changes in the steps that follow require no restarting anymore.
Add in daisywiki/webapp/daisy/sitemap.xmap, as child of <map:transformers>:
<map:transformer logger="sitemap.transformer.linkrewriter" name="linkrewriter"
pool-grow="2" pool-max="32" pool-min="2"
src="org.apache.cocoon.transformation.LinkRewriterTransformer">
<!-- schemes can be a space separeted list -->
<schemes>issues javadoc</schemes>
<!-- link-attrs can be a space separeted list -->
<link-attrs>href</link-attrs>
</map:transformer>
The configuration defines that the linkrewriter transformer should work on all "issues:" and "javadoc:" links occuring in "href" attributes.
In the same sitemap.xmap file, as child of
<map:match pattern="html-StyleDocumentPipe">
ahead of the line
<map:serialize type="xml"/>
add this:
<map:transform type="linkrewriter"/>
And that's all.
Trying it out
Create a document, enter some text, select some text, press the link button on the toolbar, and enter as link URL e.g.:
javadoc:java.lang.String
Select some other text and link it to:
issues:DSY-200
Save the document, and the links in the rendered document should be translated to the actual locations.
Final notes
- Normally we don't recommend changing files that belong to Daisy, such as the daisy/sitemap.xmap, as these are part of the Daisy Wiki implementation. These might change from release to release, as these are not public contracts or extension points. But sometimes you have no choice indeed. In any case, take good note of what you changed, so that when you upgrade Daisy, you can easily find back what needs to be done.
- To have this work for the PDF too, simply add the linkrewriter transformer to the xslfo-StyleDocumentPipe
- For more information about the linkrewriter and the LocationMapModule, refer to the Cocoon and Forrest communities, respectively.



There are no comments.