umbraco macro XSLT not working - xslt

I get an image folder parameter (folder present in the media section) from macro in Umbraco and then loop through the all the images. First thing I check that folder is not empty and then during the loop I further try to check if an image name is equal to "marhall_spadayhpbanner_jul131%20(4).jpg" then I need to put a different link to anchor. I have tried the following xslt code but for some reason its not working as expected and the second condition (when image equal to 'media/42595/marhall_spadayhpbanner_jul131%20(4).jpg' ) is never true.
Any ideas thanks
<xsl:for-each select="$imageFolderContents/node [#nodeTypeAlias='Image']">
<xsl:if test="string(current()/data [#alias='umbracoFile']) != ''">
<a href="www.somelink.com">
<img alt="{current()/#nodeName}">
<xsl:attribute name="src"><xsl:value-of select="current()/data [#alias='umbracoFile']"/></xsl:attribute>
</img>
</a>
</xsl:if>
<xsl:if test="string(current()/data [#alias='umbracoFile']) = 'media/42595/marhall_spadayhpbanner_jul131%20(4).jpg'">
<a href="someotherlink.com">
<img alt="{current()/#nodeName}">
<xsl:attribute name="src"><xsl:value-of select="current()/data [#alias='umbracoFile']"/></xsl:attribute>
</img>
</a>
</xsl:if>
</xsl:for-each>
The output is the code is
<div style="clear: both; position: relative; height: auto;" class="slideshow innerfade"><img alt="dont be a fool" src="/media/42595/marhall_spadayhpbanner_jul131 (4).jpg"><img alt="dont be a fool" src="/media/42595/marhall_spadayhpbanner_jul131 (4).jpg"><img alt="MH-Ext-16-hero.jpg" src="/media/1548/MH-Ext-16-hero.jpg"><img alt="golf_hero_arial_new.jpg" src="/media/1816/golf_hero_arial_new.jpg"><img alt="MH-Spa-e-25-hero.jpg" src="/media/1552/MH-Spa-e-25-hero.jpg"></div>

Replace the %20 in your if statement to a space. That should fix it.

Related

XSL code cannot display image

I am using arcgis and I am trying to create an XSL template to configure my HTML PopUp to display attributes of a certain location. My problem is I cannot get the images to be displayed. I've tried using both codes below, but they don't work. The first one displays an empty frame while the second one displays <img src="E:\Pictures\Lakes\lake1.jpg">.
Can anyone help, please?
First version:
<xsl:when test="FieldName[starts-with(., 'Picture')]">
<img width="350" height="210">
<xsl:attribute name="src"><xsl:value-of select="FieldValue" disable-output-escaping="yes"/></xsl:attribute>
</img>
</xsl:when>
Second version:
<xsl:when test="FieldName[starts-with(., 'Picture')]">
<xsl:variable name="imageURL" select="FieldValue"/>
<p><img border="0" src="{$imageURL}" width="355" height="272"></img></p>
</xsl:when>

Search for a IF-ANY solution that works with <XSL:for-each>

I am searching for a solution for the following problem:
Currently i have this code:
<div class="box">
<div class="header">
<h2>Item</h2>
</div>
</div>
<xsl:for-each select="umbraco.library:GetXmlNodeById($source)/* [name() = $documentTypeAlias and string(umbracoNaviHide) != '0']">
<xsl:if test="string(experuserid)=$currentPage/experuserid">
<xsl:value-of select="#nodeName"/>
<xsl:value-of select="subtitel"/>
<a href="{umbraco.library:NiceUrl(#id)}" class="readmore">
Lees meer
</a>
</div>
</xsl:if>
</xsl:for-each>
This code produces a result for-each time my source(experuserid) equals my currentpage/experuserid.
The problem is when the test comes back negative and there are no experuserid's that match with the currentpage. I want to make it so that when this occures, my layout won't also show. Thus i need something like this:
<xsl:if-any test="string(experuserid)=$currentPage/experuserid">
<div class="box">
<div class="header">
<h2>Item</h2>
</div>
</div>
<xsl:for-each select="umbraco.library:GetXmlNodeById($source)/* [name() = $documentTypeAlias and string(umbracoNaviHide) != '0']">
<xsl:if test="string(experuserid)=$currentPage/experuserid">
<xsl:value-of select="#nodeName"/>
<xsl:value-of select="subtitel"/>
<a href="{umbraco.library:NiceUrl(#id)}" class="readmore">
Lees meer
</a>
</div>
</xsl:if>
</xsl:for-each>
<xsl:if-any>
Does this kind of solution exist? p.s. i am an XSLT-Rookie. I read something about using an if test with a * like so:
<xsl:if test="*string(experuserid)=$currentPage/experuserid">
But this does not work, any help?
you probably want to count the number of matches and only do it if there are some ... something like this ...
<xsl:if test="count( child::Page[experuserid = string(experuserid)] ) > 0">
<div ... blah ... />
</xsl:if>
not entirely sure what the "string(experuserid)" is doing (apart from obviously converting a textual number contained in the child node called experuserid of the current node into string, which it is already), you present it as working in your example so I'm re-using it ... but I have no context to determine it's validity.
I would do the filtering up front rather than using an <xsl:if> within the for-each, e.g.
<xsl:variable name="interestingNodes"
select="umbraco.library:GetXmlNodeById($source)/*
[name() = $documentTypeAlias and string(umbracoNaviHide) != '0']
[experuserid=$currentPage/experuserid]"/>
This will store in the variable only the nodes that you are actually interested in processing (i.e. those with the right experuserid), which may of course be none of them. Now you can simply say
<xsl:if test="$interestingNodes"><!-- true if $interestingNodes is non-empty -->
<div class="box">
...
</div>
<xsl:for-each select="$interestingNodes">
<xsl:value-of select="#nodeName"/>
...
</xsl:for-each>
</xsl:if>
P.S. note that the string() in your original test of string(experuserid)=$currentPage/experuserid is probably redundant. If the node has exactly one experuserid child element then it makes no difference to the behaviour. If the node has more than one experuserid then using string() will mean you check only the first experuserid child in document order, whereas without the string() it'll be true if any of them match.
Just use:
<xsl:for-each select=
"umbraco.library:GetXmlNodeById($source)/*
[name() = $documentTypeAlias and string(umbracoNaviHide) != '0']
[string(experuserid)=$currentPage/experuserid]
">
<!-- Your other code here -->
</xsl:for-each>

How do I output html markup stored in a xsl:variable

I am trying to render markup stored in a variable but I am getting no joy. Reason its cached is because I am using this several times in the page
<xsl:variable name="imgHtml">
<figure>
<img src="{$img}" alt="" class="" />
<figcaption>
<p><xsl:value-of select="name" /></p>
Enlarge Image
</figcaption>
</figure>
</xsl:variable>
I then reference the variable using the value-of elment
<xsl:value-of select="$imgHtml" /> but for some reason, the HTML does not render. Don't be shy, I need the help. Thanks!
Use <xsl:copy-of select="$imgHtml"/>, value-of always creates a plain text node.
The other answers were not working for me, however this did:
<xsl:value-of select="$variable" disable-output-escaping="yes"/>

Using a link in XSL Files

I am completely new to XML so hopefully my explanations will make sense..
I am using an XSL file with 2 sections of HTML text, reading from 2 templates set up within the file.
The first text and associated template is a table, and I have set up a link within that. I want the link to then point to a picture that is part of the 2nd HTML text/template.
The link in the table is setup in that it appears as a link, underlined, etc. However it doesnt go anywhere when clicked.
The second section works fine on it's own, eg, pictures and text appears.
But what I cant figure out is how to actually get the link to work. I've tried numerous things but nothing has worked so far. And I-m not sure whether I am very close and just perhaps need to alter a line of code. Or whether I need to be doing something very different. Also, there are no error messages, and everything displays well, it's just the link itself that doesnt work.
<xsl:template match="portion">
<tr>
<td valign="top"><xsl:value-of select="food-description"/></td>
<td valign="top"><xsl:value-of select="food-number"/></td>
<!--the following is the link text-->
<td valign="top"><a><xsl:attribute name="href">#<xsl:value-of select="portion- photo/#file"/></xsl:attribute>
<xsl:value-of select="portion-photo/#file"/></a><br/>
</td>
</tr>
</xsl:template>
<xsl:template match="portion-photo">
<!--I know that this is the code that is not correct, however, believe it should be something similar-->
<a><xsl:attribute name="portion-photo"><xsl:value-of select="./#file"/></xsl:attribute></a>
<p><xsl:value-of select="../food-description"/>
<xsl:value-of select="./#file"/></p>
<img>
<xsl:attribute name="src"><xsl:value-of select="./#file"/></xsl:attribute>
<xsl:attribute name="width"><xsl:value-of select="ceiling(./#w div v2)"/></xsl:attribute>
<xsl:attribute name="height"><xsl:value-of select="ceiling(./#h div 2)"/></xsl:attribute>
</img>
</xsl:template>
Something like the following should work. Just add the missing name attribute to the anchor element:
<xsl:template match="portion">
...
<a href="#{portion-photo/#file}">
<xsl:value-of select="portion-photo/#file"/>
</a>
...
</xsl:template>
<xsl:template match="portion-photo">
<a name="{#file}">
<xsl:value-of select="#file"/>
</a>
</xsl:template>
However, you have to ensure that #file evaluates to a valid anchor name. If the values of all file attributes are unique, you could also create save IDs with generate-id():
<xsl:template match="portion">
...
<a href="#{generate-id(portion-photo)}">
<xsl:value-of select="portion-photo/#file"/>
</a>
...
</xsl:template>
<xsl:template match="portion-photo">
<a name="{generate-id()}">
<xsl:value-of select="#file"/>
</a>
</xsl:template>

xsl transform: problem with Ampersand URL parameters

I'm having issues with transforming XSL with parameters in a URL. I'm at a point that I can't change the C# code anymore, only can make changes to xsl file.
C# code:
string xml = "<APPLDATA><APPID>1052391</APPID></APPLDATA>";
XmlDocument oXml = new XmlDocument();
oXml.LoadXml(xml);
XslTransform oXslTransform = new XslTransform();
oXslTransform.Load(#"C:\Projects\Win\ConsoleApps\XslTransformTest\S15033.xsl");
StringWriter oOutput = new StringWriter();
oXslTransform.Transform(oXml, null, oOutput)
XSL Code:
<body>
<xsl:variable name="app">
<xsl:value-of select="normalize-space(APPLDATA/APPID)" />
</xsl:variable>
<div id="homeImage" >
<xsl:attribute name="style">
background-image:url("https://server/image.gif?a=10&Id='<xsl:value-of disable-output-escaping="yes" select="$app" />'")
</xsl:attribute>
</div>
</body>
</html>
URL transformed:
https://server/image.gif?a=10&Id='1052391'
URL Expected:
https://server/image.gif?a=10&Id='1052391'
How do I fix this? The output (oOutput.ToString()) is being used in an email template so it's taking the URL transformed literally. When you click on this request (with the correct server name of course), the 403 (Access forbidden) error is being thrown.
The problem is not the ampersand but the single quotes around the id. If they have to be present they have to be url encoded.
So (assuming no quotes are needed around the id) this should work:
<body>
<xsl:variable name="app">
<xsl:value-of select="normalize-space(APPLDATA/APPID)" />
</xsl:variable>
<div id="homeImage" >
<xsl:attribute name="style">
<xsl:text disable-output-escaping="yes">background-image:url('https://server/image.gif?a=10&Id=</xsl:text>
<xsl:value-of disable-output-escaping="yes" select="$app" />
<xsl:text>')</xsl:text>
</xsl:attribute>
</div>
</body>
What you get is actually what you want. The ampersand must be escaped in HTML, no matter where it occurs. So this
<div
id="homeImage"
style="background-image:url("https://server/image.gif?a=10&Id='1052391'")"
></div>
acutally is valid HTML, while this
<div
id="homeImage"
style="background-image:url("https://server/image.gif?a=10&Id='1052391'")"
></div>
is not (check it in the validator). The error you receive must come from somewhere else.