| <?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 <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 |
| &m=103097808318773&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"/> |
| <img src="images/menu2.png" alt="Community menu generated from site.xml"/> |
| <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> |
| <site label="Forrest" href="" <strong>tab="home"</strong> |
| 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"/> |
| .... |
| </about> |
| |
| <community label="Community" href="community/" <strong>tab="community"</strong>> |
| <index label="About" href="index.html"/> |
| <howto-samples label="How-To Samples" href="howto/" <strong>tab="howto"</strong>> |
| <overview label="Overview" href="index.html"/> |
| <single-page label="Single Page" href="v10/howto-v10.html"/> |
| <multi label="Multi-Page" href="multi/"> |
| <intro label="Intro" href="howto-multi.html"/> |
| <step1 label="Step 1" href="step1.html"/> |
| ...</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><about></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><linking></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"/> |
| <img src="images/dir-menu2.png" alt="community/ directory menu"/> |
| <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> |
| <link href="todo.html">to-do list<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 <link href="todo.html">, |
| write <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 |
| <external-refs> 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, <link href="ext:cocoon/ml"> |
| 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::<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:<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<at>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:<taskname></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> |