You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@forrest.apache.org by Jeff Turner <je...@apache.org> on 2002/10/12 18:33:29 UTC

[RT] Linking revisited: A general linking system

On Sat, Oct 12, 2002 at 06:04:08AM -0700, Robert Koberg wrote:
> Morning,
...
> - Create the links.xml that is the result of the crawl.
> -- perhaps this can gather other information for things like different skins
> within the same site, what features to turn on, labels, etc
> - Use the links.xml as the main source in a single page transformation
> -- pass in the page-id (P.xml path/filename?) to inidicate what page to
> transform
> -- use the document function to pull in the page's P.xml, book.xml and tabs.xml
> ---- perhaps the crawler creates a hierarchical representation and at folder
> levels you simply have a name attribute. Then you would not need book.xml or
> tabs.xml because you can pull that info from a hierarchical links.xml
> 
> You can use the same links.xml in something like a DefaultHandler to run through
> and transform each page rather quickly. There is a simple example of this in the
> download zip in this faq:
> 
> http://www.dpawson.co.uk/xsl/sect4/N9723.html#d4e306

Mm.. nifty.

I have this RT brewing on how we could use your idea of a links.xml file.
I was waiting till I had time to do a proof of concept, but might as well
throw it out now.  Since you've done it all before, I'd be interested in
your thoughts.  It can be called Kobergian linking ;P Actually
J.Pietschmann posted something similar based on Topic Maps, but I don't
think anyone understood the full idea.

                          -- o --


On Fri, Sep 06, 2002 at 09:29:18AM -0700, Robert Koberg wrote:

> http://marc.theaimsgroup.com/?l=xml-cocoon-users&m=102979611329204&w=2

That is very cool.

A brief outline for others: the idea is to have a file:

<folder id="f123" name="aaa" label="blah1">
  <page id="p123" label="blah2"/>
  <folder id="f234" name="bbb" label="blah3">
    <page id="p234" label="blah4"/>
    <page id="p235" label="blah5"/>
  </folder>
</folder>

Generated statically or dynamically, and then with some cunning <xsl:key>
usage, the XSLTs can link to other files by specifying their id.  This
XML file is the layer between xdoc links and the filesystem.


                          -- o --


1) The linkmap
--------------

This idea can be merged with that of the layout.xml file in Centipede.  Imagine
if we had a 'linkmap' file, where each directory, file and named node is
listed:

<site>
  <index/>
  <dreams/>
  <faq>
    <how_can_I_help/>
    <building_own_website/>
    <building_fails_on_subsequent_builds/>
  </faq>
  <primer/>
  <your-project/>
  <contrib/>
  <who/>
  <libre-intro/>
  <community>
    <howto>
      <index/>
      <cvs-ssh>
        <howto-cvs-ssh/>
      </cvs-ssh>
    </howto>
  </community>
</site>

This is an abstract outline of the site's information content.  Each node is
addressable and link-to-able.

Then in xdoc files, we can link to nodes, rather than files:

  "Read our <link href="site:/site/primer">Forrest Primer</link> ... "
  "See <link href="site:/site/faq/how_can_I_help">this FAQ entry<link> ... "

Likewise, book.xml files would link to nodes, not files.


  1.1) Mapping nodes to sources
  -----------------------------

In order to map this abstract linkmap to the real directory structure,
we can use attributes:

<site dir="./content/xdocs">
  <index file="index.xml"/>
  <dreams file="dreams.xml"/>
  <faq file="faq.xml">
    <how_can_I_help xpath="/faqs/faq/question[@id='how_can_I_help']">
    <building_own_website xpath="/faqs/faq/question[@id='own_website']"/>
    <building_fails_on_subsequent_builds xpath="/faqs/faq/[@id='building_fails']"/>
  </faq>
  <primer file="primer.xml"/>
  <your-project file="your-project.xml"/>
  <contrib dir="contrib"/>
  <who file="who.xml"/>
  <libre-intro file="libre-intro.xml">
  <community dir="community">
    <howto dir="howto">
      <index file="index.xml"/>
      <cvs-ssh dir="cvs-ssh">
        <howto-cvs-ssh file="howto-cvs-ssh.xml"/>
      </cvs-ssh>
    </howto>
  </community>
</site>

Most of these attributes could be inferred, eg node name == file|dir name, so
don't let the verbosity put you off.  Notice the flexibility this allows; we
could rearrange the directory structure and so long as the linkmap is updated,
no links would break.  If we wanted to keep FAQs as individual XML files inside a
faq/ directory, it's very easy.


  1.2) Summary: linkmap + nodes->sources
  --------------------------------------

At this point, we have a "map" from 'nodes' to source XML files, Nodes
are generic units of addressable content.  An XML file can link to another
node by specifying the XPath address of the node in linkmap.xml.
Everything is lovely and abstract, clean and simple.


  1.3) Nodes in the sitemap
  -------------------------

Now that we have a mapping from nodes to XML files, it would be nice if
we could rewrite the sitemap in terms of nodes, not XML files.

We can do this with a new Source.  In the sitemap, we could have:

  <map:generate src="site:/site/faq/how_can_I_help"/>

Which would return the XML for that FAQ.  The Site Source does all the
messy traversal of directories, files and XPath expressions.  So we'd
have:

<map:match pattern="faq/*">
  <map:generate src="site:/site/faq/{1}"/>
  <map:transform src="library/xslt/faq2document.xsl"/>
  ....

Now our sitemap is completely independent of the file system! We could
stick a Xindice database underneath if we wanted, and the sitemap would
still work, so long as our Source could handle Xindice sources.

See those ....'s in the snippet above? That's what the next section deals
with.



2) Mapping nodes to rendered (HTML) files
-----------------------------------------

Now for the hard part: we need a way to 'resolve' a node into a link to a
HTML file, PDF, or other rendering.  We need to be able to go from:

  "Read our <link href="site:/site/primer">Forrest Primer</link> ... "

To:

  "Read our <link href="primer.html">Forrest Primer</link> ... "

Inserting directory traversal if the linkee is in a different directory
to the linker.


Well, just like we use the linkmap to look up XML files (sources), we can
use it to look up HTML files (renderings):


<site href="http://localhost:8080/mysite">
  <index href="index.html"/>
  <dreams href="dreams.html"/>
  <faq href="faq.html">
    <how_can_I_help href="#how_can_I_help">
    <building_own_website href="#own_website"/>
    <building_fails_on_subsequent_builds href="#building_fails"/>
  </faq>
  <primer href="primer.html"/>
  <your-project href="your-project.html"/>
  <contrib href="contrib"/>
  <who href="who.html"/>
  <libre-intro href="libre-intro.html">
  <community href="community">
    <howto href="howto">
      <index href="index.html"/>
      <cvs-ssh href="cvs-ssh">
        <howto-cvs-ssh href="howto-cvs-ssh.html"/>
      </cvs-ssh>
    </howto>
  </community>
</site>

Now all we need is an XSLT stylesheet which translates links from nodes
to HTML files:

//  linkresolver.xsl

<xsl:template match="link">
  <link>
    <xsl:variable name="xpath" select="substring-after(@href, 'site:')"/>
    <xsl:attribute name="href">
      <xsl:value-of select="document('linkmap.xml')/$xpath/@href"/>
    </xsl:attribute>
</xsl:template>


That's the basic idea: a stylesheet translates from abstract node
addresses into the addresses of renderings, with the help of a linkmap.


  2.1) Relativising the linkmap
  -----------------------------

Of course, the above XSLT snippet doesn't handle relative links.  To do
this, we need to "relativise" the linkmap, so all directories are
relative to that of the file currently being rendered.  Eg, if we're
rendering community/howto/index.html, the relativised linkxmap.xml would
look like:


<site href="../../">
  <index href="../../index.html"/>
  <dreams href="../../dreams.html"/>
  <faq href="../../faq.html">
    <how_can_I_help href="../../faq.html#how_can_I_help">
    <building_own_website href="../../faq.html#own_website"/>
    <building_fails_on_subsequent_builds href="../../faq.html#building_fails"/>
  </faq>
  <primer href="../../primer.html"/>
  <your-project href="../../your-project.html"/>
  <contrib href="../../contrib"/>
  <who href="../../who.html"/>
  <libre-intro href="../../libre-intro.html">
  <community href="../">
    <howto href=".">
      <index href="index.html"/>
      <cvs-ssh href="cvs-ssh">
        <howto-cvs-ssh href="cvs-ssh/howto-cvs-ssh.html"/>
      </cvs-ssh>
    </howto>
  </community>
</site>

So if community/howto/index.xml had a link:

<link href="site:/site/faq/how_can_I_help">this faq entry</link>

It would be rendered as:

<a href="../../faq.html#how_can_I_help">this faq entry</a>


So for every directory, the linkmap is going to be different.  This
implies that we should dynamically generate it:

<map:match pattern="**/linkmap.xml">
  <map:generate src="linkmap.xml"/>
  <map:transform src="relativise-linkmap.xsl">
    <map:parameter name="directory" value="{1}"/>
  </map:transform>
  <map:serialize type="xml"/>
</map:match>

I hope that the document() function can resolve a url like
'cocoon:/linkmap.xml'. 


3) Summary and sitemap sketch
-----------------------------

So now we have a 3-way mapping:

*.xml  <--  nodes  -->  *.html

XML files can contain links to abstract nodes, which are translated at
runtime to links to HTML files.

What would the sitemap look like?

It would have two distinguishing features:

 - XML comes from nodes, not files: <map:generate src="site:...."/>
 - Just before each file is rendered, it's links are translated by
   linkresolver.xsl.

Thus we could have:

<!-- Any root directory HTML file -->
<map:match pattern="*.html">
  <map:generate src="site:/site/{1}"/>
  <map:transform src="library/xslt/linkresolver.xsl"/>
  <map:transform src="library/xslt/document2html.xsl"/>
  <map:serialize/>
</map:match>

<!-- A HTML file per FAQ entry -->
<map:match pattern="faq/*.html">
  <map:generate src="site:/site/faq/{1}"/>
  <map:transform src="library/xslt/faq2document.xsl"/>
  <map:transform src="library/xslt/linkresolver.xsl"/>
  <map:transform src="library/xslt/document2html.xsl"/>
  <map:serialize/>
</map:match>

As well as dynamic linkmap generator:

<map:match pattern="**/linkmap.xml">
  <map:generate src="linkmap.xml"/>
  <map:transform src="relativise-linkmap.xsl">
    <map:parameter name="directory" value="{1}"/>
  </map:transform>
  <map:serialize type="xml"/>
</map:match>


That's the basic idea.  Once it's all condensed in one's brain, it's
pretty simple:

Conceptual: 
  - linkmap.xml maps nodes -> {sources, renderings}
  - XML files link to node addresses, not rendering addresses
Implementation:
  - A custom Source resolves nodes to node sources (XML content)
  - A stylesheet resolves nodes to node renderings (HTML URIs)
  - The sitemap uses both of the above to translate from the abstract
    map of content to a physical hypertext of HTML files.

In the coming months I'd like to try prototyping the system to this
stage.



4) Refinements: Automatically generating the linkmap
----------------------------------------------------

In practice, I expect people would get pretty tired of having to keep
updating this linkmap.xml file every time they edit the sitemap (change
node -> HTML mapping) or add/rename an XML source file (change node ->
XML mapping.  Luckily we can infer a lot of the mappings:

 - As stated above, we can have automated rules for generating new nodes
   corresponding to new XML files and "virtual" nodes for each XPath
   expression inside them.  This is fairly easy; just examine the
   filesystem.
 - We can examine the sitemap, and infer mappings from nodes to
   renderings (HTML files).  This is tricky but possible.  Some
   thoughts on this process below.


Here is a bit of our shiny new sitemap:

<map:match pattern="primer.html">
  <map:generate src="site:/site/primer"/>
  ...

<!-- A HTML file per FAQ entry -->
<map:match pattern="faq/*.html">
  <map:generate src="site:/site/faq/{1}"/>
  ...

 <!-- Any root directory HTML file -->
<map:match pattern="*.html">
  <map:generate src="site:/site/{1}"/>

 
Now wouldn't it be possible to see that, and 'invert' it:

site/primer  -> primer.html
site/*       -> {1}.html
/site/faq/*  -> faq/{1}.html

The problem is that a sitemap is really a m:n mapping.

As an example of 1:n mapping:

<map:match pattern="*">
  <map:generate src="site:/foo"/>

Here, we're mapping _every_ source to the same rendering.  So if we
encounter <link href="site:/foo">, what do we link to?  Do we invent a
filename?  Do we avoid this ambiguity by saying the linkmap must
explicitly deal with these scenarios?  I don't know.


Another problem is we commonly have n:1 mapping, eg our everyday
index.html = index.xml + book.xml + tabs.xml merging (n=3):

<map:match pattern="*.html">
  <map:aggregate element="site">
    <map:part src="cocoon:/book-{1}.xml"/>
    <map:part src="cocoon:/tab-{1}.xml"/>
    <map:part src="cocoon:/body-{1}.xml"/>
  </map:aggregate>
  ...

If you reverse-engineer the sitemap, you'll find that '*.html' will
map to a finite set of nodes; in this case, site:/site/*.

This reverse-engineering process could be very tricky, but I think
it's theoretically possible (please correct me here).


  4.1) Summary
  ------------

The ultimate goal is to have the linkmap automatically generated.
Infer the nodes from the filesystem content, and infer the output URIs
from the sitemap and possibly an additional "good URI" policy to deal
with ambiguities.



Congratulations if you got this far.  As I said, I was hoping to
prototype it to clarify the ideas in my head before expecting others
to read them, but a month later I was simply forgetting the details,
so this braindump is as much for my benefit as anyone else.

Ideas most welcome.  In particular, if anyone has played with RDF or
Topic Maps, I'd be interested to hear if the 'linkmap' worth
translating into those domains; I can see there's possibilities for
attaching semantic info (and all sorts of other stuff) to linkmap
entries, as apparently Robert has already discovered.


--Jeff

Re: [RT] Linking revisited: A general linking system

Posted by Jeff Turner <je...@apache.org>.
On Mon, Oct 14, 2002 at 08:21:06AM -0700, Robert Koberg wrote:
> Wow Jeff - really cool brain dump! And also Betrand's concept model! - the
> combination of which can provide for an amazing GUI :)
> 
> This is the kind of thing I have been hoping for in Forrest. With an explicit
> site mapping you can do quite a bit. It is extremely flexible and gives your
> clients and yourself a great number of options when building and maintaining a
> site. I know the way I am doing it works well for the kind of sites I do (they
> can be pregenerated for the most part and are maintained by the client through a
> GUI). Where I fear (know...) my way will break down is on the large sites (who
> wants to use one big file for something like that...) - this is where I was
> hoping for some type of merging with cocoon/forrest.

I've poked around in the download (LSB 1.0).. it's very neat, and quite
far ahead of Forrest.

(Description for others: there are two main organizing files:

site.xml: "a virtual representation the generated project file structure"
content.xml: "a database of content XML filenames that are referenced in the
site.xml's folder's, page's etc" -- much like book.xml

A content.xml snippet:

<?xml version="1.0"?>
<config context="docs" id="docs">
  <folder id="f1">
    <folder id="f1379506232">
      <article id="c2010028878.xml" label="starting" lock="rk123" status="editorial"/>
      <article id="c2122108796.xml" label="why" lock="rk123" status="editorial"/>
      <faqs id="f672903140">
        <faq id="c285248103.xml" label="what XSLT processor" lock="rk123" status="editorial"/>
      </faqs>
      <folder id="f1576487314"/>
      <folder id="f212775916">
        <article id="c1038756828.xml" label="folder xml overview" lock="rk123" status="editorial"/>
      </folder>
        ...
)

Given your definition of site.xml, it seems to fulfil the roles of the sitemap
(mapping content to renderings) and a skin configuration file (specifying page
layout). The content.xml file seems more analogous to a node->XML linkmap file.

> In hopes of keeping this idea going I would like to give some XSL that
> shows the benfit of using explicit mapping. we are about to release
> version 2 of our livestoryboard product and then I can give you a
> solid, complete set of templates [i.e. the next version from what is
> currently up at:
> http://docs.livestoryboard.com/en_us/manual/Overview.html in the download zip].
> If anyone is interested in some sweet beta-quality XSL I can give it to you now
> (let me know). Below I will focus on a few templates that use the explicit,
> hierarchical mapping. A sample site.xml (my explicit mapping file) is at the
> bottom.

<snip generalization of the 1.0 node lookup mechanism>

<snip global_definitions.xsl declarations of nodesets for current 'folder',
'page' and content.xml node>

> best,
> -Rob
> 
> ----------------------------------------------------------------------
> Some XSL
> ......................................................................
> tabs.xsl - creates a set of tabs for the top-level set of folders
...
> ......................................................................
> nav.xsl - a left or right nav system
...
> .....................................................................
> snailtrail.xsl - create a nav path back to the root folder
...
> ......................................................................
> a snippet from pager.xsl that create a << prev 1 2 3 4 next >> paging system at
> the page level. I snipped out some other paging options for sake of space.
...

These certainly nail down what any Forrest site.xml ought to make possible.

> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> Snippet from a linkmap.xml (I name it site.xml):
> [please don't be thrown off by my naming...]

site.xml is a much more sensible name anyway.

> [I have schemas (relaxng) if anybody is interested]
> ----------------------------------------------------------------------
> <config id="clean2" nav_col="tabs_narrow_left" p_nam="label"
> site_index="siteindex" subtitle="Storyboard" title="Clean Site"
> use_tool_style="1">
>   <folder display_label_link="false" expand="false" id="f1"
> index_page="siteindex" label="Home" name="en_us" pager="true" snailtrail="false"
> status="editorial" xsl_fileref="basic_3col.xsl">
>     <col type="narrow_right">
>       <article id="c413186147"/>
>     </col>
>     <page display_label_link="true" file_ext=".html" gen="true" id="siteindex"
> label="index" metadata="true" print_friendly="true" status="editorial"
> title="Clean Index Page" toc="true" xsl_fileref="homepage.xsl">
>       <col type="wide_center">
>         <article id="cindex"/>
>         <article id="c1919458443"/>
>       </col>
>     </page>
.....

My brain is overheating trying to see how Forrest could use these ideas..
Beyond the general idea that an XML file describing the site contents can be
very useful.

I like the way that the file uses abstract keys for articles (it didn't in
1.0). That's a bit like sitemap.xml could use site: urls:

<map:match pattern="*.html">
  <map:generate src="site:/c1919458443"/>
  <map:transform src="homepage.xsl"/>
  ...

Hmm.. well at any rate, site.xml + content.xml provides a nice base-level for
Forrest to aim at. Thanks for posting.. it's all very thought-provoking.


--Jeff


Re: [RT] Linking revisited: A general linking system

Posted by Jeff Turner <je...@apache.org>.
On Tue, Oct 15, 2002 at 11:33:19AM +1300, Conal Tuohy wrote:
> I confess I don't know much about Forrest, but it seems to me that a
> "resource" maps to a "topic" in topicmap jargon, and a "resourcemap" or
> "linkmap" (in Jeff's terminology) maps to a "topicmap".

You're right. The following could be regarded as a listing of topics:

<site>
  <index/>
  <dreams/>
  <faq>
    <how_can_I_help/>
    <building_own_website/>
    <building_fails_on_subsequent_builds/>
  </faq>
  <primer/>
  ...
</site>

And the attributes provide mappings from topic to XML resource, and HTML
rendering.

> Is there some reason not to make use of this technology?

Nope, it's great stuff.  I'm really impressed with how the tm4j site
(http://www.tm4j.org/) is generated from a directory of topic maps.

Wouldn't it be nice if, one day, Forrest could combine the dynamicity of a Wiki
with a solid semantic base of a topic map.  

> There is an XML syntax for topicmaps (XTM) and some developing tools for
> managing them (e.g.  tm4j). I know topicmaps have been mentioned before  ...
> but do Forrest people think TopicMaps are overkill, perhaps?

Probably the XTM syntax is a bit hard for your average content producer to
understand, but that's not to say the underlying ideas aren't worth studying and
applying wherever possible.  If you have any ideas, write'em up in a RT (random
thought) post.


--Jeff

> Cheers!
> 
> Con
> 

Re: [RT] Linking revisited: A general linking system

Posted by "J.Pietschmann" <j3...@yahoo.de>.
Conal Tuohy wrote:
> I confess I don't know much about Forrest, but it seems to me that a
> "resource" maps to a "topic" in topicmap jargon, and a "resourcemap" or
> "linkmap" (in Jeff's terminology) maps to a "topicmap". Is there some reason
> not to make use of this technology?

One problem is that your topic map has sooner or later to address
content in your source XML, which means you write a string
representing an URL into the topic map. Depending on how well
you provided for addressing topics in your source XML (ID on
every element), or how much flexibility you want (is PDF an
target format?) and how much you want to invest into processing
the URL from the topic map into something which points to the
right target for both the document the processed link is in as
well as for the format of the document the link points to.

You can use XPointer in the topic map, if you have a processor
for it, but for example getting the page to point into an external
PDF might be tricky and/or expensive.

Well, a "linkmap" suffers from the same problem, except that it
somewhat implies that you put URLs to HTML pages directly into the
map as nobody uses something else anyway...


J.Pietschmann


RE: [RT] Linking revisited: A general linking system

Posted by Conal Tuohy <co...@paradise.net.nz>.
I confess I don't know much about Forrest, but it seems to me that a
"resource" maps to a "topic" in topicmap jargon, and a "resourcemap" or
"linkmap" (in Jeff's terminology) maps to a "topicmap". Is there some reason
not to make use of this technology? There is an XML syntax for topicmaps
(XTM) and some developing tools for managing them (e.g. tm4j). I know
topicmaps have been mentioned before  ... but do Forrest people think
TopicMaps are overkill, perhaps?

Cheers!

Con


Re: [RT] Linking revisited: A general linking system

Posted by Jeff Turner <je...@apache.org>.
On Mon, Oct 14, 2002 at 03:04:45PM +0200, Nicola Ken Barozzi wrote:
> 
> Jeff Turner wrote:
> ...
> >Congratulations if you got this far.  As I said, I was hoping to
> >prototype it to clarify the ideas in my head before expecting others
> >to read them, but a month later I was simply forgetting the details,
> >so this braindump is as much for my benefit as anyone else.
> >
> >Ideas most welcome.  
> 
> I buy it :-)
> But with some changes ;-)
> 
> Instead of links and URI space, which must be defined well in the 
> sitemap (@see <first-impression-comment/> at the end) I see the linkmap 
> used as a resource-map, where I can compose my *resource* space (ie the 
> internal view, that is generally the filesystem) by mounting different 
> spaces.
>
> This would give me the possibility of mixing and changing doc locations.
> 
> For example:
> 
>  <resourcemap>
>    <mount space="/javadocs" resource="file://../../tools/javadocs">
>    <mount space="/" resource="file://.">
>  </resourcemap>
> 
> In this case I've attached a different dir to the resource tree, in a 
> way similar to unix mounts (ok, it's the same ;-P ).
> 
> Then I could offload some stuff to xmldb:
> 
>  <resourcemap>
>    <mount space="/javadocs"
>           resource="file://../../tools/javadocs">
> 
>    <mount space="/code/sourcedocs"
>           resource="myprotocol:/path/to/docs">
> 
>    <mount space="/"
>           resource="file://.">
>  </resourcemap>

Yes, that's the idea.  Probably 'resourcemap' is a better name than
'linkmap', given your definition of a resource:

  "What the sitemap does is to map a URI with a resource and operate on
  it via a pipeline."

> This does not however dictate anything about the URI space, which is 
> defined in the sitemap

Correct, it's just an alias for a filesystem resource. URI space !=
resource space.

> and the real paths to the files-resources, where they should remain
> IMHO.

I didn't get this bit. So how would we use this resourcemap? Isn't the
sitemap the thing that uses it, with matchers like:

<map:match pattern="*.html">
  <map:generate src="resourcemap:/code/sourcedocs/{1}"/>
  ...
</map:match>

If so, I think we'll agree that a) there's nothing revolutionary about
this (it was part of Marc's siteplan), b) it doesn't reeeally get us too
far on it's own. In our pages, we still need to link to foo.html, not
foo.xml or just 'foo'.

> A linkmap should IMHO instead define *associations* between URIs, and a 
> general site structure to be used by the user.

(I'm assuming user = person browsing the site)

> Which is not the URI space per-se; it defines more a book-view than a 
> list of links.

How can it not be the URI space? If page A has <link href="blah.html">,
then blah.html is a URI reference, isn't it? Likewise with book.xml: it
also deals only with URIs.

> For example (still need to elaborate more on this), for Cocoon we would have
> 
>  <linkmap uri="welcome">
>    <link name="Using Cocoon" uri="cocoon/using">
>      <link name="What is it?" uri="whatis/cocoon"/>
>      <link name="Live sites" uri="links/live-sites"/>
>    </link>
>    <link name="Apache" uri="http://www.apache.org" />
>  <linkmap>
> 
> This would be used as a navigation system for all pages

How? Would we have links like <link href="cocoon/using">? If so, what
does this linkmap buy us?

> , and the book.xml as an alternative one, with both on the left side,
> as already suggested by me in prev threads.

Here's a trail of thought...

Let's call the following a 'map':

<site>
  <index/>
  <primer/>
  <faq>
    <how_can_I_help/>
  </faq>
  <javadocs/>
</site>

Q: What can we do with this?
A: We can hang things off it.

A 'resourcemap':

<site res="file://.">
  <index res="index.xml"/>
  <primer res="primer.xml"/>
  <faq res="faq/">
    <how_can_I_help res="xpath:/faqs/faq/question[@id='...']"/>
  </faq>
  <javadocs res="file://../../javadocs"/>
</site>

A 'URImap':

<site uri="http://localhost:8080/mysite">
  <index uri="index.html"/>
  <primer uri="primer.html"/>
  <faq uri="faq/">
    <how_can_I_help uri="#how_can_I_help"/>
  </faq>
  <javadocs uri="javadocs/"/>
</site>

A 'TitleMap':

<site desc="My Wonderful Site">
  <index desc="Index"/>
  <primer desc="Forrest Primer"/>
  <faq desc="FAQ">
    <how_can_I_help desc="How can I help?"/>
  </faq>
  <javadocs desc="API Docs"/>
</site>


What makes this 'map' interesting?
You can hang all sorts of stuff off it.
And address it all in the same way.
Via XPath expressions.
Isn't that neat?
:)

Exercise for the reader:

 - Use the above to solve the problem of linking to things like Javadocs,
   where we don't want to hardcode the URL to a resource.

 - Use the above to solve the "linking problem": that is, How do we avoid
   linking to URIs like "blah.html", which presupposes and hardcodes a
   blah.xml -> blah.html mapping, and is generally yucky.

 - Describe why, although these problems could be solved with custom
   formats (resourcemap, linkmap, book.xml), solving them all at once
   with the single 'map' idea is more elegant and easier for users.


That's the underlying thinking behind what I was erroneously calling a
'linkmap'.


--Jeff

>        ->->->->->->->->->->->->->->->->->->->->->->->->->
> 
> <first-impression-comment>
> All seems really nifty... but then I read it again, and I get the strong 
> feeling that the linkmap is just another sitemap.
> 
> I can implement it by making the first part of the sitemap match the 
> linkmap version of the links and redirect to a more "URLish" concrete 
> version.
> Which basically defeats the whole purpose of the sitemap, which is to do 
> this mapping from the beginning, and keep a consistent URI space.
> 
> What the sitemap does is to map a URI with a resource and operate on it 
> via a pipeline.
> The browsers should always show the URI that has been requested, which 
> is the one that is linked.
> It should be all consistent for the user.
> 
> The CAP concept is there to enable this concept by detaching URI-space 
> from content-type resolution.
> In this way the URI space is used for the conceptual URI space, while 
> the content itself used to infer the right pipeline to use.
> 
> I don't see honestly what this brings us more than a sitemap itself can 
> give, apart from URL rewriting without touching the sitemap itself. I 
> honestly don't see the need for this ATM
> 
> Our problem with links and such is about mounting external URI spaces.
> For example, I would like to be able to mount the //dir/to/javadocs 
> resources in my resource system, so that *that* dir is used instead of 
> the one relative to the Cocoon webapp dir.
> 
> Hmmm... so instead of URL rewriting it's *resource* rewriting...
> </first-impression-comment>
> 
> -- 
> Nicola Ken Barozzi                   nicolaken@apache.org
>             - verba volant, scripta manent -
>    (discussions get forgotten, just code remains)
> ---------------------------------------------------------------------
> 

RE: [RT] Linking revisited: A general linking system

Posted by Robert Koberg <ro...@koberg.com>.
Wow Jeff - really cool brain dump! And also Betrand's concept model! - the
combination of which can provide for an amazing GUI :)

This is the kind of thing I have been hoping for in Forrest. With an explicit
site mapping you can do quite a bit. It is extremely flexible and gives your
clients and yourself a great number of options when building and maintaining a
site. I know the way I am doing it works well for the kind of sites I do (they
can be pregenerated for the most part and are maintained by the client through a
GUI). Where I fear (know...) my way will break down is on the large sites (who
wants to use one big file for something like that...) - this is where I was
hoping for some type of merging with cocoon/forrest. In hopes of keeping this
idea going I would like to give some XSL that shows the benfit of using explicit
mapping. we are about to release version 2 of our livestoryboard product and
then I can give you a solid, complete set of templates [i.e. the next version
from what is currently up at:
http://docs.livestoryboard.com/en_us/manual/Overview.html in the download zip].
If anyone is interested in some sweet beta-quality XSL I can give it to you now
(let me know). Below I will focus on a few templates that use the explicit,
hierarchical mapping. A sample site.xml (my explicit mapping file) is at the
bottom.

You will see a match or select uses something like:
<xsl:template match="key('folder-match-set', 'folder-types')" mode="nav">

This is a pretty cool, but not evident, thing. The keys are defined like so:
<xsl:key
   name="folder-match-set"
   match="folder | faqs | category | jobs | press_releases"
   use="'folder-types'" />
<xsl:key
   name="content-match-set"
   match="article | faq | job | press_release"
   use="'content-types'" />
<xsl:key
   name="special-content-match-set"
   match="faq | job | press_release"
   use="'special-content-types'" />

I was given the above technique by Jeni Tennison. I had inquired to the XSL list
about having a match-set like an attribute-set so that when I add types to my
schema I have one place to affect a match (or select).

A very handy (critical, actually) thing is to define your current context in the
explicit mapping for the following things:
<xsl:variable name="folder_nodeset" select="key('site_config_key',
$folder_idref)"/>
<xsl:variable name="page_nodeset" select="key('site_config_key', $page_idref)"/>
<!-- if they navigate down to a content piece level otherwise
false=boolean($content_nodeset) -->
<xsl:variable name="content_nodeset" select="key('site_config_key',
$content_idref)"/>

best,
-Rob

----------------------------------------------------------------------
Some XSL
......................................................................
tabs.xsl - creates a set of tabs for the top-level set of folders
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template name="tabs">
  <xsl:apply-templates select="$root_nodeset/folder/*" mode="tabs"/>
</xsl:template>

<xsl:template match="col | page" mode="tabs"></xsl:template>

<xsl:template match="key('folder-match-set', 'folder-types')" mode="tabs">
  <xsl:if test="@display_label_link='true'">
    <xsl:variable name="_href">
      <xsl:call-template name="folder_path_builder"/>
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="@name=$folder_nodeset/@name or
descendant::*[@name=$folder_nodeset/@name]">
        <span class="tabsel">
          <a href="{$_href}"><xsl:value-of select="@label"/></a>
        </span>
      </xsl:when>
      <xsl:otherwise>
        <span class="tabnorm" onmouseover="this.className='tabhover'"
onmouseout="this.className='tabnorm'">
          <a href="{$_href}"><xsl:value-of select="@label"/></a>
        </span>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:if>
</xsl:template>

</xsl:stylesheet>
......................................................................
nav.xsl - a left or right nav system
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- entry point called from a primary or source XSL. It starts at the current
folder_nodeset or the top of the tree -->
<xsl:template name="nav">
  <div id="navWrapper">
    <xsl:choose>
    <xsl:when test="not(boolean($folder_nodeset/../config))">
      <xsl:apply-templates select="$folder_nodeset/*" mode="nav"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:apply-templates select="$root_nodeset/folder/*" mode="nav"/>
    </xsl:otherwise>
    </xsl:choose>
  </div>
</xsl:template>

<xsl:template match="col" mode="nav">
  <xsl:apply-templates mode="nav"/>
</xsl:template>

<xsl:template match="key('folder-match-set', 'folder-types')" mode="nav">
  <xsl:if test="@display_label_link='true'">
    <xsl:variable name="_href">
       <xsl:call-template name="folder_path_builder"/>
    </xsl:variable>
    <xsl:variable name="title">Index Page: <xsl:value-of select="@index_page"/>
Label: <xsl:value-of select="@label"/>
Name: <xsl:value-of select="@name"/></xsl:variable>
    <xsl:choose>
      <xsl:when test="@name=$folder_nodeset/@name or
descendant::*[@name=$folder_nodeset/@name]">
        <div class="navsel" title="{$title}">
          <a href="{$_href}">
            <xsl:value-of select="@label"/>
          </a>
        </div>
        <xsl:apply-templates select="page | key('folder-match-set',
'folder-types')" mode="nav"/>
      </xsl:when>
      <xsl:otherwise>
      <div class="navnorm" onmouseover="this.className='navhover'"
onmouseout="this.className='navnorm'" title="{$title}">
        <a href="{$_href}">
          <xsl:value-of select="@label"/>
        </a>
      </div>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:if>
</xsl:template>

<xsl:template match="page" mode="nav">
  <xsl:if test="@display_label_link='true' and @gen='true'">
    <xsl:variable name="current_page_idref" select="@id"/>
    <xsl:variable name="_href">
      <xsl:call-template name="page_path_builder"/>
    </xsl:variable>
    <xsl:variable name="title">Label: <xsl:value-of select="@label"/>
Metadata visible: <xsl:value-of select="@metadata"/>
Print Friendly version: <xsl:value-of select="@print_friendly"/>
Title: <xsl:value-of select="@title"/>
Table of Contents visible: <xsl:value-of select="@toc"/></xsl:variable>
  <xsl:choose>
    <xsl:when test="not($current_page_idref=$page_idref)">
    <div class="navnorm" onmouseover="this.className='navhover'"
onmouseout="this.className='navnorm'">
      <a href="{$_href}"><xsl:value-of select="@label"/></a>
    </div>
    </xsl:when>
    <xsl:otherwise>
    <div class="navsel">
      <a href="{$_href}"><xsl:value-of select="@label"/></a>
    </div>
    </xsl:otherwise>
  </xsl:choose>
  </xsl:if>
</xsl:template>

</xsl:stylesheet>
.....................................................................
snailtrail.xsl - create a nav path back to the root folder
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template name="snailtrail">
  <span id="snailtrailWrapper">
    <xsl:choose>
      <xsl:when test="boolean($content_nodeset)">
        <xsl:apply-templates
select="$content_nodeset[../../@id=$folder_nodeset/@id]" mode="snailtrail"/>
      </xsl:when>
      <xsl:when test="boolean($page_nodeset)">
        <xsl:apply-templates select="$page_nodeset" mode="snailtrail"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates select="$folder_nodeset" mode="snailtrail"/>
      </xsl:otherwise>
    </xsl:choose>
  </span>
</xsl:template>

<xsl:template match="page" mode="snailtrail">
  <span>
    <xsl:apply-templates select="$folder_nodeset" mode="snailtrail"/>
    <xsl:value-of select="@label"/>
  </span>
</xsl:template>

<xsl:template match="key('special-content-match-set', 'special-content-types')"
mode="snailtrail">
  <xsl:variable name="id" select="@id"/>
  <span>
    <xsl:apply-templates select="$folder_nodeset" mode="snailtrail"/>
    <xsl:for-each select="$content">
    	<xsl:value-of select="key('site_config_key', $id)/@label"/>
    </xsl:for-each>
  </span>
</xsl:template>

<xsl:template match="key('folder-match-set', 'folder-types')" mode="snailtrail">
  <xsl:apply-templates select="parent::*[not(name()='config')]"
mode="snailtrail"/>
  <xsl:variable name="_href">
    <xsl:call-template name="folder_path_builder"/>
  </xsl:variable>
  <a href="{$_href}">
    <xsl:value-of select="@label"/>
  </a>
  <xsl:text>  &#187; </xsl:text>
</xsl:template>

</xsl:stylesheet>
......................................................................
a snippet from pager.xsl that create a << prev 1 2 3 4 next >> paging system at
the page level. I snipped out some other paging options for sake of space.
<!-- an entry point -->
<xsl:template name="pager">
  <div class="pagerWrapper">
    <xsl:apply-templates select="$folder_nodeset/page" mode="pager"/>
   </div>
</xsl:template>

<xsl:template match="page" mode="pager">
  <xsl:if test="position()=1">
    <xsl:apply-templates select="$page_nodeset" mode="pager_prev">
      <xsl:with-param name="first_id" select="@id"/>
    </xsl:apply-templates>
    <xsl:text> </xsl:text>
  </xsl:if>
  <xsl:choose>
    <xsl:when test="@id=$page_nodeset/@id">
      <span class="pagerCurrentPage">
        <xsl:value-of select="position()"/>
      </span>
    </xsl:when>
    <xsl:otherwise>
      <xsl:variable name="_href">
        <xsl:call-template name="page_path_builder"/>
      </xsl:variable>
      <a href="{$_href}"><xsl:value-of select="position()"/></a>
    </xsl:otherwise>
  </xsl:choose>
  <xsl:text> </xsl:text>
  <xsl:if test="position()=last()">
    <xsl:variable
      name="following_page"
      select="key('site_config_key',
following-sibling::page[@id=$page_nodeset/@id]/@id)"/>
    <xsl:apply-templates select="$page_nodeset" mode="pager_next">
      <xsl:with-param name="last_id" select="@id"/>
    </xsl:apply-templates>
  </xsl:if>
</xsl:template>

<xsl:template match="page" mode="pager_prev">
  <xsl:param name="first_id"/>
  <xsl:choose>
    <xsl:when test="not(@id=$first_id)">
      <xsl:variable name="_href">
        <xsl:call-template name="page_path_builder_prev"/>
      </xsl:variable>
    	<xsl:text>&#171; </xsl:text>
    	<a href="{$_href}">previous</a>
      <xsl:text> : </xsl:text>
    </xsl:when>
    <xsl:otherwise>
      <xsl:text>previous : </xsl:text>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="page" mode="pager_next">
  <xsl:param name="last_id"/>
  <xsl:choose>
    <xsl:when test="not(@id=$last_id)">
      <xsl:variable name="_href">
        <xsl:call-template name="page_path_builder_next"/>
      </xsl:variable>
      <xsl:text> : </xsl:text>
    	<a href="{$_href}">next</a>
      <xsl:text> &#187;</xsl:text>
    </xsl:when>
    <xsl:otherwise>
      <xsl:text> : next &#160;</xsl:text>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


Snippet from a linkmap.xml (I name it site.xml):
[please don't be thrown off by my naming...]
[I have schemas (relaxng) if anybody is interested]
----------------------------------------------------------------------
<config id="clean2" nav_col="tabs_narrow_left" p_nam="label"
site_index="siteindex" subtitle="Storyboard" title="Clean Site"
use_tool_style="1">
  <folder display_label_link="false" expand="false" id="f1"
index_page="siteindex" label="Home" name="en_us" pager="true" snailtrail="false"
status="editorial" xsl_fileref="basic_3col.xsl">
    <col type="narrow_right">
      <article id="c413186147"/>
    </col>
    <page display_label_link="true" file_ext=".html" gen="true" id="siteindex"
label="index" metadata="true" print_friendly="true" status="editorial"
title="Clean Index Page" toc="true" xsl_fileref="homepage.xsl">
      <col type="wide_center">
        <article id="cindex"/>
        <article id="c1919458443"/>
      </col>
    </page>
    <page display_label_link="true" file_ext=".html" gen="true" id="p353715906"
label="page 2" metadata="false" print_friendly="true" status="editorial"
title="page 2" toc="false" xsl_fileref="basic_3col.xsl">
      <col type="wide_center">
        <article id="c1919458443"/>
        <article id="cindex"/>
      </col>
    </page>
    <page display_label_link="true" file_ext=".html" gen="true" id="p523744271"
label="page 3" metadata="false" print_friendly="true" status="editorial"
title="page 3" toc="false" xsl_fileref="basic_3col.xsl">
      <col type="wide_center">
        <article id="cindex"/>
      </col>
    </page>
    <jobs display_label_link="true" expand="false" id="jobs1" index_page="empty"
label="Jobs" name="jobs" pager="false" snailtrail="true" status="editorial"
xsl_fileref="spec_folders_primary.xsl">
      <col type="wide_center">
        <job id="job1"/>
        <job id="job2"/>
        <job id="job3"/>
        <job id="job4"/>
      </col>
    </jobs>
    <faqs display_label_link="true" expand="false" id="faq" index_page="empty"
label="FAQs" name="faqs" pager="false" snailtrail="true" status="editorial"
xsl_fileref="spec_folders_primary.xsl">
      <col type="wide_center">
        <faq id="faqtest2"/>
        <faq id="faqtest4"/>
        <faq id="faqtest5"/>
        <faq id="faqtest6"/>
        <faq id="faqtest"/>
        <faq id="faqtest3"/>
      </col>
    </faqs>
    <folder display_label_link="false" expand="false" id="base"
index_page="sitemap" label="Utility Pages" name="util" pager="true"
snailtrail="true" status="editorial" xsl_fileref="basic_3col.xsl">
      <page display_label_link="false" file_ext=".html" gen="true" id="sitemap"
label="Sitemap" metadata="false" print_friendly="false" status="editorial"
title="Sitemap" toc="false" xsl_fileref="root_rel_sitemap.xsl">
      </page>
      <page display_label_link="false" file_ext=".html" gen="true"
id="page_not_found" label="Page Not Found" metadata="false"
print_friendly="false" status="editorial" title="Page Not Found" toc="false"
xsl_fileref="root_relative_shell.xsl">
        <col type="wide_center">
          <article id="c919656982"/>
        </col>
      </page>
    </folder>
  </folder>
</config>



Re: [RT] Linking revisited: A general linking system

Posted by Nicola Ken Barozzi <ni...@apache.org>.
Jeff Turner wrote:
...
> Congratulations if you got this far.  As I said, I was hoping to
> prototype it to clarify the ideas in my head before expecting others
> to read them, but a month later I was simply forgetting the details,
> so this braindump is as much for my benefit as anyone else.
> 
> Ideas most welcome.  

I buy it :-)
But with some changes ;-)

Instead of links and URI space, which must be defined well in the 
sitemap (@see <first-impression-comment/> at the end) I see the linkmap 
used as a resource-map, where I can compose my *resource* space (ie the 
internal view, that is generally the filesystem) by mounting different 
spaces.

This would give me the possibility of mixing and changing doc locations.

For example:

  <resourcemap>
    <mount space="/javadocs" resource="file://../../tools/javadocs">
    <mount space="/" resource="file://.">
  </resourcemap>

In this case I've attached a different dir to the resource tree, in a 
way similar to unix mounts (ok, it's the same ;-P ).

Then I could offload some stuff to xmldb:

  <resourcemap>
    <mount space="/javadocs"
           resource="file://../../tools/javadocs">

    <mount space="/code/sourcedocs"
           resource="myprotocol:/path/to/docs">

    <mount space="/"
           resource="file://.">
  </resourcemap>

This does not however dictate anything about the URI space, which is 
defined in the sitemap and the real paths to the files-resources, where 
they should remain IMHO.

A linkmap should IMHO instead define *associations* between URIs, and a 
general site structure to be used by the user.
Which is not the URI space per-se; it defines more a book-view than a 
list of links.

For example (still need to elaborate more on this), for Cocoon we would have

  <linkmap uri="welcome">
    <link name="Using Cocoon" uri="cocoon/using">
      <link name="What is it?" uri="whatis/cocoon"/>
      <link name="Live sites" uri="links/live-sites"/>
    </link>
    <link name="Apache" uri="http://www.apache.org" />
  <linkmap>

This would be used as a navigation system for all pages, and the 
book.xml as an alternative one, with both on the left side, as already 
suggested by me in prev threads.

        ->->->->->->->->->->->->->->->->->->->->->->->->->

<first-impression-comment>
All seems really nifty... but then I read it again, and I get the strong 
feeling that the linkmap is just another sitemap.

I can implement it by making the first part of the sitemap match the 
linkmap version of the links and redirect to a more "URLish" concrete 
version.
Which basically defeats the whole purpose of the sitemap, which is to do 
this mapping from the beginning, and keep a consistent URI space.

What the sitemap does is to map a URI with a resource and operate on it 
via a pipeline.
The browsers should always show the URI that has been requested, which 
is the one that is linked.
It should be all consistent for the user.

The CAP concept is there to enable this concept by detaching URI-space 
from content-type resolution.
In this way the URI space is used for the conceptual URI space, while 
the content itself used to infer the right pipeline to use.

I don't see honestly what this brings us more than a sitemap itself can 
give, apart from URL rewriting without touching the sitemap itself. I 
honestly don't see the need for this ATM

Our problem with links and such is about mounting external URI spaces.
For example, I would like to be able to mount the //dir/to/javadocs 
resources in my resource system, so that *that* dir is used instead of 
the one relative to the Cocoon webapp dir.

Hmmm... so instead of URL rewriting it's *resource* rewriting...
</first-impression-comment>

-- 
Nicola Ken Barozzi                   nicolaken@apache.org
             - verba volant, scripta manent -
    (discussions get forgotten, just code remains)
---------------------------------------------------------------------