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?
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 ;-)
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.
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:
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.
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.
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.:
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
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 ;-)
Thanks Jan - I will check it out!
I think you're right, he might have a golden solution for this ;-)
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
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.. :-)
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:
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.
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?
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
Tried this - doesnt output anything.. Hmm?
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:
Now i got all the fields from the root node and the employee stuff twice :).
I'll try to get it right..
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY nbsp " ">
]>
<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>
<a href="{umbraco.library:NiceUrl(@id)}">
<xsl:value-of select="@nodeName"/>
</a>
</h1>
</xsl:template>
<xsl:template match="EmployeeDepartment">
<h2>
<a href="{umbraco.library:NiceUrl(@id)}">
<xsl:value-of select="@nodeName"/>
</a>
</h2>
</xsl:template>
<xsl:template match="Employee">
<div>
<a 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 :)
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
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.
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.:
-which will work when EmployeeArea is the currentPage or when EmployeeArea's parent node is currentPage.
/Chriztian
Hi Chriztian,
Well spotted on the quotes, that was a typo on my part.
Cheers,
Chris
Cool Chriztian, thanks :-)
is working on a reply...