Node:Step 6, Next:Step 7, Previous:Step 5, Up:Tutorial
The ancestors annotation searches each of the
parent directories of the currently processed file. It is useful for
creating a 'you-are-here' or 'breadcrumbs' style navigation
links. Unlike other annotations, the ordering does not depend on the
file or directory name - the order is the directory hierarchy from top
to bottom. The first file in the annotation will always be the one
for the root of the source tree. The last file will be the one for the
directory containing the currently processed file. If the currently
processed file happens to also match the file-name,
it will also appear in the annotation.
The members annotation picks up other files
in the current directory. However, we won't be using it in this
tutorial. (A hint to remember: all these annotations have names which
are plurals - e.g. "members", not "member".)
Design the layout of the source tree directories with
annotations in mind so that they can be used to generate the site
navigation links. The children annotation picks up
files in immediate subdirectories. The ancestors
annotation picks up files in the parent directories. The
members annotation picks up files in the current
directory.
If a directory doesn't have a file with a matching name, that directory is just skipped. That might be useful if you want to have a directory that is not reflected in the Web site's navigation hierarchy.
So far, annotations have been calculated relative to the
directory containing the currently processed source file - that can be
changed using the dir annotation. It has a
mandatory path attribute which specifies the new
working directory. This path can be relative or absolute, and may
optionally be prefixed by transbuild:// as a
reminder that it is in the source tree file space.
Annotations listed inside the dir element are
processed relative to that new directory. In the output, a
dir element is created and the annotations in the
dir are nested inside it.
You can add multiple annotations in one
xml-load. The annotation elements will be appended
in the same order as supplied. For example, we'll change the rule
to:
<rule source-suffix=".xml" target-suffix=".html">
<xml-load>
<dir path="/">
<children file-name="index.xml"/>
</dir>
<ancestors file-name="index.xml"/>
<children file-name="index.xml"/>
</xml-load>
<xslt stylesheet="scripts/tr06.xsl"/>
</rule>
This will parse the source file and annotate it to create a
large body of XML data containing something like:
<article
xmlns:TBA="http://hoylen.com/ns/xmlns/2002/transbuild/annotation"
TBA:source="transbuild://hardware/index.xml">
<title>Hardware</title>
<para>Our products incorporate leading edge technology with award
winning design which is both beautiful and functional.</para>
<TBA:dir TBA:source="transbuild://">
<TBA:children>
<article
TBA:source="transbuild://about/index.xml">...</article>
<article
TBA:source="transbuild://contact/index.xml">...</article>
<article
TBA:source="transbuild://hardware/index.xml">...</article>
<article
TBA:source="transbuild://software/index.xml">...</article>
</TBA:children>
</TBA:dir>
<TBA:ancestors>
<article TBA:source="transbuild://index.xml">...</article>
<article TBA:source="transbuild://hardware/index.xml">...</article>
</TBA:ancestors>
<TBA:children>
<article
TBA:source="transbuild://hardware/mp100/index.xml">...</article>
<article
TBA:source="transbuild://hardware/mp120/index.xml">...</article>
<article
TBA:source="transbuild://hardware/mp110/index.xml">...</article>
<article
TBA:source="transbuild://hardware/mp130/index.xml">...</article>
<article
TBA:source="transbuild://hardware/omp/index.xml">...</article>
</TBA:children>
</article>
Notice that the ordering of the imported root elements is sorted
in lexicographical order, except for the ancestors
annotation. In this example, the data from the
~source~/hardware/index.xml file appears three
times (as the document itself, in the children of the directory
annotation, and in the last ancestors annotation). This may seem very
inefficient, but don't worry about it - most of the time your files
are small and Transbuild creates these annotations very efficiently by
caching the parsed XML data.
The XSLT script is modified to use the information from the
annotations. The top level children are used to create navigation
links into the different major sections of the site. The ancestor
annotations will be used to create a "bread-crumbs" navigation showing
all the levels above the current page.
<xsl:template match="article">
<body>
<div class="nav-top">
<ul>
<li><a href="{TBF:href('/index.xml')}">Home</a></li>
<xsl:for-each select="/article/TBA:dir/TBA:children/article">
<xsl:sort select="@status" data-type="number"
order="ascending"/>
<li>
<a href="{TBF:href(@TBA:source)}">
<xsl:value-of select="title"/>
</a>
</li>
</xsl:for-each>
</ul>
</div>
<h1><xsl:value-of select="title"/></h1>
<div class="nav-hier">
<xsl:for-each select="/article/TBA:ancestors/article">
<xsl:if test="position() != 1">
<xsl:text> > </xsl:text>
</xsl:if>
<a href="{TBF:href(@TBA:source)}">
<xsl:value-of select="title"/>
</a>
</xsl:for-each>
<xsl:text disable-output-escaping="yes">&nbsp;</xsl:text>
</div>
...
This step can be tested by running Transbuild on the build
script file tb-step06.xml. It produces a set of
Web pages with a set of navigation links.
The usefulness of Transbuild is now apparent. By using
Transbuild annotations, the navigation links are all generated
automatically without any hand editing of the source files. By
carefully writing flexible XSLT scripts, you can future-proof your
site. For example, if we wanted to add a new section to the site
(e.g. for support), all you have to do is create a directory
~source~/support and a single file
~source~/support/index.xml and re-run Transbuild.
A new set of Web pages will be generated, with every page having a top
level link to that new section. It's that simple - try it! Or, try
adding a new hardware product by creating a single directory and one
file.