projectDetail is my current page. the externalLinks node is created by the repeatable custom content datatype. (note that the package generates old schema xml).
i worked before with this datatype without any problem, but from some reason i'm not succeded to loop on this.
i tried this and few other options without success. where i am wrong?
First of all, I don't think Repeatable Custom Content is compatible with Umbraco 4.5. Not sure to what extent, but since you've got the XML there I guess it should work.
What is happening, an error on saving or its just not outputting anything?
What is $externalLink? Have you checked whether there's anything in that variable/parameter using e.g. <xsl:copy-of/> ? It's the only point of failure I can see.
<items> <item> <dataalias="ExtLinkTxt"><![CDATA[link to site]]></data> <dataalias="ExtLinkUrl"><![CDATA[http://www.natalkids.org.uk/]]></data> <dataalias="ExtLinkToolTip"><![CDATA[this is tooltip]]></data> </item> </items>
like i said, the above loop is working when i excute it in the main template (match=/) but i want to send it to different template (in the same macro). i can't understand why its not working. i tried few options with zero results.
In what scope is the $externalLink variable? Is it in the global stylesheet itself, or do you create it in the <template match="/"> ?
Variables created within templates are only available (scoped) within that template. If you don't want to or can't have the $externalLink in the global scope of the stylesheet, you could use a template with a parameter and call the template with $externalLink as input parameter.
my question is exactly about that - how to send this variable to template. i did it before a lot of times. but from some reason i dont succeeded to do that now. i attached here the whole macro code so you can understand the while picture:
If not, to help debug, write out the following in your template so you can see the XML that's getting passed and that should help figure out what needs to be changed:
First: why do you use copy-of instead of value-of? When you use value-of, you won't need to use msxml:node-set(). Don't double the trouble.
Second: in your current copy-of, you're selecting externalLink instead of externalLinks. Seem like a typo.
Third: in your showExternalLinks template, your externalLink doesn't contain "/items/item" nodes when you've called it by passing in "/externalLink/items". It will contain only "/item" nodes.
You might want to consider using a named template that matches "externalLinks", since in the new schema it actually has that name. Then it would become something like
tom and thijs: i combine your answers with few modifications, and now i have a working solution: in the regular method (me and tom method), i call the template like this:
this is working perfectlly and my problem is solved - thanks!
just for interest and learning - thijs: your method is working, but with one problem: its not looping on all the items. i wonder how can i solve this: i call the template like:
You will still need to loop over the "/items/item" nodes at some point. It is just a matter of taste at which point you choose to do it, I like keeping my root template clean, so I can break up the XSLT in smaller "problems".
If you mean more efficient CPU or memory-wise, I wouldn't know. Never tested it.
However, I find it to be more efficient in writing. This time, you know what you're selecting on beforehand (namely "externalLinks/items/item"). So you know the name and type of each node. However, you might encounter a situation where you select a more general set of nodes. Using "apply-templates" combined with "template match='nodeSelector'" you're able to write concise and general XSLT at the same time. I allows you to implicitly include and exclude certain node types from the selected set.
E.g. I've just implemented Examine (search engine provider) on a 4.5 site. The resulting nodeset for a query could point to any node type included in the Examine index. Using a combination of matching and named templates, I was able to list those results in HTML, with a minimum amount of effort. That's efficient.
thanks for your time and efforts. i marketd your answer as the solution, as you supply working solution to my problem. thanks for all the other that tried to help.
p.s - thikjs, it will be interesting how you implements the examine search. i think that we need more real world examples/posts for examine + umbraco. i wrote about my experience in my blog.
<xsl:variable name="rootNode" select="$currentPage/ancestor::root"/>
<xsl:variable name="searchQuery" select="umbraco.library:RequestQueryString('s')"/>
<xsl template match="/">
<!-- This is the actual search query in Examine.
First argument is (string)searchText,
second is (bool)useWildCards,
third is (string)providerName
Multiple overloads of the same method exist, so look at the documentation. -->
<xsl:variable name="searchResults" select="Examine:Search($searchQuery, true(), 'SiteSearchSearcher')"/>
<xsl:apply-templates select="$searchResults/nodes/node">
<xsl:sort select="@score" data-type="number" order="descending" />
</xsl:apply-templates>
</xsl:template>
<!-- Template used to match nodes that have an @score attribute,
and thus come from Examine results -->
<xsl:template match="node[@score]">
<!-- Get the actual node by id -->
<xsl:variable name="currentNode" select="$rootNode/descendant::*[@id = current()/@id]"/>
<!-- Call named template for the actual node, wrapped in for-each just in case
a node appears twice for an id -->
<xsl:for-each select="$currentNode">
<xsl:call-template name="Post"/>
</xsl:for-each>
</xsl:template>
<xsl:template name="Post">
<!-- Create some (X)HTML markup from the current node -->
</xsl:template>
In this case, I'm using a named template (because all searchable pages inherit from the same Document Type), but had it been the case that nodes from multiple document types could be in the search result nodeset, I would have created multiple matching templates.
I don't know whether there's a lot of documentation yet, but take a look at this file at Codeplex, it's the source of the Examine XSLT extensions with comments.
loop on repeatable custom content - simple question
hi. i have this xmldump from my web site:
(the site is 4.5 schema)
projectDetail is my current page.
the externalLinks node is created by the repeatable custom content datatype.
(note that the package generates old schema xml).
i worked before with this datatype without any problem, but from some reason i'm not succeded to loop on this.
i tried this and few other options without success. where i am wrong?
Hi,
First of all, I don't think Repeatable Custom Content is compatible with Umbraco 4.5. Not sure to what extent, but since you've got the XML there I guess it should work.
What is happening, an error on saving or its just not outputting anything?
How are you setting the $externalLink variable?
ok, so now when i'm not using template, the loop is working, like this:
but i dont get it working with template. (how i send it to template? do i need to use msxml:node-set in the template?
Thanks,
Eran.
What is $externalLink? Have you checked whether there's anything in that variable/parameter using e.g. <xsl:copy-of/> ? It's the only point of failure I can see.
hi,
the $externalLink contains this xml:
like i said, the above loop is working when i excute it in the main template (match=/) but i want to send it to different template (in the same macro).
i can't understand why its not working. i tried few options with zero results.
thanks,
Eran.
In what scope is the $externalLink variable? Is it in the global stylesheet itself, or do you create it in the <template match="/"> ?
Variables created within templates are only available (scoped) within that template. If you don't want to or can't have the $externalLink in the global scope of the stylesheet, you could use a template with a parameter and call the template with $externalLink as input parameter.
From my TextMate snippets, template definition:
Call template with parameter:
my question is exactly about that - how to send this variable to template.
i did it before a lot of times. but from some reason i dont succeeded to do that now.
i attached here the whole macro code so you can understand the while picture:
Hi Eran,
This should work, but I see a possible typo in the <!-- not Working --> section
$currentPage/externalLink should be $currentPage/externalLinks (plural), I believe
Also, I think you should leave off /items and just pass it like so:
Then in your for-each loop inside the showExternalLinks template, I think you should change to:
If not, to help debug, write out the following in your template so you can see the XML that's getting passed and that should help figure out what needs to be changed:
Well:
First: why do you use copy-of instead of value-of? When you use value-of, you won't need to use msxml:node-set(). Don't double the trouble.
Second: in your current copy-of, you're selecting externalLink instead of externalLinks. Seem like a typo.
Third: in your showExternalLinks template, your externalLink doesn't contain "/items/item" nodes when you've called it by passing in "/externalLink/items". It will contain only "/item" nodes.
You might want to consider using a named template that matches "externalLinks", since in the new schema it actually has that name. Then it would become something like
Combined with a template
that does the plumbing (like looping over the items).
tom and thijs: i combine your answers with few modifications, and now i have a working solution:
in the regular method (me and tom method), i call the template like this:
and the template looks like:
this is working perfectlly and my problem is solved - thanks!
just for interest and learning - thijs: your method is working, but with one problem: its not looping on all the items.
i wonder how can i solve this:
i call the template like:
<xsl:apply-templates select="$currentPage/externalLinks"/>
and the template looks like:
like i said, the problem is that its only display one item, and not all of them.
Let me be nice and post the full code of what I meant ;)
You will still need to loop over the "/items/item" nodes at some point. It is just a matter of taste at which point you choose to do it, I like keeping my root template clean, so I can break up the XSLT in smaller "problems".
One other (even cleaner) solution would be:
Yeah, looking back at it the latter might be the best solution.
oright - i tried to do like in your second method - without the for-each loop.
by the way, is the method with template match is more efficient than the "regular" one?
Thanks.
If you mean more efficient CPU or memory-wise, I wouldn't know. Never tested it.
However, I find it to be more efficient in writing. This time, you know what you're selecting on beforehand (namely "externalLinks/items/item"). So you know the name and type of each node. However, you might encounter a situation where you select a more general set of nodes. Using "apply-templates" combined with "template match='nodeSelector'" you're able to write concise and general XSLT at the same time. I allows you to implicitly include and exclude certain node types from the selected set.
E.g. I've just implemented Examine (search engine provider) on a 4.5 site. The resulting nodeset for a query could point to any node type included in the Examine index. Using a combination of matching and named templates, I was able to list those results in HTML, with a minimum amount of effort. That's efficient.
thanks for your time and efforts. i marketd your answer as the solution, as you supply working solution to my problem.
thanks for all the other that tried to help.
p.s - thikjs, it will be interesting how you implements the examine search. i think that we need more real world examples/posts for examine + umbraco.
i wrote about my experience in my blog.
regards,
Eran.
Regarding Examine: I'm using the XSLT Extensions in Examine 1.0
So in config/xsltExtensions.config you'll need to register the Examine XSLT extensions:
Next I created an XSLT macro with bits like:
In this case, I'm using a named template (because all searchable pages inherit from the same Document Type), but had it been the case that nodes from multiple document types could be in the search result nodeset, I would have created multiple matching templates.
very interesting, thank for sharing. i will search for the ducumantation for the xslt and examine.
thanks!
I don't know whether there's a lot of documentation yet, but take a look at this file at Codeplex, it's the source of the Examine XSLT extensions with comments.
http://examine.codeplex.com/SourceControl/changeset/view/57954#1074649
that will save me time, thanks!
Eran
is working on a reply...