LOOKING AT SOME XSLT EXAMPLES

To dig even further into how Umbraco implements XSLT, look at the examples that follow in the rest of the chapter.

When utilizing the Umbraco built-in editor for XSLT manipulation (in the backoffice), you can always refer to the Visualize XSLT tool to see how your XSLT macro will render. This tool allows you to select a target in the content tree and run your XSLT template as is without your having to add the macro to a template or node. Here's how that works:

  1. While in the XSLT editor in the Developer section, click the Visualize XSLT button in the toolbar, as shown in Figure 11-4.

    FIGURE 11-4

    image

  2. In the resulting Choose Content dialog, select the node from which you want to test your code. Using the example from the earlier “Working with Media” section, select the FAQ node that has the image you are trying to display, as shown in Figure 11-5.

    FIGURE 11-5

    image

  3. Click the Visualize XSLT button again. The corresponding image appears, as shown in Figure 11-6.

    FIGURE 11-6

    image

  4. Close the dialog when you are done to return to the XSLT code editor.

List All Content

The script in Listing 11-5 enables you to list all the content starting at the root node. This example is easy because you can take advantage of one of the XSLT extension methods that come with Umbraco.

LISTING 11-5: ListAllContent.xslt

image
<?xml version=“1.0” encoding=“UTF-8”?>
<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp “&#x00A0;”> ]>
<xsl:stylesheet
    version=“1.0”
    xmlns:xsl=“http://www.w3.org/1999/XSL/Transform”
    xmlns:msxml=“urn:schemas-microsoft-com:xslt”
    xmlns:umbraco.library=“urn:umbraco.library”
xmlns:Exslt.ExsltCommon=“urn:Exslt.ExsltCommon”
xmlns:Exslt.ExsltDatesAndTimes=“urn:Exslt.ExsltDatesAndTimes”
xmlns:Exslt.ExsltMath=“urn:Exslt.ExsltMath”
xmlns:Exslt.ExsltRegularExpressions=“urn:Exslt.ExsltRegularExpressions”
xmlns:Exslt.ExsltStrings=“urn:Exslt.ExsltStrings”
xmlns:Exslt.ExsltSets=“urn:Exslt.ExsltSets”
xmlns:umbusersguide.library=“urn:umbusersguide.library”
    exclude-result-prefixes=“msxml umbraco.library Exslt.ExsltCommon
Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions
Exslt.ExsltStrings Exslt.ExsltSets umbusersguide.library “>

    <xsl:output method=“xml” omit-xml-declaration=“yes” />

    <xsl:param name=“currentPage”/>

    <xsl:template match=“/”>
        <!-- The fun starts here -->
        <ul>
        <xsl:for-each select=“umbraco.library:GetXmlAll()/descendant::xs*
[@isDoc and string(umbracoNaviHide) != ‘1’]”>
            <li class=“level-{@level}”> <!-- create indentations
                                             using CSS class definitions -->
                <a href=“{umbraco.library:NiceUrl(@id)}”>
                    <xsl:value-of select=“@nodeName”/>
                </a>
            </li>
        </xsl:for-each>
        </ul>
    </xsl:template>
</xsl:stylesheet>

The select statement in Listing 11-5 can be broken down as follows:

  1. umbraco.library:GetXmlAll() retrieves the entire XML cache.
  2. descendants::* tells the select statement to return all the children, children's children, and so on where the asterisk is a wildcard statement specifying that all node types are valid.
  3. @isDoc is a boolean condition making sure that the isDoc attribute exists on the node. It also filters out any that don't.

    image The isDoc attribute was introduced along with the new XML schema. This allows you to differentiate between a document node (or a node that represents a page with fields), from the field nodes themselves. In the old schema, field values were all contained in the <data /> nodes and the pages in the <node /> node.

  4. string(umbracoNaviHide) != 1 checks to make sure that the document node does not contain an <umbracoNaviHide /> node with a value of 1.

Now take a look at Listing 11-6 to see what this same script looks like in Umbraco 4.0.x and earlier. The difference here is that the script now specifies that it's looking for all nodes named node, as opposed to the wildcard in 4.5.x. Also, to check whether the field umbracoNaviHide equals 1, you must query for it by the node name data and checking its attribute value.

LISTING 11-6: ListAllPages-40x.xslt

image
<?xml version=“1.0” encoding=“UTF-8”?>
<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp “&#x00A0;”> ]>
<xsl:stylesheet
       version=“1.0”
       xmlns:xsl=“http://www.w3.org/1999/XSL/Transform”
       xmlns:msxml=“urn:schemas-microsoft-com:xslt”
       xmlns:umbraco.library=“urn:umbraco.library”
xmlns:Exslt.ExsltCommon=“urn:Exslt.ExsltCommon”
xmlns:Exslt.ExsltDatesAndTimes=“urn:Exslt.ExsltDatesAndTimes”
xmlns:Exslt.ExsltMath=“urn:Exslt.ExsltMath”
xmlns:Exslt.ExsltRegularExpressions=“urn:Exslt.ExsltRegularExpressions”
xmlns:Exslt.ExsltStrings=“urn:Exslt.ExsltStrings”
xmlns:Exslt.ExsltSets=“urn:Exslt.ExsltSets”
xmlns:umbusersguide.library=“urn:umbusersguide.library”
       exclude-result-prefixes=“msxml umbraco.library Exslt.ExsltCommon
Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions
Exslt.ExsltStrings Exslt.ExsltSets umbusersguide.library “>

    <xsl:output method=“xml” omit-xml-declaration=“yes” />

    <xsl:param name=“currentPage”/>

    <xsl:template match=“/”>
           <!-- The fun starts here -->
           <ul>
           <xsl:for-each
               select=“umbraco.library:GetXmlAll()/descendant::node
               [string(data[@alias=‘umbracoNaviHide’] != ‘1’]”>
                 <li class=“level-{@level}”> <!-- create indentations using
                                                 CSS class definitions -->
                        <a href=“{umbraco.library:NiceUrl(@id)}”>
                               <xsl:value-of select=“@nodeName”/>
                       </a>
                 </li>
           </xsl:for-each>
           </ul>
    </xsl:template>
</xsl:stylesheet>

Counting, Looping, and Conditional Statements

Suppose you want to loop out some nodes, but want only the latest three of them, and they must have a value. Imagine that you want to apply this looping to the FAQs list on your homepage. Listing 11-7 does this task for Umbraco version 4.5.x and later.

LISTING 11-7: ListLatestFaqs.xslt

image
<?xml version=“1.0” encoding=“UTF-8”?>
<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp “&#x00A0;”> ]>
<xsl:stylesheet
    version=“1.0”
    xmlns:xsl=“http://www.w3.org/1999/XSL/Transform”
    xmlns:msxml=“urn:schemas-microsoft-com:xslt”
    xmlns:umbraco.library=“urn:umbraco.library”
xmlns:Exslt.ExsltCommon=“urn:Exslt.ExsltCommon”
xmlns:Exslt.ExsltDatesAndTimes=“urn:Exslt.ExsltDatesAndTimes”
xmlns:Exslt.ExsltMath=“urn:Exslt.ExsltMath”
xmlns:Exslt.ExsltRegularExpressions=“urn:Exslt.ExsltRegularExpressions”
xmlns:Exslt.ExsltStrings=“urn:Exslt.ExsltStrings”
xmlns:Exslt.ExsltSets=“urn:Exslt.ExsltSets”
xmlns:umbusersguide.library=“urn:umbusersguide.library”
    exclude-result-prefixes=“msxml umbraco.library Exslt.ExsltCommon
Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions
Exslt.ExsltStrings Exslt.ExsltSets umbusersguide.library “>

    <xsl:output method=“xml” omit-xml-declaration=“yes” />

    <xsl:param name=“currentPage”/>

    <!-- Specify the document type -->
    <xsl:variable name=“documentTypeAlias” select=“string(‘FAQ’)”/>

    <xsl:template match=“/”>
        <!-- Output latest FAQs list -->
        <h2>Latest FAQs</h2>
        <ul>
        <xsl:for-each select=“$currentPage/* [name() = $documentTypeAlias and
string(umbracoNaviHide) != ‘1’]”>
            <!-- specify sort order so we get the latest
            updated FAQ first -->
            <xsl:sort select=“@updateDate” order=“descending” />

            <!-- Test to make sure that the current
            position in the loop is less than or equal
            to 3 -->
            <xsl:if test=“position()&lt;=3”>
                <li>
                    [<xsl:value-of
select=“umbraco.library:FormatDateTime(@updateDate,'MM/dd/yy hh:mm:ss')” />]
                    <a href=“{umbraco.library:NiceUrl(@id)}”>
                        <xsl:value-of select=“@nodeName”/>
                    </a>
                </li>
            </xsl:if>
        </xsl:for-each>
        </ul>
    </xsl:template>
</xsl:stylesheet>

The following list breaks down what's going on in Listing 11-7:

  • currentPage: This variable contains all the XML from the node where the XSLT is executed and its child elements. Remember that currentPage can always be used as a starting point even if you are traversing the content tree upwards using the ancestor axis. This is a much more efficient way to query content because you are not asking for the entire cache every time, like you would with umbraco.library:GetXMLAll(), for example.
  • name(): This built-in function retrieves the name of the node; that is, <TextPage …/> will return TextPage.
  • xsl:sort: This tells the parser to sort the returning records by the given select statement. The select statement can be any valid XPath statement.
  • position(): This is another built-in node set function that provides you with the current position within the for-each loop. It's much like a manually incremented index in a standard .NET for loop.

For good measure, Listing 11-8 shows how to list the latest FAQs in Umbraco version 4.x.

LISTING 11-8: ListLatestFaqs-40x.xslt

image
<?xml version=“1.0” encoding=“UTF-8”?>
<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp “&#x00A0;”> ]>
<xsl:stylesheet
    version=“1.0”
    xmlns:xsl=“http://www.w3.org/1999/XSL/Transform”
    xmlns:msxml=“urn:schemas-microsoft-com:xslt”
    xmlns:umbraco.library=“urn:umbraco.library”
xmlns:Exslt.ExsltCommon=“urn:Exslt.ExsltCommon”
xmlns:Exslt.ExsltDatesAndTimes=“urn:Exslt.ExsltDatesAndTimes”
xmlns:Exslt.ExsltMath=“urn:Exslt.ExsltMath”
xmlns:Exslt.ExsltRegularExpressions=“urn:Exslt.ExsltRegularExpressions”
xmlns:Exslt.ExsltStrings=“urn:Exslt.ExsltStrings”
xmlns:Exslt.ExsltSets=“urn:Exslt.ExsltSets”
xmlns:umbusersguide.library=“urn:umbusersguide.library”
    exclude-result-prefixes=“msxml umbraco.library Exslt.ExsltCommon
Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions
Exslt.ExsltStrings Exslt.ExsltSets umbusersguide.library “>

    <xsl:output method=“xml” omit-xml-declaration=“yes” />

    <xsl:param name=“currentPage”/>

    <!-- Specify the document type -->
    <xsl:variable name=“documentTypeAlias” select=“string(‘FAQ’)”/>

    <xsl:template match=“/”>
        <!-- Output latest FAQs list -->
        <h2>Latest FAQs</h2>
        <ul>
        <xsl:for-each select=“$currentPage/node
[@nodeTypeAlias=$documentTypeAlias and string(data [@alias=‘umbracoNaviHide’])
!= ‘1’]”>
            <!-- specify sort order so we get the latest
            updated FAQ first -->
            <xsl:sort select=“@updateDate” order=“descending” />

            <!-- Test to make sure that the current
            position in the loop is less than or equal
            to 3 -->
            <xsl:if test=“position()&lt;=3”>
                <li>
                    [<xsl:value-of
select=“umbraco.library:FormatDateTime(@updateDate,'MM/dd/yy hh:mm:ss')” />]
                    <a href=“{umbraco.library:NiceUrl(@id)}”>
                        <xsl:value-of select=“@nodeName”/>
                    </a>
                </li>
            </xsl:if>
        </xsl:for-each>
        </ul>
    </xsl:template>

</xsl:stylesheet>

For a list of available node set functions, see Table 11-2.

TABLE 11-2: Node Set Functions

FUNCTION DESCRIPTION
last() Returns the number of nodes in a node set.
position() Returns the position of the context node (current node). The starting value is 1. As you loop through each node, the position increments.
count(node1, node2, …) Returns the total number of nodes in the node set as provided between the parentheses. If you leave the parentheses blank, it will use the context node.
id((string1, string2, …) node) Returns the nodes whose ID matches the string (s) passed to the function.
local-name(node_set) Returns the local name of the first node in the node set. The local name is the name without the namespace prefix. To use the context node, simply leave node_set blank.
name(node_set) Returns the full, qualified name of the first node in the node set. To use the context node, simply leave node_set blank.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset