blob: 7f83b31b3a6a695312b499086538f8871bcb0a3a [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2002-2004 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.2//EN"
"document-v12.dtd" [
<!ENTITY a '<code>index.xml</code>'>
<!ENTITY b '<code>todo.xml</code>'>
<!ENTITY s '<code>site.xml</code>'>
]>
<document>
<header>
<title>Menus and Linking</title>
<version>$Revision: 1.13 $</version>
</header>
<body>
<section id="intro">
<title>Introduction</title>
<p>
This document describes Forrest's internal URI space; how it is managed
with &s;, how menus are generated, and how various link schemes (site:,
ext:) work. An overview of the implementation is also provided.
</p>
</section>
<section id="site">
<title>site.xml</title>
<p>
&s; is what we'd call a 'site map' if Cocoon hadn't already claimed
that term. &s; is a loosely structured XML file, acting as a map of the
site's contents. It provides a unique identifier (an XPath address)
for 'nodes' of information in the website. A 'node' of site information
can be:
</p>
<ul>
<li>A category of information, like 'the user guide'. A category may
correspond to a directory, but that is not required.</li>
<li>A specific page, e.g. 'the FAQ page'</li>
<li>A specific section in a page, e.g. "the 'general' section of the FAQ
page" (identified by <code>id="general"</code> attribute)</li>
</ul>
<p>
In addition to providing fine-grained addressing of site info, &s;
allows <em>metadata</em> to be associated with each node, with
attributes or child elements. Most commonly, a <code>label</code>
attribute is used to provide a text description of the node.
</p>
<p>
There are currently two applications of &s;
</p>
<dl>
<dt><link href="#menu_generation">Menu generation</link></dt>
<dd>&s; is used to generate the menus for the HTML website.</dd>
<dt><link href="#semantic_linking">Indirect linking</link></dt>
<dd>&s; provides a basic aliasing mechanism for linking, e.g. one
can write &lt;link href="site:changes"> from anywhere in the site, and
link to the 'changes' information node (translated to changes.html).
More on this below.</dd>
</dl>
<p>
Here is a sample site.xml, a stripped-down version from Forrest's
own <link href="ext:forrest">website</link>:
</p>
<source><![CDATA[
<?xml version="1.0"?>
<site label="Forrest" href="" tab="home"
xmlns="http://apache.org/forrest/linkmap/1.0">
<about label="About">
<index label="Index" href="index.html"/>
<license label="License" href="license.html"/>
<your-project label="Using Forrest" href="your-project.html">
<new_content_type href="#adding_new_content_type"/>
</your-project>
<linking label="Linking" href="linking.html"/>
<changes label="Changes" href="changes.html"/>
<todo label="Todo" href="todo.html"/>
<live-sites label="Live sites" href="live-sites.html"/>
</about>
<community label="Community" href="community/" tab="community">
<index label="About" href="index.html"/>
<howto-samples label="How-To Samples" href="howto/" tab="howto">
<overview label="Overview" href="index.html"/>
<single-page label="Single Page" href="v10/howto-v10.html"/>
<multi-page label="Multi-Page" href="multi/">
<intro label="Intro" href="howto-multi.html"/>
<step1 label="Step 1" href="step1.html"/>
<step2 label="Step 2" href="step2.html"/>
</multi-page>
</howto-samples>
</community>
<references label="References">
<gump label="Apache Gump" href="http://jakarta.apache.org/gump/"/>
<cocoon label="Apache Cocoon" href="http://xml.apache.org/cocoon/"/>
</references>
<external-refs>
<mail-archive href="http://marc.theaimsgroup.com"/>
<xml.apache.org href="http://xml.apache.org/">
<cocoon href="cocoon/">
<ml href="mail-lists.html"/>
<actions href="userdocs/concepts/actions.html"/>
</cocoon>
<forrest href="forrest/"/>
<xindice href="xindice/"/>
<fop href="fop/"/>
</xml.apache.org>
<mail>
<semantic-linking href="http://marc.theaimsgroup.com/?l=forrest-dev
&amp;m=103097808318773&amp;w=2"/>
</mail>
<cool-uris href="www.w3.org/Provider/Style/URI.html"/>
<uri-rfc href="http://zvon.org/tmRFC/RFC2396/Output/index.html"/>
</external-refs>
</site>
]]></source>
<p>As you can see, things are pretty free-form. The rules are as follows:</p>
<ul>
<li>The root element must be 'site', and normal content should be in the
namespace <code>http://apache.org/forrest/linkmap/1.0</code>. Feel
free to mix in your own content (RDF, dublin core, etc) under new
namespaces</li>
<li>Element names are used as identifiers. The <code>foo</code> in
<code>site:foo</code> must therefore be a valid NMTOKEN.</li>
<li>Elements with <code>href</code> attributes can be used as identifiers
in <code>site:</code> URIs</li>
<li>Relative href attribute contents are 'accumulated' by prepending hrefs
from ancestor nodes</li>
<li>Elements without <code>label</code> attributes (and their children)
are not displayed in the menu.</li>
<li>Elements below <code>external-refs</code> are mapped to the
<code>ext:</code> scheme. so <code>ext:cocoon/ml</code> becomes
<code>http://xml.apache.org/cocoon/mail-lists.html</code></li>
</ul>
</section>
<section id="menu_generation">
<title>Generating Menus</title>
<p>
Two files are used to define a site's tabs and menu; &s; and
<code>tabs.xml</code>. Both files are located in
<code>src/documentation/content/xdocs/</code>.</p>
<p>Assume that our <code>tabs.xml</code> looked as follows:</p>
<source><![CDATA[
<tabs ...>
<tab id="home" label="Home" dir=""/>
<tab id="community" label="Community" dir="community" indexfile="mailLists.html"/>
<tab id="howto" label="How-Tos" dir="community/howto"/>
</tabs>
]]></source>
<p>Using the &s; listed above, we would get these menus:</p>
<p>
<img src="images/menu.png" alt="Menu generated from site.xml"/>&nbsp;&nbsp;&nbsp;
<img src="images/menu2.png" alt="Community menu generated from site.xml"/>&nbsp;&nbsp;&nbsp;
<img src="images/menu3.png" alt="Howto menu generated from site.xml"/>
</p>
<p>When using the <code>dir</code> attribute as above the value of the
<code>indexfile</code> parameter is appended to the value of the
<code>dir</code> attribute (together with a preceding '/'). For example,
the link for the community tab above is
<code>community/mailLists.html</code>. Note that <code>indexfile</code>
defaults to <code>index.html</code> if no value is supplied. Therefore the
link for the howto tab is <code>community/howto/index.html</code>.</p>
<section id="tabs-external">
<title>Tabs for External Resources</title>
<p>You can make a tab point to an external resource by using the
<code>href</code> attribute instead of the <code>dir</code> attribute.
The value of <code>href</code> should be the URI of the resource you wish
to link to. For example:</p>
<source><![CDATA[
<tab id="apache" label="XML Apache" href="http://xml.apache.org/"/>
]]></source>
<p>Unlike the <code>dir</code> attribute, the value of <code>href</code>
is left unmodified by Forrest unless it is root-relative and obviously
specifies a directory (ends in '/'). In which case /index.html will be
added</p>
</section>
<section id="selecting-entries">
<title>Selecting menu entries</title>
<p>Forrest decides which menu entries to display by examining the
<code>tab</code> attributes in &s;. All &s; entries with a
<code>tab</code> equal to that of the current page are put in the
menu.</p>
<p>Consider our &s; example:</p>
<source>
&lt;site label="Forrest" href="" <strong>tab="home"</strong>
xmlns="http://apache.org/forrest/linkmap/1.0"&gt;
&lt;about label="About"&gt;
&lt;index label="Index" href="index.html"/&gt;
&lt;license label="License" href="license.html"/&gt;
&lt;your-project label="Using Forrest" href="your-project.html"&gt;
&lt;new_content_type href="#adding_new_content_type"/&gt;
&lt;/your-project&gt;
&lt;linking label="Linking" href="linking.html"/&gt;
....
&lt;/about&gt;
&lt;community label="Community" href="community/" <strong>tab="community"</strong>&gt;
&lt;index label="About" href="index.html"/&gt;
&lt;howto-samples label="How-To Samples" href="howto/" <strong>tab="howto"</strong>&gt;
&lt;overview label="Overview" href="index.html"/&gt;
&lt;single-page label="Single Page" href="v10/howto-v10.html"/&gt;
&lt;multi label="Multi-Page" href="multi/"&gt;
&lt;intro label="Intro" href="howto-multi.html"/&gt;
&lt;step1 label="Step 1" href="step1.html"/&gt;
...</source>
<p>
Every &s; node can potentially have a <code>tab</code> attribute. If
unspecified, nodes inherit the <code>tab</code> of their parent. Thus
everything in the <strong>&lt;about&gt;</strong> section has an implicit
<code>tab="home"</code>.</p>
<note>You can see this by viewing your site's <link
href="abs-menulinks">abs-menulinks</link> pipeline in a
browser.</note>
<p>Say that the user is viewing the <code>linking.html</code>
page. The <strong>&lt;linking&gt;</strong> node has an implicit tab
value of <code>home</code>. Forrest will select <em>all nodes with
tab="home"</em>, and put them in the menu.
</p>
</section>
<section id="other-menu-selection">
<title>Alternative menu selection mechanisms.</title>
<p>
The <code>tab</code> attribute-based scheme for selecting a menu's
entries is not the only one, although it is the most flexible. Here
we describe a few alternatives.
</p>
<section id="dir-menu-selection">
<title>Directory-based selection</title>
<p>In this scheme, each tab corresponds to a directory within the
site. All content below that directory is included in the menu.</p>
<p>
<img src="images/dir-menu.png" alt="Directory-based site menu"/>&nbsp;&nbsp;&nbsp;
<img src="images/dir-menu2.png" alt="community/ directory menu"/>&nbsp;&nbsp;&nbsp;
<img src="images/dir-menu3.png" alt="community/howto/ directory menu"/>
</p>
<p>
To use this scheme:
</p>
<ul>
<li>Edit <code>forrest.properties</code> and set
<code>project.menu-scheme=directories</code></li>
<li>Remove the <code>id</code> attributes from <code>tabs.xml</code>
entries.</li>
</ul>
</section>
<section id="book-menu-selection">
<title>Specifying menus with book.xml</title>
<p>
Historically, menus in Forrest have been generated from a
<code>book.xml</code> file, one per directory. This mechanism is
still available, and if a <code>book.xml</code> is found, it will be
used in preference to the &s;-generated menu. <code>book.xml</code>
files can use <code>site:</code> URIs to ease the maintenance burden
that led to book.xml's obsolescence. In general, however, we
recommend that users avoid <code>book.xml</code>.
</p>
</section>
</section>
<section id="tab-selection">
<title>Selecting the current tab</title>
<p>
The tab selection algorithm is quite simple: the tab with the
<code>id</code> matching that of the current <code>site.xml</code>
node is "selected".
</p>
</section>
</section>
<section id="toc-generation">
<title>Table of Contents Generation</title>
<p>Each page can have an automatically generated table of contents. This
is created from the titles of each section in your xdoc. By default only
sections up to two levels deep are included and the table of contents is
displayed at the top of the page. However, you can configure this
behaviour in <code>src/documentation/skinconf.xml</code> using the <code>toc</code>
element.</p>
<source><![CDATA[
<toc level="2" location="page"/>
]]></source>
<ul>
<li><strong><code>level</code></strong> - is the depth to which you
want your table of contents to go. Setting it to 3 will therefore
include sections nested to 3 levels. Setting this to 0 will result in
no table of contents being generated.</li>
<li><strong><code>location</code></strong> - indicates where you
want the table of contents to be rendered. It can be set to one of
three values:
<ul>
<li><code>page</code> - the table of contents will be rendered
at the top of the body of your page</li>
<li><code>menu</code> - the table of contents will be rendered
in the menu to the left of the body of the page</li>
<li><code>menu, page</code> - table of contents will be rendered
in both the page and the menu positions</li>
</ul>
</li>
</ul>
</section>
<section id="linking">
<title>Linking systems</title>
<section id="direct-linking">
<title>Direct linking</title>
<p>
In earlier versions of Forrest (and in similar systems), there has
been only one URI space: that of the generated site. If &a; wants to
link to &b; then &a; would use
</p>
<source>
&lt;link href="todo.html">to-do list&lt;link>
</source>
<p>
The theoretical problem with this is that the content producer should
not know or care how Forrest is going to render the source. A URI
should only <em>identify</em> a resource, not specify it's type [<link
href="ext:semantic-linking">mail ref</link>] [<link
href="ext:cool-uris">cool URIs</link>]. In fact, as Forrest
typically renders to multiple output formats (HTML and PDF), links in
one of them (here, the PDF) are likely to break.
</p>
</section>
<section id="indirect-linking">
<title>Indirect linking</title>
<p>
Forrest's solution is simple: instead of &lt;link href="todo.html">,
write &lt;link href="site:todo">, where:
</p>
<dl>
<dt>site</dt>
<dd>is a URI 'scheme'; a namespace that restricts
the syntax and semantics of the rest of the URI [<link
href="ext:uri-rfc">rfc2396</link>]. The semantics of 'site' are
"this identifier locates something in the site's XML sources".</dd>
<dt>todo</dt>
<dd>identifies the content in <code>todo.xml</code>, by reference to a
'node' of content declared in &s;.</dd>
</dl>
<p>
We call this indirect, or <em>semantic</em> linking because instead of
linking to a physical representation (todo.html), we've linked to the
'idea' of "the todo file". It doesn't matter where it physically lives;
that will be sorted out by Forrest.
</p>
<section id="resolve-site-uris">
<title>Resolving site: URIs</title>
<p>
How exactly does <code>site:todo</code> get resolved? A full answer
is provided in the <link href="#implementation">implementation</link>
section. Essentially, the <code>todo</code> part has
<code>/site//</code> prepended, and <code>/@href</code> appended, to
form string <code>/site//todo/@href</code>. This is
then used as an XPath expression in &s; identifying the string
replacement, in this case <code>todo.html</code>.
</p>
<p>
Thus by modifying the XPath prefix and suffix, just about any XML
format can be accommodated.
</p>
<note>
Actually, the XPath is applied to XML generated dynamically from
&s;. The generated XML has @href's fully expanded ('absolutized')
and ..'s added ('relativized') as needed.
</note>
<p>
Notice that the '//' allows us any degree of specificity when linking.
In the sample &s; above, both <code>site:new_content_type</code> and
<code>site:about/your-project/new_content_type</code> identify the
same node. It is up to you to decide how specific to make links. One
nice benefit of link 'ambiguity' is that &s; can be reorganized
without breaking links. For example, 'new_content_type' currently
identifies a node in 'your-project'. By leaving that fact unspecified
in <code>site:new_content_type</code>, we are free to make
'new_content_type' its own XML file, or a node in another file, in
another category.
</p>
</section>
<section id="resolve-ext-uris">
<title>ext: URIs: linking to external URLs</title>
<p>
The <code>ext:</code> scheme was created partly to demonstrate the
ease with which new schemes can be defined, and partly for practical
use. <code>ext:</code> URIs identify nodes in &s; below the
&lt;external-refs&gt; node. By convention, nodes here link to URLs
outside the website, and are not listed in the menu generated from
&s;.
</p>
<p>Here is a &s; snippet illustrating <code>external-refs</code>:</p>
<source><![CDATA[
<site>
...
<external-refs>
<mail-archive href="http://marc.theaimsgroup.com"/>
<xml.apache.org href="http://xml.apache.org/">
<cocoon href="cocoon/">
<ml href="mail-lists.html"/>
<actions href="userdocs/concepts/actions.html"/>
</cocoon>
</xml.apache.org>
<forrest href="forrest/"/>
<xindice href="xindice/"/>
<fop href="fop/"/>
...
</external-refs>
</site>
]]></source>
<p>
As an example, &lt;link href="ext:cocoon/ml"&gt;
generates the link <link
href="ext:cocoon/ml">http://xml.apache.org/cocoon/mail-lists.html</link>
</p>
<p>
The general rules of &s; and <code>site:</code> linking apply.
Specifically, the @href aggregation makes defining large numbers of
related URLs easy.
</p>
</section>
<section id="source-uris">
<title>Theory: source URIs</title>
<p>
<code>site:</code> URIs like <code>site:todo</code> are examples of
<em>source</em> URIs, in contrast to the more usual
<code>foo.html</code>-style URIs, which we here call
<em>destination</em> URIs. This introduces an important concept: that
the <em>source</em> URI space exists and is independent of that of the
generated site. Furthermore, URIs (ie, links) are first-class objects,
on par with XML documents, in that just as XML content is transformed,
so are the links. Within the source URI space, we can have all sorts of
interesting schemes (person:, mail:, google:, java:, etc). These will
all be translated into plain old <code>http:</code> or relative URIs
in the destination URI space, just like exotic XML source formats are
translated into plain old HTML in the output.
</p>
</section>
<section id="future-schemes">
<title>Future schemes</title>
<p>
So far, <code>site:</code> and <code>ext:</code> schemes are defined.
To give you some ideas on other things we'd like to implement (and
we'd welcome help implementing), here are a few possibilities.
</p>
<table>
<tr><th>Scheme</th><th>Example 'From'</th><th>Example 'To'</th><th>Description</th></tr>
<tr>
<td>java</td>
<td>java:org.apache.proj.SomeClass</td>
<td><code>../../apidocs/org/apache/proj/SomeClass.html</code></td>
<td>
Links to documentation for a Java class (typically generated by
<code>javadoc</code>).
</td>
</tr>
<tr>
<td>mail</td>
<td>mail::&lt;Message-Id></td>
<td><code>http://marc.theaimsgroup.com?t=12345678</code></td>
<td>
Links to an email, identified by its <code>Message-Id</code>
header. Any mail archive website could be used.
</td>
</tr>
<tr>
<td>search</td>
<td>search:&lt;searchterm></td>
<td><code>http://www.google.com/search?q=searchterm</code></td>
<td>Link to set of results from a search engine</td>
</tr>
<tr>
<td>person</td>
<td>person:JT, person:JT/blog etc</td>
<td><code>mailto:jefft&lt;at&gt;apache.org</code>,
<code>http://www.webweavertech.com/jefft/weblog/</code>, etc:</td>
<td>
A <code>person:</code> scheme could be used, say, to insert an
automatically obfuscated email address, or link to a URI in some
way associated with that person.
</td>
</tr>
</table>
<p>
There are even more possibilities in specific environments. In an
intranet, a <code>project:XYZ</code> scheme could identify company
project pages. In a project like <link href="ext:ant">Apache
Ant</link>, each Task could be identified with
<code>task:&lt;taskname&gt;</code>, eg <code>task:pathconvert</code>.
</p>
</section>
</section>
</section>
<section id="concept">
<title>Concept</title>
<p>
The <code>site:</code> scheme and associated ideas for &s; were
originally described in <link href="ext:linkmaps">the 'linkmap' RT
email</link> to the forrest-dev list (RT means 'random thought'; a
Cocoon invention). Only section 2 has been implemented, and there is
still significant work required to implement the full system
described. In particular, there is much scope for automating the
creation of &s; (section 4). However, what is currently implemented
gains most of the advantages of the system.
</p>
</section>
<section id="implementation">
<title>Implementation</title>
<p>Full details on the implementation of <link
href="site:linkrewriting_impl">link rewriting</link> and <link
href="site:menu_generation_impl">menu generation</link> are available in
the <link href="site:sitemap-ref">Sitemap Reference</link></p>
</section>
</body>
</document>