Copied to clipboard

Flag this post as spam?

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


  • Daniel Horn 319 posts 344 karma points
    Feb 03, 2011 @ 12:37
    Daniel Horn
    0

    Show childs of page and childs of these childs

    Hi

    I have this structure:

    - Employees

    -- Department A

    --- employee 1

    --- employee 2

    -- Department B

    --- employee 4

    --- employee 5

     

    How would you guys do this in XSLT?

    I'm thinking something like a for each that loops through the childs of Employees and then a foreach in that foreach that loops through the childs of the departments? But is that the smartest way?

     

    Want it shown on the page like this:

    Employees page:

    - Finance

    -- Person 1

    -- Person 2

    - Sales

    -- Person 4

    -- Person 5

  • Jan Skovgaard 11280 posts 23678 karma points MVP 11x admin c-trib
    Feb 03, 2011 @ 12:49
    Jan Skovgaard
    1

    Hi Daniel

    Please forget about the loopy loop stuff you just described above. It's indeed possible but I really don't think that's the way to go. Bad performance and ugly to look at and easy to get confused about (Believe me, I've been there).

    I think you should try and give the predefined "sitemap" xslt, that you can find when creating a XSLT macro in the developer section a look. It goes through all the nodes recursively listing them in a structure like the one you describe above.

    Hope this helps.

    /Jan

    PS: I bet mr. Steinmeier has got an even smarter solution for you if he sees this post ;-)

  • Daniel Horn 319 posts 344 karma points
    Feb 03, 2011 @ 12:54
    Daniel Horn
    0

    Thanks Jan - I will check it out!

    I think you're right, he might have a golden solution for this ;-)

  • Chris Houston 535 posts 980 karma points MVP admin c-trib
    Feb 06, 2011 @ 13:06
    Chris Houston
    1

    Hi Daniel,

    Do you want to show all levels from 1 - n and all the nodes within those levels?

    One thing you might want to look at is APPLY-TEMPLATES which can work recursively depending on how your format the MATCH criteria.

    Have a look at the W3C example here: XSL:APPLY-TEMPLATES Example

    This is usually much better than using a "for-each"

    What it does not show you in the example above is you can apply-templates to a specific selection of nodes, e.g.

    <xsl:apply-templates select="$currentPage/Departments | $currentPage/AnotherNodeType" />

    You can use any XPATH section to decide which nodes you wish to Apply the templates for and then if a match is found the child template will render, as mentioned above this can be recursive so you could apply templates on all children and then the template match could match ALL and then apply templates in it's children, etc.

    I hope this makes sense :)

    Cheers,

    Chris

  • Daniel Horn 319 posts 344 karma points
    Feb 06, 2011 @ 13:12
    Daniel Horn
    0

    Actually the whole structure is like this:

    - Frontpage

    -- Employees

    --- Department #1

    ---- Employee #1

    ---- Employee #2

    ---- Employee #3

    --- Department #2

    ---- Employee #4

    ---- Employee #6

     

    This i want to show on my employees page with some more details on each employee.

    So its a list of employees which is shown under their correct department.

    It makes sense - I just can't really see how i can group them under their correct department?

    I'll look some more into apply templates.. :-)

  • Chris Houston 535 posts 980 karma points MVP admin c-trib
    Feb 06, 2011 @ 13:26
    Chris Houston
    3

    Hi Daniel,

    Is that the structure you have within the Umbraco content tree in the back end or is the data coming from somewhere else?

    Assuming you have the structure the same in the backend then the nodes render in the sort order they are in the backend, hopefully the below helps a little more:

        <xsl:template match="department">
    <div class="department">
    <h1>
    Department <xsl:value-of select="./@nodeName"/>
    </h1>
    <ul class="employeeList">
    <xsl:apply-templates select="./employee"/>
    </ul>
    </div>
    </xsl:template>

    <xsl:template match="employee">
    <li>
    <xsl:value-of select="./@nodeName"/>
    </li>
    </xsl:template>
  • Daniel Horn 319 posts 344 karma points
    Feb 06, 2011 @ 13:30
    Daniel Horn
    0

    Hi Chris,

    That makes sense :-)

    It's the structure in the backend so your XSLT snippets looks like it could work - I'll play around with it and get back with the result. 

  • Daniel Horn 319 posts 344 karma points
    Feb 06, 2011 @ 14:03
    Daniel Horn
    0

    Actually it works when i do it in my xml editor, but when I try it in Umbraco it doesnt... I thinks its the xpaths which is wrong?

  • Chris Houston 535 posts 980 karma points MVP admin c-trib
    Feb 06, 2011 @ 14:10
    Chris Houston
    0

    Hi Daniel,

    I assume your realised that you also need the top level template on which you need to APPLY-TEMPLATES with a select that will return all your Departments.

    If you post the code you now have, I might be able to help.

    Cheers,

    Chris

  • Daniel Horn 319 posts 344 karma points
    Feb 06, 2011 @ 15:37
    Daniel Horn
    0

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="html" indent="yes"/>
          <xsl:variable name="vBaseLink" select="/"/>
        <xsl:template match="EmployeeArea">
            <body>
                <h1>
                    <href="{$vBaseLink}{@urlName}">
                        <xsl:value-of select="@nodeName"/>
                    </a>
                </h1>
                <xsl:apply-templates/>
            </body>
        </xsl:template>
        <xsl:template match="EmployeeDepartment">
            <h2>
                <href="{$vBaseLink}{@urlName}">
                    <xsl:value-of select="@nodeName"/>
                </a>
            </h2>
            <xsl:apply-templates/>
        </xsl:template>
        <xsl:template match="Employee">
            <div>
                <href="{$vBaseLink}{@urlName}">
                    <xsl:value-of select="@nodeName"/>
                </a>
            </div>
        </xsl:template>
    </xsl:stylesheet>

    Tried this - doesnt output anything.. Hmm?

  • Chris Houston 535 posts 980 karma points MVP admin c-trib
    Feb 06, 2011 @ 15:54
    Chris Houston
    1

    Hi Daniel,

    You are missing the currentPage definition in your XSLT file, make sure you create your XSLT file originally in Umbraco...

    How about the following:

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

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

    <xsl:param name="currentPage"/>

    <xsl:template match="/">

    <xsl:apply-templates select="$currentPage/ancestor-or-self::*[@isDoc]['EmployeeArea']" />

    </xsl:template>

    <xsl:template match="EmployeeArea">
    <body>
    <h1>
    <a href="{umbraco.library:NiceUrl(@id)}">
    <xsl:value-of select="@nodeName"/>
    </a>
    </h1>
    <xsl:apply-templates select="./EmployeeDepartment"/>
    </body>
    </xsl:template>

    <xsl:template match="EmployeeDepartment">
    <h2>
    <a href="{umbraco.library:NiceUrl(@id)}">
    <xsl:value-of select="@nodeName"/>
    </a>
    </h2>
    <xsl:apply-templates select="./Employee"/>
    </xsl:template>

    <xsl:template match="Employee">
    <div>
    <a href="{umbraco.library:NiceUrl(@id)}">
    <xsl:value-of select="@nodeName"/>
    </a>
    </div>
    </xsl:template>
    </xsl:stylesheet>
  • Daniel Horn 319 posts 344 karma points
    Feb 06, 2011 @ 18:00
    Daniel Horn
    0

    Now i got all the fields from the root node and the employee stuff twice :).

    I'll try to get it right.. 

  • Daniel Horn 319 posts 344 karma points
    Feb 06, 2011 @ 18:01
    Daniel Horn
    0

     

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

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

        <xsl:param name="currentPage"/>
        
        <xsl:template match="/">

            <xsl:apply-templates select="$currentPage/descendant-or-self::*[@isDoc]['EmployeeArea']" />

        </xsl:template>

        <xsl:template match="EmployeeArea">

                <h1>
                    <href="{umbraco.library:NiceUrl(@id)}">
                        <xsl:value-of select="@nodeName"/>
                    </a>
                </h1>

        </xsl:template>

        <xsl:template match="EmployeeDepartment">
            <h2>
                <href="{umbraco.library:NiceUrl(@id)}">
                    <xsl:value-of select="@nodeName"/>
                </a>
            </h2>
            
        </xsl:template>

        <xsl:template match="Employee">
            <div>
                <href="{umbraco.library:NiceUrl(@id)}">
                    <xsl:value-of select="@nodeName"/>
                </a>
            </div>
        </xsl:template>
    </xsl:stylesheet>

    This works.. If anyone else needs it in the future :)

     

  • Chris Houston 535 posts 980 karma points MVP admin c-trib
    Feb 06, 2011 @ 18:18
    Chris Houston
    0

    I think you will find that it will only work on your current page, if you try and use the same XSLT macro on a lower level page it probably won't work.

    What you probably need to do it to change your initial select so that it always selects the top level node of your employee structure.

    Cheers,

    Chris

  • Daniel Horn 319 posts 344 karma points
    Feb 06, 2011 @ 18:28
    Daniel Horn
    0

    Thanks for all your help Chris ! Now I understand apply templates :-).

    In this case it's only going to be used on that currentpage but i see your point.

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Feb 06, 2011 @ 21:27
    Chriztian Steinmeier
    3

    Hi Daniel (+Chris),

    Just a quick observation - adding a predicate with a single string like this one: ['EmployeeArea'] does not change anything - it's interpreted as [true()] which won't include or exclude any nodes from the selection. If, however, you remove the apostrophes and say [EmployeeArea], you filter the selection to only include the nodes that have one or more EmployeeArea childnodes. If the intent was to select only EmployeeArea nodes, it would be enough to just replace the asterisk with EmployeeArea, e.g.:

    <xsl:apply-templates select="$currentPage/descendant-or-self::EmployeeArea" />

    -which will work when EmployeeArea is the currentPage or when EmployeeArea's parent node is currentPage.

    /Chriztian 

     

  • Chris Houston 535 posts 980 karma points MVP admin c-trib
    Feb 06, 2011 @ 21:38
    Chris Houston
    0

    Hi Chriztian,

    Well spotted on the quotes, that was a typo on my part.

    Cheers,

    Chris

  • Daniel Horn 319 posts 344 karma points
    Feb 08, 2011 @ 15:38
    Daniel Horn
    0

    Cool Chriztian, thanks :-)

Please Sign in or register to post replies

Write your reply to:

Draft