Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Chad Schulz 13 posts 46 karma points
    Dec 10, 2010 @ 21:11
    Chad Schulz
    0

    Xslt Recursion Parent Traversal

    I wrote some Xslt to display a header image for a specific page. If the page does not have one uploaded it searches its parent (to keep a section the same). It continues up the content tree until if find on with a banner image, and it uses it. The root page has the default banner image used throughout the site for in the rare case a page traverses all the way to the root.

    I was excited about it and wanted to share, but also looking for feedback. Is there a better/different way to do it? Can this be stramlined?

    <xsl:param name ="currentPage" />

      <xsl:param name ="alternateText" select="$currentPage/pageTitle" />

     

      <xsl:template match="/">

     

        <!-- start writing XSLT -->

        <div id="interior-banner">

          <img>

     

            <xsl:attribute name="src">

              <xsl:call-template name="bannerImage">

                <xsl:with-param name="currentID" select="$currentPage/@id"/>

              </xsl:call-template>

            </xsl:attribute>

     

            <xsl:if test="$alternateText != ''">

              <xsl:attribute name="alt">

                <xsl:value-of select="$alternateText"/>

              </xsl:attribute>

            </xsl:if>

     

            <xsl:if test="$alternateText != ''">

              <xsl:attribute name="alt">

                <xsl:value-of select="$currentPage/@nodeName"/>

              </xsl:attribute>

            </xsl:if>

     

            <xsl:attribute name="height">240</xsl:attribute>

            <xsl:attribute name="width">980</xsl:attribute>

          </img>

        </div>

     

      </xsl:template>

     

      <xsl:template name="bannerImage">

        <xsl:param name="currentID" />

     

          <xsl:if test="umbraco.library:GetXmlNodeById(string($currentID))/interiorBannerImage = ''">

            <xsl:if test="string($currentID) != ''">

              <xsl:call-template name="bannerImage">

                <xsl:with-param name="currentID" select="umbraco.library:GetXmlNodeById($currentID)/../@id" />

              </xsl:call-template>

            </xsl:if>

          </xsl:if>

     

          <xsl:variable name="mediaNode" select="umbraco.library:GetXmlNodeById(string($currentID))/interiorBannerImage" />

          <xsl:if test="$mediaNode != ''"><xsl:value-of select="umbraco.library:GetMedia($mediaNode, 1)/umbracoFile" /></xsl:if>

     

      </xsl:template>

  • Chad Schulz 13 posts 46 karma points
    Dec 10, 2010 @ 21:21
    Chad Schulz
    0

    I am also unable to wrap the code with 'code' style. Nor can I delete this post to update it. If you have the ability, please fix. :(

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Dec 11, 2010 @ 00:48
    Chriztian Steinmeier
    0

    Hi Chad,

    There's a couple of things you can do to streamline this - here's a shorter version:

       <xsl:template match="/">
            <div id="interior-banner">
                <img width="980" height="240" alt="{$currentPage/@nodeName}">
                    <xsl:attribute name="src">
                        <xsl:apply-templates select="$currentPage/ancestor-or-self::*[normalize-space(interiorBannerImage)][1]/interiorBannerImage" />
                    </xsl:attribute>
                    <xsl:if test="normalize-space($alternateText)">
                        <xsl:attribute name="alt">
                            <xsl:value-of select="$alternateText" />
                        </xsl:attribute>
                    </xsl:if>
                </img>
            </div>
        </xsl:template>
    
        <xsl:template match="interiorBannerImage">
            <xsl:variable name="mediaNode" select="umbraco.library:GetMedia(., true())" />
            <xsl:if test="not($mediaNode[error])">
                <xsl:value-of select="umbracoFile" />
            </xsl:if>
        </xsl:template>
    
    Notice the XPath for the src attribute - it does the trick of taking the interiorBannerImage property from either $currentPage, $currentPage's parent or the parent's parent etc. (the key here is the ancestor-or-self:: axis - check it out here).
    I've also moved the width, height and alt attributes into the tag as literal attributes (the alt attribute will be overwritten if $alternateText has a value).

    /Chriztian

  • Neil Tootell 73 posts 118 karma points
    Mar 10, 2011 @ 16:42
    Neil Tootell
    0

    Hi Chad - this is really great thanks - I pulled the logic and used perfectly on my own site.

    I use a function to call images and it makes your function very tidy

    Here's the function I use from my XSLT includes folder...

    <xsl:template name="Utils.DisplayImage">
            <xsl:param name="imageId"/>
            <xsl:param name="imagePathOnly"/>
            <xsl:param name="imageWidth"/>
            <xsl:param name="imageAltOverride"></xsl:param>
            <xsl:param name="imageClass"></xsl:param>
            <xsl:if test="$imageId != ''">
                <xsl:variable name="mediaXml" select="umbraco.library:GetMedia($imageId, 0)"/>
                <xsl:variable name="umbracoFile" select="$mediaXml/umbracoFile"/>
                <xsl:variable name="umbracoWidth" select="$mediaXml/umbracoWidth"/>
                <xsl:variable name="umbracoAlt">
                    <xsl:choose>
                        <xsl:when test="$imageAltOverride != ''">
                            <xsl:value-of select="$imageAltOverride" />
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="$mediaXml/umbracoAlt" />
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:variable>
                <xsl:choose>
                    <xsl:when test="$imagePathOnly = '1'">
                        <xsl:value-of select="$umbracoFile"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <img>
                            <!-- Use ImageGen to resize on the fly if needed -->
                            <xsl:choose>
                                <xsl:when test="$imageWidth != '' and number($umbracoWidth) &gt; $imageWidth">
                                    <xsl:attribute name="src">
                                        <xsl:value-of select="concat($imageGeneratorPath, '?image=', $umbracoFile, '&amp;width=', $imageWidth)"/>
                                    </xsl:attribute>
                                </xsl:when>
                                <xsl:otherwise>
                                    <xsl:attribute name="src">
                                        <xsl:value-of select="$umbracoFile"/>
                                    </xsl:attribute>
                                </xsl:otherwise>
                            </xsl:choose>
                            <!-- Add class if needed -->
                            <xsl:if test="string($imageClass) != ''">
                                <xsl:attribute name="class">
                                    <xsl:value-of select="$imageClass"/>
                                </xsl:attribute>
                            </xsl:if>
                            <!-- Add alt text -->
                            <xsl:attribute name="alt">
                                <xsl:value-of select="$umbracoAlt"/>
                            </xsl:attribute>
                        </img>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:if>
        </xsl:template>

    If you don't use imageGen you'll need to strip that bit out, but a basic 4.6+ call to it goes like this...

    <xsl:call-template name="Utils.DisplayImage">
    <xsl:with-param name="imageId" select="$pageImage"/>
    </xsl:call-template>

     

    Many thanks for you recursiveness :)

    Neil

Please Sign in or register to post replies

Write your reply to:

Draft