forrest-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Robert Koberg" <...@koberg.com>
Subject RE: [RT] Linking revisited: A general linking system
Date Mon, 14 Oct 2002 15:21:06 GMT
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>



Mime
View raw message