Copied to clipboard

Flag this post as spam?

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


  • Molly 94 posts 134 karma points
    Oct 04, 2012 @ 22:50
    Molly
    0

    Display content from each child node seperately on the parent page

    Hi All, 

    I am trying to display the content of each child node of the parent on the parent page. I have a page named:

    Work (parent node) 

    Creative (child)

    Business (child) 

    Market (child)

    within each child i have project items for each node, now i can get all the project items to show on the parent page, but i want it to display each child node content on seperate lines e.g.

    Creative 

    {projectItem} {projectItem} {projectItem}

    Business

    {projectItem} {projectItem} {projectItem}

    Market

    {projectItem} {projectItem} {projectItem}

    Styled in Div's, i know it is probably something simple. 

    In my XSLT file i have 

    $currentPage/ProjectGroupPage/ProjectItem

    and this displays them all from all nodes,

    my aim is to have 

    $currentPage/Creative/ProjectItem and so on for each. 

    this is what i have so far.

     

    version="1.0" encoding="UTF-8"?>
    xsl:stylesheet [
      
    ]>
    <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:autofolders.library="urn:autofolders.library" xmlns:uTube.XSLT="urn:uTube.XSLT"
      exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets autofolders.library uTube.XSLT ">


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

        <xsl:param name="currentPage"/>


    <xsl:template match="/">
      <xsl:for-each select="$currentPage/Creative/ProjectItem">
      <div class="item">

                  <href="{umbraco.library:NiceUrl(@id)}">
                  <img id="project-home-image">
                    <xsl:attribute name="src">
                      <xsl:text>/imageGen.ashx?image=xsl:text>
                      <xsl:value-of select="RF-Slide/image"/>
                      <xsl:text>&width=172&height=166xsl:text>
                    xsl:attribute>
                    <xsl:attribute name="alt">
                      <xsl:value-of select="title"/>
                    xsl:attribute>
                  img>
                 a>
             <href="{umbraco.library:NiceUrl(@id)}">
                 <h2>
                    
                    <xsl:value-of select="@nodeName"/>
                h2>
                 a>
                
             
        

              div>


       
    xsl:for-each>

     xsl:template>
    xsl:stylesheet>

    Any help would be greatly appreciated! 

    Thanks

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Oct 04, 2012 @ 23:04
    Chriztian Steinmeier
    0

    Hi Molly,

    The trick is to create simple templates to handle each of the elements you need, e.g. somethiing like this:

    <xsl:template match="/">
        <!-- Process all ProjectGroupPage children of $currentPage -->
        <xsl:apply-templates select="$currentPage/ProjectGroupPage" />
    </xsl:template>
    
    <xsl:template match="ProjectGroupPage">
        <h2><xsl:value-of select="@nodeName" /></h2>
    
        <!-- Process all ProjectItem children of this ProjectGroupPage -->
        <xsl:apply-templates select="ProjectItem" />
    </xsl:template>
    
    <xsl:template match="ProjectItem">
        <div class="item">
            <a href="{umbraco.library:NiceUrl(@id)}">
                <img id="project-home-image" src="/imageGen.ashx?image={RF-Slide/image}&amp;width=172&amp;height=166" alt="{title}" />
            </a>
            <a href="{umbraco.library:NiceUrl(@id)}">
                <h2><xsl:value-of select="@nodeName"/></h2>
            </a>
        </div>
    </xsl:template>
    

    Now - it's not totally obvious if all your wrappers are of document type ProjectGroupPage or some are of other doctypes - if they are, you can match more than one type in a template:

    <xsl:template match="ProjectGroupPage | CreativeGroupPage | BusinessGroup">

    /Chriztian

     

  • Molly 94 posts 134 karma points
    Oct 05, 2012 @ 13:47
    Molly
    0

    Thank you! That worked perfectly exactly how i wanted it to be :) 

     

  • Molly 94 posts 134 karma points
    Oct 05, 2012 @ 14:09
    Molly
    0

    I would like to have only a certain number of the project items showing on the page i.e first 4/5 i have implemented this for blog feeds in razor but not xslt. 

    Thanks 

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Oct 07, 2012 @ 00:35
    Chriztian Steinmeier
    0

    Hi Molly,

    Sorry I hadn't seen the question about limiting output.

    To do that you can add a so-called "predicate" to the apply-templates instruction, e.g.:

    <xsl:apply-templates select="ProjectItem[position() &lt;= 5]" />


    There's a little caveat though - if you happen to need sorting the nodes, you'd normally just "open" the apply-templates and throw that in, like this:

     <xsl:apply-templates select="ProjectItem[position() &lt;= 5]">
        <xsl:sort select="@createDate" data-type="text" order="descending" />
    </xsl:apply-templates>  

    But that will actually only sort the 5 selected nodes by date - when what you'd usually want was to get the 5 newest nodes.

    For that you can use a for-each instruction:

    <xsl:for-each select="ProjectItem">
        <xsl:sort select="@createDate" data-type="text" order="descending" />
        <xsl:if test="position() &lt;= 5">
            <xsl:apply-templates select="." />
        </xsl:if>
    </xsl:for-each>
    

    Not that you're still using the generic template for the actual rendering, which is rather nice :-) 

    /Chriztian

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Oct 07, 2012 @ 00:37
    Chriztian Steinmeier
    0

    Correction: That last line should read: "Note that you're still using ..."

    /Chriztian 

  • Molly 94 posts 134 karma points
    Oct 09, 2012 @ 15:36
    Molly
    0

    Thank you very much! 

  • Molly 94 posts 134 karma points
    Oct 09, 2012 @ 21:23
    Molly
    0

    to extend this i would like to be able to add seperate styling to the first projectitem of each section. would i do this by adding another template and selecting the position of the 1st item and applying a class to it? 

     

    Thank you in advance. you are very helpful and i'm learning a lot by breaking it down.

     

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

    Hi Molly,

    To do that, one needs just a little information about how the position() function works - it returns the position of the "current node" within the "current node list" (neither of these have anything to do with Umbraco's $currentPage parameter). The current node is the ProjectItem element when you're inside that template; or if you're inside a for-each "loop" it's the current node in the loop.

    The current node list is all the nodes selected by the select attribute in an apply-templates or a for-each instruction.

    So, in your current scenario, if you were to print the value of position() within the for-each loop, you'd get 1, 2, 3, 4, 5, 6, 7 etc. - but if you print the value from within the ProjectItem template, you'll get 1, 1, 1, 1 etc. - because we only apply-templates to a single element (the current) in the for-each.

    The way I usually handle this is by sending an index parameter into the template - like this:

    <xsl:for-each select="ProjectItem">
        <xsl:sort select="@createDate" data-type="text" order="descending" />
        <xsl:if test="position() &lt;= 5">
            <xsl:apply-templates select=".">
                <xsl:with-param name="index" select="$position()" />
            </xsl:apply-templates>
        </xsl:if>
    </xsl:for-each>
    
    <xsl:template match="ProjectItem">
        <xsl:param name="index" />
        <div class="item">
            <xsl:if test="$index = 1"><!-- Override the class attribute on first item --> <xsl:attribute name="class">first item</xsl:attribute> </xsl:if>
            <a href="{umbraco.library:NiceUrl(@id)}">
                <img id="project-home-image" src="/imageGen.ashx?image={RF-Slide/image}&amp;width=172&amp;height=166" alt="{title}" />
            </a>
            <a href="{umbraco.library:NiceUrl(@id)}">
                <h2><xsl:value-of select="@nodeName"/></h2>
            </a>
        </div>
    </xsl:template>

    This makes you keep the separate template - and it's easy to see what's happening.

    /Chriztian

  • Molly 94 posts 134 karma points
    Oct 10, 2012 @ 13:50
    Molly
    0

    Ok, so i think i have everything in the right place. Here is my code now: 

    <?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:autofolders.library="urn:autofolders.library" xmlns:uTube.XSLT="urn:uTube.XSLT"
      exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets autofolders.library uTube.XSLT ">


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

        <xsl:param name="currentPage"/>


    <xsl:template match="/">
            <!-- Process all ProjectGroupPage children of $currentPage -->
            <xsl:apply-templates select="$currentPage/ProjectGroupPage" />
        </xsl:template>

    <xsl:template match="ProjectGroupPage">
            <h1><xsl:value-of select="@nodeName" /></h1>
      
            <!-- Process all ProjectItem children of this ProjectGroupPage -->
    <xsl:apply-templates select="ProjectItem" />
      
      <xsl:for-each select="ProjectItem">
            <xsl:sort select="@createDate" data-type="text" order="descending" />
            <xsl:if test="position() &lt;= 4">
                    <xsl:apply-templates select=".">
              <xsl:with-param name="index" select="$position()" />
         </xsl:apply-templates>
            </xsl:if>
    </xsl:for-each>
      
       </xsl:template>
    <xsl:template match="ProjectItem">
      <xsl:param name="index" />
            <div class="item">
              <xsl:if test="$index =1">
                <!--override the class attribute on first item --> 
                <xsl:attribute name="class">first item</xsl:attribute
              </xsl:if>
                    <href="{umbraco.library:NiceUrl(@id)}">
                            <img id="project-home-image" src="/imageGen.ashx?image={RF-Slide/image}&amp;width=172&amp;height=166" alt="{title}" />
                    </a>
                    <href="{umbraco.library:NiceUrl(@id)}">
                            <h2><xsl:value-of select="@nodeName"/></h2>
                    </a>
            </div>
    </xsl:template>
                
    </xsl:stylesheet>

     

    It gives me this error: (I looked into the with-param element and checked it seems to look fine. )

    Error occured

    Error in XSLT at line 33, char 11
    31:       <xsl:if test="position() &lt;= 4">
    32:       <xsl:apply-templates select=".">
    33: >>>   <xsl:with-param name="index" select="$position()" /> <<<
    34:       </xsl:apply-templates>
    35:       </xsl:if>

     

    Thanks Chriztian

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Oct 10, 2012 @ 13:55
    Chriztian Steinmeier
    0

    Oh - my bad :-(

    It should read like this (without the dollar sign):

    <xsl:with-param name="index" select="position()" />

    Also, you should remove this line (just above the for-each):

     <xsl:apply-templates select="ProjectGroupPage" />

    since you're now using a for-each because of the sorting/limiting.

    /Chriztian

  • Molly 94 posts 134 karma points
    Oct 10, 2012 @ 14:05
    Molly
    0

    Great, that's perfect! Thank you. 

    I resized the image for the first item through css, is it possible for me to apply the img for the first item within that code to have the imageGen on there to resize the first to the new size 280px wide? like it is underneath. 

     

  • Molly 94 posts 134 karma points
    Oct 10, 2012 @ 14:58
    Molly
    0

    I figured out a way, 

    I set the height and width i wanted the images to be in the css and then in the xslt i set the imageGen width and height to 100% and it worked perfect :) 

    I want to specifically target each section within the xslt so that say i have 3 sections 

    Marketing 

    <projectItem> <projectItem> <projectItem> <projectItem> more..links to projectgrouppage = marketing

    Creative

    <projectItem> <projectItem> <projectItem> <projectItem> <more..links to projectgrouppage = creative>

    Lead 

    <projectItem> <projectItem> <projectItem> <projectItem> <more..links to projectgrouppage = lead>

     

    i want to add a small <more..> link on the end of each section to go to the parent page (ProjectGroupPage) of the (ProjectItems) within each section. 

    I'm guessing i could add this as another attribute after the initial attribute i already have linking to the parent ? 

     

  • Molly 94 posts 134 karma points
    Oct 10, 2012 @ 16:23
    Molly
    0

    I actually also figured that out i added the attribute here : 

            <xsl:with-param name="index" select="position()" />
         </xsl:apply-templates>
            </xsl:if>
    </xsl:for-each>
      <href="{umbraco.library:NiceUrl(@id)}"><img src="/media/8350/arrow.jpg" alt="More..." /></a>
       </xsl:template>
    <xsl:template match="ProjectItem">

     

    Just after the closing of for-each and before closing of template and it worked perfect :) 

  • Molly 94 posts 134 karma points
    Oct 10, 2012 @ 20:40
    Molly
    0

    Sorry to be a pain, but I'm spending quite some time trying to get 2 of those project items any it doesn't matter to display on the homepage. I can either get 2 of each projectgrouppage project items to display or all of the project items. It seems to ignore the sorting i put in there. This is what i have ..

    <?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:autofolders.library="urn:autofolders.library" xmlns:uTube.XSLT="urn:uTube.XSLT"
      exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets autofolders.library uTube.XSLT ">


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

    <xsl:param name="currentPage"/>


    <xsl:template match="/">

      <!-- start writing XSLT -->

      <xsl:apply-templates select="$currentPage/OurWork/ProjectGroupPage" />
        </xsl:template>
        <xsl:template match="ProjectItem" >
         <xsl:for-each select="ProjectItem">
            <xsl:sort select="@createDate" data-type="text" order="descending" />
            <xsl:if test="position() &lt;= 2">
              <xsl:apply-templates select="." />
            </xsl:if>
        </xsl:for-each>
       
              <div class="home-item">

                  <href="{umbraco.library:NiceUrl(@id)}">
                  <img id="project-home-image">
                    <xsl:attribute name="src">
                      <xsl:text>/imageGen.ashx?image=</xsl:text>
                      <xsl:value-of select="RF-Slide/image"/>
                      <xsl:text>&amp;width=172&amp;height=166</xsl:text>
                    </xsl:attribute>
                    <xsl:attribute name="alt">
                      <xsl:value-of select="projectTitle"/>
                    </xsl:attribute>
                  </img>
                 </a>
             <href="{umbraco.library:NiceUrl(@id)}">
                 <h2>
                    <!--<xsl:attribute name="title">
                      <xsl:value-of select="projectTitle"/>
                    </xsl:attribute>-->
                    <xsl:value-of select="@nodeName"/>
                </h2>
                 </a>
                 
            <!-- <p><xsl:value-of select="projectSummary"/></p> -->

              </div>
      </xsl:template>
    </xsl:stylesheet>

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Oct 11, 2012 @ 10:31
    Chriztian Steinmeier
    0

    Hi Molly,

    It just seems like you're a little confused about apply-templates, for-each and templates. No worries, you'll grok it eventually!

    This is how you'd put it together - the comments should help you with what's going on:

    <!-- Grab all the relevant ProjectItems -->
    <xsl:variable name="projectItems" select="$currentPage/OurWork/ProjectGroupPage/ProjectItem" />
    
    <xsl:template match="/">
        <!-- Only show the latest 2 project items -->
        <xsl:for-each select="$projectItems">
            <xsl:sort select="@createDate" data-type="text" order="descending" />
            <xsl:if test="position() &lt;= 2">
                <xsl:apply-templates select="." />
            </xsl:if>
        </xsl:for-each>
    </xsl:template>
    
    <!-- This is the template for a single item -->
    <xsl:template match="ProjectItem" >
        <div class="home-item">
            <!-- You know this... -->
        </div>
    </xsl:template>

    Please note that just by extracting the long select from the for-each into a variable, that it's suddenly much easier to "read" what's going on, right?

    /Chriztian 

  • Molly 94 posts 134 karma points
    Oct 11, 2012 @ 15:27
    Molly
    0

    It's much easier looking at it like that! I seem to confuse myself and make it so complicated and lost! This helps alot so thank you! 

    Since then the projects to display on the homepage have changed slightly, as i was using a multinode picker then i swapped to the one above to come in automatically but now they want the treepicker back so they can select 4 items for the homepage with the first having its own style, I'm pretty sure i can implement the param for the class to the first item, i have had the multinode working when my project items were originally under one node <our work> under <homepage> but now i have child sections<projectgrouppage> under the <our work> and the project items are under each of those project group pages, i get the node to show all of those but for some reason they are all red and won't drag over. 

    This is what i have (it's strange because one minute it was only displaying the <our work > node and the next it was displaying the children underneat, so i'm unsure whether it's something i'm doing or it's basically just glitchy :S 


      <xsl:for-each select="$currentPage/ancestor-or-self::*/Homepage/projectsToDisplayOnHomepage/MultiNodePicker/nodeId">
        <xsl:variable name="myPosition" select="position()"/>
        <xsl:variable name="idProject" select="."/>

        <xsl:for-each select="$currentPage/ancestor-or-self::*/Homepage/OurWork/ProjectGroupPage/ProjectItem">

          <xsl:variable name="idNodePicker" select="@id"/>

            <xsl:if test="$idNodePicker = $idProject">
             

             <xsl:if test="$myPosition mod 4 = 0">
                <xsl:text disable-output-escaping="yes"><![CDATA[<div class="item-row"]]></xsl:text>
                <xsl:text disable-output-escaping="yes"><![CDATA[>]]></xsl:text>
              </xsl:if>

     

    This is my screenshot 


  • Molly 94 posts 134 karma points
    Oct 11, 2012 @ 18:17
    Molly
    0

    I was wrong, it seems i am struggling with where to place the with-param function as i'm now looking at unfamiliar elements with the multinode picker, my bad! 

Please Sign in or register to post replies

Write your reply to:

Draft