Solprovider Lenya Kongregate Registration for Free Flash Games and Chat with solprovider

Displaying a Map of a Publication

This article creates a page displaying every page on the site, including pages marked "not visible". The instructions create a separate page as the "Sitemap" with the current page marked with an asterisk. The new navigation control "map" could be used as a replacement for the "menu" navigation control, although the asterisk may be undesirable for that purpose. (I would love to use the CSS2 :after content: "*", but I am not certain any browsers support it.)

NOTES

1. The term "sitemap" has special meaning for Lenya, so I refer to a sitemap (in the standard web sense) as a "map". This is reflected in the name of the files.

2. While {pub} means your publication directory, braces in code are meant to kept. XMAP and XSL files use braces around variables, such as {page-envelope:publication-id} and {$url}, and CSS uses braces around each section.

Instructions

These instructions start from the interface and work down, because I may have forgotten an instruction. Most of my articles start with building the functionality, then add it to the interface. Just skip step 1 until the other steps are completed.

While this follows the Lenya paradigm, performance could be improved. On the bad side, the map is created for every page, regardless of whether it is needed. Performance would be better if the Usecase pipeline copied the lenyabody pipeline and replaced every "{4}" with "map". On the good side, any customization of the main pipeline is obeyed.

1. To add a link to the map to your XSL, use:
<A HREF="{$url}?lenya.usecase=map"><i18n:text>Sitemap</i18n:text></A>
You may want to read Static Pages for how to avoid showing the link on the map page.

2. Add the map Usecase.
NEW FILE: {pub}/usecase-map.xmap
<?xml version="1.0" encoding="UTF-8"?>
<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
<map:pipelines>
<map:pipeline>
<map:match pattern="**">
<map:generate src="cocoon://{page-envelope:publication-id}/lenyabody-view/{page-envelope:publication-id}/{page-envelope:area}/map{page-envelope:document-id}_{page-envelope:document-language}.html"/>
<map:transform src="../../xslt/util/strip_namespaces.xsl"/>
<map:serialize type="html"/>
</map:match>
</map:pipeline>
</map:pipelines>
</map:sitemap>


3. Create the XSLT.
NEW FILE: {pub}/xslt/page2xhtml-map.xsl
I use the standard XSL for my publication, replacing
<xsl:apply-templates select="xhtml:div[@id = 'body']"/>
with:
<H2>Sitemap</H2>
<xsl:apply-templates select="xhtml:div[@id = 'map']"/>


4. Add the map navigation element to the standard XMAP.
FILE: {pub}/publication-sitemap.xmap
FIND:
<map:match pattern="lenyabody-*/*/*/*/**">
<map:aggregate element="cmsbody">

ADD THIS LINE:
<map:part src="cocoon://navigation/{2}/{3}/map/{5}.xml"/>

5. Add the navigation creator.
FILE: {pub}\lenya\xslt\navigation\map.xsl
<?xml version="1.0" encoding="UTF-8" ?>
<!-- Created by solprovider -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:nav="http://apache.org/cocoon/lenya/navigation/1.0"
xmlns="http://www.w3.org/1999/xhtml"
exclude-result-prefixes="nav">

<xsl:template match="nav:site">
<div class="map" id="map">
<xsl:apply-templates select="nav:node"/>
</div>
</xsl:template>

<xsl:template match="nav:node">
<div class="mapblock" level="{count(ancestor-or-self::nav:node)}">
<xsl:call-template name="item"/>
<xsl:apply-templates select="nav:node"/>
</div>
</xsl:template>

<xsl:template name="item">
<xsl:choose>
<xsl:when test="@current = 'true'">
<xsl:call-template name="item-selected"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="item-default"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

<xsl:template name="item-default">
<div class="mapitem" level="{count(ancestor-or-self::nav:node)}" id="{@id}">
<a href="{@href}"><xsl:apply-templates select="nav:label"/></a>
</div>
</xsl:template>

<xsl:template name="item-selected">
<div class="mapitem-selected" level="{count(ancestor-or-self::nav:node)}" id="{@id}">
<a href="{@href}"><xsl:apply-templates select="nav:label"/></a> *
</div>
</xsl:template>

<xsl:template match="nav:label">
<xsl:value-of select="."/>
</xsl:template>

<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

CSS

I added this CSS to page.css for a neatly spaced and indented red page listing. The key element is left-padding each mapblock. Since each line is a link, color is determined by the mapitem A tags.

.mapblock {
position: relative;
padding: 0px 0px 0px 20px;
}
.mapitem A { color: #660000; }
.mapitem A:visited { color: #660000; }


<< Dynamic Webpages
(Fixing Cache)
Website Map with Descriptions >>

Contact Solprovider
Paul Ercolino