spacer

Webref WebRef   Sitemap · Experts · Tools · Services · Newsletters · About i.com

home / programming / xsltweb2 / 1 To page 1To page 2To page 3To page 4current pageTo page 6
[previous][next]

Sr. Web Developer
mediabistro.com
US-NY-New York

Justtechjobs.com Post A Job | Post A Resume
Developer News
Microsoft Shows Off Silverlight 4, IE9 Plans
Metasploit Expands Vulnerability Test Framework
HyperCard Reborn?


XSLT 2.0 Web Development: Elements of a Web Site. Pt. 2.

3.9.1.4. Registering dynamic content

Recall our discussion of dynamic sites in 1.5. We found that a dynamic web page is produced from two main parts — static templates and dynamic values — and that both can (and should) use XML markup. It’s now time to see how these concepts fit into the source definition we are building.

One way of many. There exist different ways to aggregate dynamic content and static templates. Some of them come before XSLT transformation, which is usually the last stage in a dynamic XML web site workflow; in these cases, you don’t need any special source markup because your stylesheet will get complete seamless page source with both static and dynamic content. However, in some situations (notably offline XSLT processing, 1.4.1) implementing dynamic content aggregation in XSLT is convenient. This section shows one approach to organizing such transformation-time incorporation of dynamic content.

Reusing blocks. An orthogonal content block that the stylesheet extracts from another document may be considered a special case of a composite dynamic value. Therefore, it makes sense to extend our blocks’ markup constructs so that they cover the “truly dynamic” content as well — content that is calculated or compiled by some external process and not just stored in a static document.

We can define a number of block conventions that will allow us to use blocks not only for enveloping independent bits of content but also as links to external sources of information. Once again, our guiding principle is: Let the page author use short mnemonic identifiers and hide all the gory details of accessing data in the master document and/or stylesheet.

Calling a process. Suppose we want to build a site map page that automatically compiles a hierarchical list of all pages of the site. The first thing we need is the static part of that page — a document that stores all the static bits unique to the page, such as an introductory paragraph and heading(s). This is a normal page that is listed in the menu hierarchy in the master, just like any other page.

Wherever we want to insert our dynamic content into that static frame, we place a block reference, e.g.:

<block idref="sitemap"/>

In the master, however, we cannot associate the sitemap identifier with any source file, since no such file exists — the list of pages is generated dynamically.

Instead, we must associate our dynamic block identifier (sitemap) with an identifier of some abstract process that generates its data. You can think of a process as a kind of a script or application; it may accept some parameters that affect its output. Thus, if we write in the master document (within the same blocks envelope used for orthogonal blocks)

<block-process id="sitemap" process="sitemap" mode="text" depth="2"/>

then the stylesheet will know that a sitemap block needs to be filled in with data generated by the sitemap process with parameters mode="text" and depth="2". This process can be, for example, a callable template within the stylesheet (4.5.1) or an external program. With this approach, document authors don’t need to know anything about processes or parameters; they use identifiers to refer to data sources, and the master document associates each source with a process and its set of parameters.

Watching a directory. A stylesheet can access external files even if the list of these files is changing dynamically. For example, an external process (which may or may not be another stylesheet) might be dropping its output XML documents into a directory. Your stylesheet would then read the list of files in that directory (5.3.2) and do what it pleases with their content — such as dump all available content from all files into one page or perform some elaborate selection, filtering, or rotation.

If, for example, your stylesheet implements a list-titles process that takes a directory as a parameter and returns the list of title elements from all XML documents in the directory, then you could define a block to perform this operation on all (dynamically updated) documents in the news directory by writing in the master document

<block-process id="news-list" process="list-titles" dir="news/"/>

In a page document that wants to use this list, you would then write simply

<block idref="news-list"/>

XML, not HTML. Note that processes similar to sitemap or list-titles should only aggregate content, not format it. This means that the corresponding templates or functions in your stylesheet must produce valid XML data (nodesets), not HTML renditions. You would then feed these nodesets to the regular formatting templates in the same stylesheet (see 5.3.3.1 for ideas on how to chain templates together). If a process is implemented as an external program, it should return serialized XML data or plain text that the stylesheet will be able to convert to nodesets.

3.9.2. Common content and site metadata

On a typical web site, all pages contain bits of information that either remain the same or change predictably from page to page. Some of this repeating data, such as the company logo or tag line, actually belongs to the domain of presentation rather than content and therefore needs to be filled in by the stylesheet rather than stored in the source. Other components, such as webmaster email links, “designed by” signatures, copyright or legal notices, etc., are natural to store in the master document.

It is recommended that you envelop all such bits of content in one or more umbrella elements, each containing data with similar roles or positions on the pages. Here’s a master document fragment defining the footer to be placed at the bottom of each page:

<page-footer>
  <designed-by>Site design: <ext link="www.kirsanov.com">Dmitry
    Kirsanov Studio</ext></designed-by>
  <legal linktype="internal" link="legal">Legal notices</legal>
  <contact linktype="internal" link="contact">Contact us</contact>
</page-footer>

Note that the elements inside page-footer may have mixed content with any of the text markup, linking, or other elements that were developed for page documents. In particular, we see internal and external links used in this example, each with its own address abbreviation scheme 3.5.3).

The page-footer parent element makes the stylesheet simpler and more bullet-proof: Instead of providing templates for each of the individual footer elements, you can program the stylesheet to process all items within a page-footer in turn, and only provide separate templates for those that differ from others in formatting. With this approach, you’ll be able to add a new element type for a new footer object even without changing the stylesheet.

Similarly, we can create an envelope for storing metadata that applies to the entire site. Examples of such metadata include site-wide keyword lists (which could be merged with page-specific keywords supplied by the page documents, 3.1.1) and extended credits (which could be put in comments in the HTML code of the site’s front page).

3.9.3. Processing parameters

Your stylesheet will need to know some parameters of the environment in which it is run as well as the environment where its HTML output will be placed. The most frequently required processing parameter is the base URI that the stylesheet will prepend to all the image and link pathnames. By changing this parameter, you can turn all internal link URIs from relative to absolute with an arbitrary base, which is useful for testing the site in different environments. Other parameters may provide the path to the source tree and the operating system under which the stylesheet is run (which, in turn, may affect the syntax of pathnames).

Grouping parameters into environments. It is important that the same set of source files may be processed on different computers — for example, on a developer’s personal system, then in a temporary (staging) location on the server, and finally in the publicly accessible area on the target server. Each of these environments will require its own set of processing parameters. It is therefore convenient to define several groups of parameter values, one for each environment, and select only one of the groups by its identifier when running the transformation.

Where to store the environment groups? Obviously, the need to group parameters and assign a unique identifier to each group makes using XML very convenient — as opposed to, say, storing the values within scripts used to run the site build process (6.5.1). Note also that scripts are the most OS-dependent part of the site setup, so it is best to keep them as simple and therefore as portable as possible. And of all the XML documents of a web site, the two most likely choices are the XSLT stylesheet and the master document.

Your stylesheet is more likely to be shared (in whole or in part) among different projects, so it is not wise to use it for storing information that is too project-specific. Also, even though you can use XSLT variables for storing processing parameters, it is more convenient to use custom element hierarchies for structuring and accessing this data. For these reasons, the master document emerges as the most natural storage for processing parameters.

This does not mean that your master document will differ among environments. Instead, all identical copies of it will have information on all environments, and each environment will extract the relevant set of data by passing a parameter to the stylesheet.

Here’s an example group of parameters that define the processing environment called staging (see 3.10.2 for the meanings of the elements):

<environment id="staging">
  <os>Linux</os>
  <src-path>/var/website/src/</src-path>
  <out-path>/var/website/out/</out-path>
  <target-path>/test/</target-path>
  <img-path>img</img-path>
</environment>

3.9.4. Site-wide content and formatting

Normally, formatting of web pages is created by the stylesheet. Sometimes, however, formatting is dependent on certain parameters that, being more content than style, belong in the site’s source and not in the stylesheet. Also, sometimes the stylesheet may need to create objects that are used on many pages but do not belong to any one page in particular. In both these situations, the master document is a convenient place to store data.

Site-wide buttons. An example of such an object is a pair of graphic buttons — “next” and “prev” — used on sequential pages (such as chapters in an online book). If your stylesheet generates other graphic buttons on the site (5.5.2), design consistency and maintainability will be much better if all buttons are done in the same way.

These buttons are not specific to any particular page; moreover, pages that use them don’t even need to mention the buttons in the source because the stylesheet can automatically create the page sequence, including appropriate navigation. All we need is to store the button labels somewhere so the stylesheet can generate the buttons. It makes sense to use the master document for this.

You can store the button labels in a separate element in the master and program the stylesheet to regenerate the buttons when run with the corresponding parameter. For example,

<buttons>
  <button>prev</button>
  <button>next</button>
</buttons>

3.10. Summary examples

This section presents examples of complete documents that bring together everything we’ve discussed in the last two chapters (and more). The content is fictitious, but the structure and markup are from real web site projects (somewhat abridged for readability).

3.10.1. Page document

Compared to the master document example (3.10.2), the page document in Example 3.1 is short and simple. This is, in fact, what you should strive for in your project. Page documents are the primary work area for those who will update and maintain the site, so the layout of a page document must be as simple and self-evident as possible. (For instance: Do we need indentation in page documents? Probably not, unless it is taken care of automatically.)

The main rule of thumb is: If you can move a bit of information away from a page document to the master or to the stylesheet, do that.


Example 3.1. en/team/index.xml: A page document.

<?xml version="1.0" encoding="us-ascii"?>
<page keywords="team, people, staff, competences, skills">

<title>Our team</title>

<!-- Main content block: -->
<block type="body">
<p>With backgrounds in technology and communications, FooBar's
experienced management team has - you guessed it -
<em>the right combination of skills for success</em>.</p>

<section image="mike">
<head>Mike M. Anager</head> 
<subhead>CEO</subhead>
<p>CEO and Co-Founder, Mike leads FooBar towards bringing the vision
of "personal foobar" to reality. He previously served as Chief
Architect at <ext link="www.barfoo.com">BarFoo Corporation</ext>.</p>
</section>

<section image="ed">
<head>Ed N. Gineer</head> 
<subhead>VP, Engineering</subhead>
<p>Ed has over 30 years of foobar design experience under his
belt. He has personally contributed to the most acclaimed of 
our <int link="solutions">products</int>, including the famous
<int link="fbplus">Foobar Plus</int>.</p>
</section>

<section image="jack">
<head>Jack J. Anitor</head> 
<subhead>Senior Janitor</subhead>
<p>Jack's expert janitorial skills and experience have been
critical in the success of FooBar.</p> 
</section>
</block>

<!-- Orthogonal content blocks: -->
<block idref="subscribe"/>
<block idref="feature"/>

</page>

3.10.2. Master document

Example 3.2shows a master document that compiles most of the data we discussed in 3.9 but adds a few new twists.

Languages. Our example site is bilingual (English and German), so all titles and labels are provided in two languages, and the languages themselves are listed in a languages element. We add an internal DTD subset with mnemonic entity references (2.2.4.3) for German characters.

Environments. For every installation where the site can be built, an environment element with a unique id supplies the following information:

On Windows, all absolute paths must be given in the file:/ URL format.17 This is the only standard and reliable way to represent an absolute pathname that includes a drive letter. In HTML, URLs with file:/ work for both links and image references in all browsers we tested. Other platforms may use absolute pathnames without the file:/.

Menu. The menu lists all the pages of the site. For each page, the src attribute contains the page’s pathname (add .xml for source files or .html for output files) relative to the site’s root directory.

Each page has an id attribute used to link to it. To make life easier, you can also provide a space-separated list of aliases in the alias attribute. In internal links to this page, you can use either its id or any of the aliases.

Each menu item has a label child storing the item’s visible label. In the menu on a web page, each item is supposed to be linked to its first page child, so there’s no need to specify a link in an item.

It is assumed that the English and German versions of the source files are named the same but stored in different directory trees under the root directory. The corresponding directories are named after the language designations defined in languages. So, for instance, the complete path to the German fbplus source page in the staging environment would be constructed as follows:

/home/d/web/de/solutions/foobar_plus.xml

Blocks. The blocks element holds a list of orthogonal content blocks with their identifiers (id), source document locations (src), and block selectors (select, 3.9.1.3). Note that the subscribe page is listed only once as an orthogonal source, while the solutions/foobar_plus page is both in the menu and in the blocks list. For this reason, a block must specify a complete location for the orthogonal content source and not just its id, as all other links do, because not all orthogonal documents are registered in the menu and assigned an id.

Misc. Finally, the master document lists the common part to be prepended to page titles 3.2.4) on all pages (html-title), page footer content (page-footer), and two labels for buttons that need to be created by the stylesheet (buttons).

Note that the mailto links used in page-footer represent a special link type (3.5.2) with an abbreviated address (the corresponding resolved URI will have mailto: prepended to the email address).


Example 3.2. _master.xml: The master document.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE site [
  <!ENTITY auml "&#228;">
  <!ENTITY ouml "&#246;">
  <!ENTITY uuml "&#252;">
]>

<site> <!-- Environments: --> <environment id="local"> <os>Windows</os> <src-path>file:/C:/Work/Website/XML/</src-path> <out-path>file:/C:/Work/Website/Out/</out-path> <target-path>file:/C:/Work/Website/Out/</target-path> <img-path>Images</img-path> </environment> <environment id="staging"> <os>Linux</os> <src-path>/home/d/web/</src-path> <out-path>/home/d/web/out/</out-path> <target-path>/</target-path> <img-path>img</img-path> </environment> <environment id="final"> <os>BSD</os> <src-path>/var/tomcat/webapps/cocoon/foobar/</src-path> <out-path>/var/tomcat/webapps/cocoon/foobar/</out-path> <target-path>/cocoon/foobar/</target-path> <img-path>img</img-path> </environment> <!-- Languages: --> <languages> <lang>en</lang> <lang>de</lang> </languages> <!-- Menu: --> <menu> <item> <label> <translation lang="en">Home</translation> <translation lang="de">Home</translation> </label> <page id="home" alias="index front fp frontpage" src="index"/> </item>
<item> <label> <translation lang="en">Solutions</translation> <translation lang="de">L&ouml;sungen</translation> </label> <page id="solutions" src="solutions/intro_solutions"/> <item> <label> <translation lang="en">Life</translation> <translation lang="de">Das Leben</translation> </label> <page id="life" src="solutions/life"/> <page id="fbplus" alias="foobar_plus fb+ foobar+" src="solutions/foobar_plus"/> <page id="fbminus" src="solutions/foobar_minus"/> </item> <page id="universe" src="solutions/universe"/> <page id="everything" src="solutions/everything"/> </item> <item> <label> <translation lang="en">Our team</translation> <translation lang="de">Unser Team</translation> </label> <page id="team" src="team/index"/> <page id="history" src="team/history"/> <page id="hire" src="team/hire"/> </item> <item> <label> <translation lang="en">Contact</translation> <translation lang="de">Kontakt</translation> </label> <page id="contact" src="contact/contact"/> <page id="map" src="contact/map"/> </item> </menu>
<!-- Orthogonal and dynamic blocks: --> <blocks> <!-- Extract the 'summary' block from the product page: --> <block id="feature" src="solutions/foobar_plus" select="summary"/> <!-- Extract the 'last' block from the front page: --> <block id="news" src="index" select="last"/> <!-- Take the entire subscribe.xml: --> <block id="subscribe" src="subscribe"/> <!-- Run site map generation: --> <block-process id="sitemap" process="sitemap" mode="text" depth="2"/> <!-- Run list-titles on all files in news/: --> <block-process id="news-list" process="list-titles" dir="news/"/> </blocks> <!-- The common part of the page titles: --> <html-title> <translation lang="en">Foobar Corporation AG</translation> <translation lang="de">Foobar Corporation AG</translation> </html-title> <!-- Page footer content: --> <page-footer> <copyright> <translation lang="en">&#169; 2003 by Foobar Corporation AG. All rights reserved.</translation> <translation lang="de">&#169; 2003 by Foobar Corporation AG. All rights reserved.</translation> </copyright> <language-switch> <translation lang="en"> <lang link="de">Diese Seite in deutsch</lang> </translation> <translation lang="de"> <lang link="en">This page in English</lang> </translation> </language-switch>
<contact-webmaster> <translation lang="en"> Problems using this site? Contact the <mailto link="webmaster@foobar.com">Webmaster</mailto>. </translation> <translation lang="de"> Probleme mit dieser Web-Site? Kontaktieren Sie bitte unseren <mailto link="webmaster@foobar.com">Webmaster</mailto>. </translation> </contact-webmaster> </page-footer> <!-- Sequence navigation buttons: --> <buttons> <button id="prev"> <translation lang="en">prev</translation> <translation lang="de">zur&uuml;ck</translation> </button> <button id="next"> <translation lang="en">next</translation> <translation lang="de">vorw&auml;rts</translation> </button> </buttons> </site>

home / programming / xsltweb2 / 1 To page 1To page 2To page 3To page 4current pageTo page 6
[previous][next]

internet.commediabistro.comJusttechjobs.comGraphics.com

Search:

WebMediaBrands Corporate Info

Legal Notices, Licensing, Permissions, Privacy Policy.
Advertise | Newsletters | Shopping | E-mail Offers | Freelance Jobs

webref The latest from WebReference.com Browse >
Rolling Out Your Own HTML Application Version Control · HTML 5: Client-side Storage · Working with Ajax Server Extensions
Sitemap · Experts · Tools · Services · Email a Colleague · Contact FREE Newsletters 
 The latest from internet.com
Wi-Fi Product Watch, November 2009 · Chip Market Recovering From '08 Collapse · Low-Cost Tools to Kickstart Your New Business

Created: March 27, 2003
Revised: May 24, 2004

URL: http://webreference.com/programming/xsltweb2/1