Copied to clipboard

Flag this post as spam?

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


  • Graeme Paul 44 posts 64 karma points
    Aug 10, 2011 @ 17:40
    Graeme Paul
    0

    xslt dilemma

    hey guys, im creating a online jquery slideshow using umbraco and have come across some things i am unsure of. I have a layout like below, I have a master template which has a xslt which shows all the slides by $currentPage/descendant-or-self::* However i would like one of my pages to display the 3 child elements which contain information about product etc. My slidehow has a structure like below

    first slide
    -------slide 1---
    ------------------product 1
    ------------------product 2
    ------------------product 3
    -------slide 2---
    -------slide 3---
    -------slide 4---

    What is the best way to call these pages? Can i do this via apply template or is it worth including external xslt files? Below is what i have as a starting point.

    <xsl:param name="currentPage"/>
      <xsl:template match="/">
        <ul>
          <xsl:apply-templates select="$currentPage/descendant-or-self::* [@isDoc and string(umbracoNaviHide) != '1']" />
        </ul>
       </xsl:template>
      <xsl:template match="*[@isDoc]">
        <xsl:if test="@nodeName = 'Slide 1' ">
        bbhjkhjkhjk
          <xsl:apply-templates select="product" />
        </xsl:if>
      </xsl:template>
      <xsl:template match="product">
        <li>
        <article class="spot1">
          <div class="product_images">
            <img src="/new_images/magazine/magazine_top5_product1.jpg" alt="main product shot 1" />
            <div class="description">
              <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
            </div>
            <h2>hahahah thisd is a test</h2>
          </div>
        </article>
        </li>
      </xsl:template>
    </xsl:stylesheet>
  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Aug 10, 2011 @ 21:29
    Chriztian Steinmeier
    0

    Hi Graeme,

    You don't even need to test if you're on 'Slide 1' - what if you decide to put products under another one next week?

    Using apply-templates it all just works - when you say <xsl:apply-templates select="product" /> , the processor will collect all <product> elements under the current node, if there ain't any, nothing will happen - tada! :-)

    /Chriztian 

  • Graeme Paul 44 posts 64 karma points
    Aug 10, 2011 @ 23:21
    Graeme Paul
    0

    hey Christian, that is a good point about the slide 1.

    I cant seem to get the below to show, is the below enough for example if i include bodyText from those pages or do i have to put currentpage/product?

    <xsl:apply-templatesselect="product"/>
  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Aug 10, 2011 @ 23:42
    Chriztian Steinmeier
    0

    Hi Graeme,

    Could be a couple of things, most likely due to CasE-sENsitivitY - on the face of it, I'd say your product ought to be Product if it's a seperate DocumentType (lowercase elements are almost always properties.) - so:

    <xsl:template match="/">
        <!-- In here, / refers to the rootnode of the <macro> XML document...  -->
        <!-- So we need to get into the Umbraco XML using $currentPage as a starter. -->
        <!-- Here, we take all descendants of the current page -->
        <xsl:apply-templates select="$currentPage//*[@isDoc][not(umbracoNaviHide = 1)]" />
    </xsl:template>
    
    <!-- Match any Umbraco DocumentType -->
    <xsl:template match="*[@isDoc]">
        <!-- Do something with it -->
    
        <!-- Process any <Product> childnodes -->
        <xsl:apply-templates select="Product" />
    
    </xsl:template>
    
    <xsl:template match="Product">
        <!-- Hey - we found a Product node -->
        <p>
            I'm a Product
        </p>
    </xsl:template>
    

    /Chriztian 

  • Graeme Paul 44 posts 64 karma points
    Aug 11, 2011 @ 11:32
    Graeme Paul
    0

    Thanks for the reply chriztan,  i think i was half asleep when i replied last night. I still cant get the template match to work,  My site structure is more like below, i forgot to include the table of contents

    first slide (which includes first cover)
    ---table of contents
    -----------slide 1---
    ---------------------product 1
    ---------------------product 2
    ---------------------product 3
    -----------slide 2---
    -----------slide 3---
    -----------slide 4---

    I changed my doc type and it hasnt made a difference

    <xsl:param name="currentPage"/>
      <xsl:template match="/">
        <!-- In here, / refers to the rootnode of the <macro> XML document...  -->
        <!-- So we need to get into the Umbraco XML using $currentPage as a starter. -->
        <!-- Here, we take all descendants of the current page -->
        <xsl:apply-templates select="$currentPage/descendant-or-self::*[@isDoc][not(umbracoNaviHide = 1)]" />
      </xsl:template>
      <!-- Match any Umbraco DocumentType -->
      <xsl:template match="*[@isDoc]">
          <!-- Do something with it -->
              <!-- Process any <Product> childnodes -->
        <xsl:apply-templates select="Product" />
      </xsl:template>
      <xsl:template match="Product">
        <!-- Hey - we found a Product node -->
        <p>
          I'm a Product
        </p>
      </xsl:template>
  • Rob Watkins 369 posts 701 karma points
    Aug 12, 2011 @ 11:47
    Rob Watkins
    0

    Are you sure you are actually where you think you are in the document tree?

    I would stick this in at the top:

    <xmp><xsl:copy-of select="$currentPage"/></xmp> 

    Then you can assure yourself that $currentPage is what you think it is. 

    And maybe count() your first selector to check it's matching correctly, too.

  • Rob Watkins 369 posts 701 karma points
    Aug 12, 2011 @ 12:08
    Rob Watkins
    0

    Actually, ignore that, I have just done a quick test and am gettign no output either, I'll get back to you :o)

  • Rob Watkins 369 posts 701 karma points
    Aug 12, 2011 @ 12:18
    Rob Watkins
    0

    Okay, the template matching *[@isDoc] seems to be preventing the Product template from matching. I'm still not 100% sure about where in your structure you are using this, so maybe this is not entirely relevant, but if I have the structure:

    EventsPage
    ---EventsItem
    ---EventsItem
    ---EventsItem

    ...and with $currentPage as EventsPage print out name() from the *[@isDoc] template, I get:

    EventsPage
    EventsItem
    EventsItem
    EventsItem

    ...but the EventsItem specific template (i.e. your Product one) does not fire at all.

    I can fix this by changing the *[@isDoc] match to *[name() != 'EventsItem'][@isDoc], but then obviously you ONLY get the item specific template macthing, which may not be what you want. At any rate, there is definitely a matching issue going on here.

     

     

  • Rob Watkins 369 posts 701 karma points
    Aug 12, 2011 @ 12:30
    Rob Watkins
    1

    http://msdn.microsoft.com/en-us/magazine/cc164105.aspx (search with page for "conflict resolution")

    As both your templates with match your Product and my EventItem nodes, the matching engine will choose the template with the highest priority. As far as I can tell from the rules, matching by name has a priority of 0, but matching by specific attribute (@isDoc) has a priority of 0.5, so the *[@isDoc] template will always be the one used.

    You can see this by adding priority="1" to you match="Product" template - that will give the same behaviour as explicitly excluding those nodes by name as in my last post. If you want to do more hierarchical processing you will have to rethink your original selector, as the descendant-or-self is flattening everything.

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Aug 12, 2011 @ 12:40
    Chriztian Steinmeier
    0

    Good detective work, Rob - I may have been quite sleepy myself, when I posted that answer :-)

    Depending on the scenario, I actually tend to downgrade the generic template (by setting priority="-1") - otherwise I'll have to add the priority attribute to all future DocType templates.

    /Chriztian 

  • Rob Watkins 369 posts 701 karma points
    Aug 12, 2011 @ 13:13
    Rob Watkins
    0

    Are yes, good point. That's why you're an XSLT guru and I'm merely a gifted grasshopper ;o)

  • Graeme Paul 44 posts 64 karma points
    Aug 12, 2011 @ 21:53
    Graeme Paul
    0

    thanks for the help guys, i have added the below with no effect. Is the priority =-1 on the default template match ="/" not where i have put it? Im wondering if my layout is causing some issues as the xlst is pulled directly into a master template and i am just listing all the pages for the slideshow.

    first slide (master template which includes xslt macro )
    ---table of contents
    -----------slide 1--- ( i want to display the child nodes in this page)
    ---------------------product 1
    ---------------------product 2
    ---------------------product 3
    -----------slide 2---
    -----------slide 3---
    -----------slide 4---



     <xsl:template match="/">
        <!-- In here, / refers to the rootnode of the <macro> XML document...  -->
        <!-- So we need to get into the Umbraco XML using $currentPage as a starter. -->
        <!-- Here, we take all descendants of the current page -->
        <xsl:apply-templates select="$currentPage/descendant-or-self::*[@isDoc][not(umbracoNaviHide = 1)]" />
      </xsl:template>
      <!-- Match any Umbraco DocumentType -->
      <xsl:template match="*[@isDoc]" priority="-1">
          <!-- Do something with it -->
        <!--<xsl:value-of select="@nodeName"/>-->
        <!-- Process any <Product> childnodes -->
        <xsl:apply-templates select="Product" />
      </xsl:template>
      <xsl:template match="Product" priority="1">
        <!-- Hey - we found a Product node -->
        <p>
          I'm a Product
        </p>
      </xsl:template>
                 

     

     

  • Graeme Paul 44 posts 64 karma points
    Aug 16, 2011 @ 16:00
    Graeme Paul
    0

    I'm still unable to show to show child elements in each of my slide pages, any ideas?

  • Graeme Paul 44 posts 64 karma points
    Oct 24, 2011 @ 11:51
    Graeme Paul
    0

    Hey guys, ive got the basis of my code working, only thing is when i try to get the child elements of the slide page i get all the child elements of all the slide pages.
    is there a way only to get the children of that parent page?

    first slide (master template which includes xslt macro )
    ---table of contents
    -----------slide 1---( i want to display the child nodes inthis page)
    ---------------------product 1
    ---------------------product 2
    ---------------------product 3
    -----------slide 2---
    -----------slide 3---
    -----------slide 4---

    below is my code. thanks

        
    <xsl:variable name="maxLevelForSitemap" select="5"/>

    <xsl:template match="/">
    <!-- Here, we take all descendants and self (landing page) of the pages-->
    <xsl:apply-templates select="$currentPage/descendant-or-self::*[@isDoc and @level &lt;= $maxLevelForSitemap][not(umbracoNaviHide = 1)]" />
    </xsl:template>
        
      <!-- Match any Umbraco DocumentType -->
      <xsl:template match="*[@isDoc]">
        <xsl:choose>
          <xsl:when test ="local-name() = 'cover_doc'">

            <li data-url="{@nodeName}">
            <div class="slide">
                <h1><xsl:value-of select="@nodeName"/></h1>
              </div>
            </li>
          </xsl:when>     
          <xsl:when test ="local-name() = 'table_of_content_doc'">
            <li data-url="{@nodeName}" >
              <div class="slide">
                <h1><xsl:value-of select="@nodeName"/></h1>
              </div>
            </li>
          </xsl:when>
        <xsl:when test ="local-name() = 'slide1_doc'">
          <li data-url="{@nodeName}" >
            <div class="slide">
              <h1><xsl:value-of select="@nodeName"/></h1>
              <xsl:call-template name="Product">    
            </xsl:call-template>
            </div>
          </li>
        </xsl:when>

      <xsl:otherwise>
        <li data-url="{@nodeName}">
          <xsl:value-of select="@nodeName"/>
        </li>
        </xsl:otherwise>
      </xsl:choose>
      </xsl:template>

      <xsl:template name="Product">
        <!-- Process any [Product] childnodes -->
        <em><!-- Do something with it -->
            <xsl:for-each select="$currentPage/descendant-or-self::* [@level=6]">
              <choose>
                <when test="$currentPage/parent::*[]">
                  <xsl:value-of select="@nodeName"/>
                </when>
                <otherwise>
                  <xsl:value-of select="@nodeName"/>
                </otherwise>
              </choose>
            </xsl:for-each>
        </em>
      </xsl:template>
    </xsl:stylesheet>

     

     

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Oct 24, 2011 @ 12:57
    Chriztian Steinmeier
    1

    Hi Graeme,

    The apply-templates instruction rteally makes stuff like this very easy - try this:

    1. Create a template that matches your "Product" doctype and render a single item in it, e.g.:

    <!-- This will run for every <product_doc> childnode of a <slide1_doc> -->
    <xsl:template match="product_doc">
        <div class="productslide">
            <xsl:value-of select="@nodeName" />
            ...
        </div>
    </xsl:template>
    
    2. "Call" it like this from the parent element:
    <xsl:when test="self::slide1_doc">
        <li data-url="{@nodeName}" >
            <div class="slide">
                <h1><xsl:value-of select="@nodeName"/></h1>
                <!-- Process <product_doc> children     -->
                <xsl:apply-templates select="product_doc" />
            </div>
        </li>
    </xsl:when>
    
     

    /Chriztian

  • wolulcmit 357 posts 693 karma points
    Oct 24, 2011 @ 13:20
    wolulcmit
    0

    apply-templates FTW!

  • Graeme Paul 44 posts 64 karma points
    Oct 24, 2011 @ 16:29
    Graeme Paul
    0

    Thanks Chriztian i added  priority="1" to product_doc template match and it all works!! thanks :)

    is it possible to use the following if I ever wanted to use apply templates multiple times to filter results? or is it better to create separate doc types?

    if test="parent::slide1_doc"

    thanks again! :)

    Graeme

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Oct 24, 2011 @ 22:15
    Chriztian Steinmeier
    0

    Hi Graeme,

    Yes you can - it all depends really - e.g., in the example you've posted you're duplicating the <li data-url="..."> for every type (you're also generating the same output though, but that's probably just simplified for the example) - I would probably have created seperate templates for each of the different doctypes; I generally avoid a choose/when/otherwise like the plaque. I firmly believe they made it that ugly so you'll always see it as a flag that something is not quite as it should be :-)

    /Chriztian

  • Graeme Paul 44 posts 64 karma points
    Nov 30, 2011 @ 13:05
    Graeme Paul
    0

    I Have 2 pages calling the same template match. What i would like to do is show a different image per page, i could do this in css but at this stage it would be easier if i could query the parent ID name. Ive tried the below but it doesnt work. Any ideas?

    <xsl:if test="$currentPage/parent::node/data[@alias = 'Beauty-News']">

    Also is it possible to put a position count on doctypes. I have a slider which has 15 pages, 4 of the 15 are using a certain doctype. Can add a class to my doc type like below?

    1 blah_doc
    2 me_doc (1)
    3 me_doc (2)
    4 me_doc (3)
    5 hello_doc


Please Sign in or register to post replies

Write your reply to:

Draft