Does anyone know of a way to list nodes from multiple sources?
I have this content layout: Content |_ Website 1 |_ News |_ News 1 |_ News 2 |_ Website 2 |_ News |_ News 1 |_ News 2
Now, in the News template under Website 1, there is a news listing. I need to list all News nodes in Website 1 and Website 2 here. And it must not list any news from other websites than those two.
If anyone know how to select all nodes with a @nodeTypeAlias that is the child of a master document type, it would also be very welcome. I have a master document type called News, and the I have more specific types of News as sub-documenttypes. What I need is a xslt that finds all nodes based on a common master document type.
My current idea is to pass a comma separated list in the macro and then run a for-each for every @id there, but it is not a pretty solution.
Is it possible to insert another xslt file in the middle of another xslt file? That way I might create some "wrapper" xslt files and do it recursively.
You could create a property yes/no in the document type for a news document type (grouping news doctype vs individual news items) to indicate 'include on news feed' etc. Then in the macro, simple check for this doctypealias of the NEWS document where property = 1, then display all nodes under that?
I noticed this paragraph in your post:If anyone know how to select all nodes with a @nodeTypeAlias that is the child of a master document type, it would also be very welcome."</span>Let's say your News-nodes have nodeTypeAlias="News", and items below News nodes have nodeTypeAlias="NewsItem", then you should be able to select all NewsItem nodes into a variable with the following declaration, and let's say all your websites has a root node with nodeTypeAlias="Website"</span>You should then be able to "chain" your selection criteria together in a xpath statement like this:</span>
<xsl:variable name="newsNodes"
select="$currentPage/ancestor::root//node[@nodeName = 'Website1' or @nodeName =
'Website2']//node[@nodeTypeAlias='News']/node[@nodeTypeAlias='NewsItem']
/>
The //'s in this xpath works the same way as descendant::node would.
It's a fairly long xpath, and I haven't tested it myself, but I'm pretty sure it will work.
I also noticed you mentioned id it's possible to "<span style="white-space: pre-wrap;">insert another xslt file in the middle of another xslt file?". Not sure exactly what you mean by that, and I don't know how well you know xslt. But if your main exposure to xslt has been through Umbraco xslt examples you will se a lot of <xsl:for-each /> statements, which generally leads to fairly convoluted xslt code.</span>In other parts of xslt-land the use of multiple xslt templates in one xslt file is much more common, and your statement above plus the idea of "wrapper" xslt made me think that this maybe was what you're looking for. Let's say you'd want all your news-items rendered in a particular way; then you could do it like this (not using xsl:for-each):</span>
<!-- Start of xsl file here -->
<xsl:param name="currentPage" />
<xsl:variable name="newsNodes" select="** See code above **" />
<xsl:template match="/">
<ul>
<xsl:apply-templates select="$newsNodes" />
</ul>
</xsl:template">
<xsl:template match="node">
<li>
<h2><a href="{umbraco.library:NiceUrl(@id)}"><xsl:value-of select="data[@alias='header']" /></a><h2>
<p><xsl:value-of select="data[@alias='resume']</p>
</li>
</xsl:template>
<!-- End of xsl file here -->
I think that the limited use of multiple xsl:template in Umbraco-land may have something to do with every node in the xml-file we're working on is a <node />, because in more normal xml the nodes will have different names eg. <News><NewsItem></NewsItem><NewsItem></NewsItem></News>, and you then have different templates that are used for nodes with different names, where everything is a <node /> in Umbraco. But actually xsl templates can be coerced into only reacting on a certain condition using the mode-attribute.
<xsl:apply-templates select="** Some select statement that selects nodes **" mode="newsItem" />
<xsl:template match="node" mode="newsItem">
</xsl:template>
After some thought about your advices, I think I'm going to try to make a wrapper that can take on a comma-separated list of node id's. It will then make a node-set with all the subnodes under the list of nodes.
After this, it will redirec t to a template with the node-set as a parameter, and this template will take care of iterating through the node-set.
I really don't see why you want to do it like this, you ask for a solution for a problem, the solutions provided are working and are general considered as good practice, you are trying to make from a simple problem a very complex one, why on earth would you like to redirect as you want to render a submenu?
I don't want to render a submenu. What I need is a reusable "wrapper" like the on posted by Jesper Hauge, that I can use in several xslt files. It would have been no problem hard-coding the thing, but I don't want a new xslt file for every new situation.
Reusable code is worth spending time to figure out, as it will save time later.
I could go for Paul Blair's solution, but if it is possible do this by supplying a comma-separated list if id's, then it will be a better solution for me.
The error is caused by the <xsl:value-of /> in the variable $SourceXML.
It seems that when you use <xsl:value-of /> in a <xsl:variable>, the data is saved as a string.
The solution was to use <xsl:copy-of /> and then make a new variable that encased $SourceXML in a msxsl:node-set.<xsl:variable name="SourceXML"> <xsl:for-each select="umbraco.library:Split($source, ',') /value"> <xsl:copy-of select="umbraco.library:GetXmlNodeById(current()/text())"/> </xsl:for-each> </xsl:variable>
Help with document type crawler
Does anyone know of a way to list nodes from multiple sources?
I have this content layout:
Content
|_ Website 1
|_ News
|_ News 1
|_ News 2
|_ Website 2
|_ News
|_ News 1
|_ News 2
Now, in the News template under Website 1, there is a news listing.
I need to list all News nodes in Website 1 and Website 2 here. And it must not list any news from other websites than those two.
If anyone know how to select all nodes with a @nodeTypeAlias that is the child of a master document type, it would also be very welcome.
I have a master document type called News, and the I have more specific types of News as sub-documenttypes. What I need is a xslt that finds all nodes based on a common master document type.
My current idea is to pass a comma separated list in the macro and then run a for-each for every @id there, but it is not a pretty solution.
Is it possible to insert another xslt file in the middle of another xslt file?
That way I might create some "wrapper" xslt files and do it recursively.
Does anyone know of a good solution to this?
You could create a property yes/no in the document type for a news document type (grouping news doctype vs individual news items) to indicate 'include on news feed' etc. Then in the macro, simple check for this doctypealias of the NEWS document where property = 1, then display all nodes under that?
-Chris
You can use a XSLT Macro like this:
<?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"
exclude-result-prefixes="msxml
umbraco.library">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:param name="currentPage"/>
<xsl:variable name="minLevel" select="1"/>
<xsl:template match="/">
<xsl:for-each select="$currentPage/ancestor-or-self::root//node [@id=1078 or @id=1159][@alias = 'Prj_Links']/descendant::node">
<xsl:value-of select="@nodeName"/><br/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet></span><span class="pln"><br /></span>
Sorry pasted wrong script, this is the correct one:
<?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"
exclude-result-prefixes="msxml
umbraco.library">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:param name="currentPage"/>
<xsl:variable name="minLevel" select="1"/>
<xsl:template match="/">
<xsl:for-each select="$currentPage/ancestor-or-self::root//node [@id=1078 or @id=1159]/descendant::node[@nodeTypeAlias= 'NewsItem']">
<xsl:value-of select="@nodeName"/><br/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Hi,
When i need to do this I add a SiteID property to my property types and then I can select records like this:
select="$currentPage/ancestor::root/node[ string(data [@alias='SiteID']) = 'FairlieAgile' and string(data [@alias='umbracoNaviHide']) != '1']"
Similar to the above solution but does not rely on hard-coding the id's so works better if you will be releasing to differernt environments.
I noticed this paragraph in your post:If anyone know how to select all nodes with a @nodeTypeAlias that is the child of a master document type, it would also be very welcome."</span>Let's say your News-nodes have nodeTypeAlias="News", and items below News nodes have nodeTypeAlias="NewsItem", then you should be able to select all NewsItem nodes into a variable with the following declaration, and let's say all your websites has a root node with nodeTypeAlias="Website"</span>You should then be able to "chain" your selection criteria together in a xpath statement like this:</span>
The //'s in this xpath works the same way as descendant::node would.
It's a fairly long xpath, and I haven't tested it myself, but I'm pretty sure it will work.
I also noticed you mentioned id it's possible to "<span style="white-space: pre-wrap;">insert another xslt file in the middle of another xslt file?". Not sure exactly what you mean by that, and I don't know how well you know xslt. But if your main exposure to xslt has been through Umbraco xslt examples you will se a lot of <xsl:for-each /> statements, which generally leads to fairly convoluted xslt code.</span>In other parts of xslt-land the use of multiple xslt templates in one xslt file is much more common, and your statement above plus the idea of "wrapper" xslt made me think that this maybe was what you're looking for. Let's say you'd want all your news-items rendered in a particular way; then you could do it like this (not using xsl:for-each):</span>
I think that the limited use of multiple xsl:template in Umbraco-land may have something to do with every node in the xml-file we're working on is a <node />, because in more normal xml the nodes will have different names eg. <News><NewsItem></NewsItem><NewsItem></NewsItem></News>, and you then have different templates that are used for nodes with different names, where everything is a <node /> in Umbraco. But actually xsl templates can be coerced into only reacting on a certain condition using the mode-attribute.
Regards
.Hauge
After some thought about your advices, I think I'm going to try to make a wrapper that can take on a comma-separated list of node id's.
It will then make a node-set with all the subnodes under the list of nodes.
After this, it will redirec t to a template with the node-set as a parameter, and this template will take care of iterating through the node-set.
Current code:
Now, testing on the web page with the following code inside the "/" template:
Both paragraphs return the expected result as you can see here.
The list however, returns nothing.
Does anyone have a clue why I don't get a list of nodenames using this code?
I really don't see why you want to do it like this, you ask for a solution for a problem, the solutions provided are working and are general considered as good practice, you are trying to make from a simple problem a very complex one, why on earth would you like to redirect as you want to render a submenu?
I don't want to render a submenu. What I need is a reusable "wrapper" like the on posted by Jesper Hauge, that I can use in several xslt files. It would have been no problem hard-coding the thing, but I don't want a new xslt file for every new situation.
Reusable code is worth spending time to figure out, as it will save time later.
I could go for Paul Blair's solution, but if it is possible do this by supplying a comma-separated list if id's, then it will be a better solution for me.
Sorry for the misunderstanding, is it maybe an idea to use the input from a multipage picker?
I did use that to create a related links? Still not sure or that's what you want, it's a little bit confusing for me ;)
Hmm. That looks almost exactly what I need!
Thank you! I'm gonna try this out right now and post back with the results.
It seems the my main problem is that when using a "value-of" in a variable, the variable becomes a string, not a node-set.
That is why I am not able to iterate through the $SourceXML and get the nodes from it.
Does anyone know how to fix this?
I have found the solution!
The error is caused by the <xsl:value-of /> in the variable $SourceXML.
It seems that when you use <xsl:value-of /> in a <xsl:variable>, the data is saved as a string.
The solution was to use <xsl:copy-of /> and then make a new variable that encased $SourceXML in a msxsl:node-set.<xsl:variable name="SourceXML">
<xsl:for-each select="umbraco.library:Split($source, ',') /value">
<xsl:copy-of select="umbraco.library:GetXmlNodeById(current()/text())"/>
</xsl:for-each>
</xsl:variable>
I have blogged about the problem here.
Now I have a collection of nodes that I can operate on. Thank you for the help everyone!
Hi Ove was wondering or you got this working...
is working on a reply...