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

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"/>

Related

xslt variable set based on condition

I would like to set an xsl variable based on a condition. The xsl below is not currently working for me. I've been able to make two different matchers (<xsl:template match="rule/condition" and <xsl:template match="condition/condition") which enables me to put the ;display:none on just condition/condition matches but that results in the template being duplicated except for the one part of ;display:none. Guess I'm under the impression that I should be able to dynamically set a variable based on a condition but maybe my impression is wrong?
<xsl:template match="condition">
<xsl:variable name="display">
<xsl:if test='name(..)=condition'>;display=none</xsl:if>
</xsl:variable>
<div style="{$divIndent}{$display}">
<a href="javascript:void(0)" style="{$expandPosition}" onclick="expandContents(this)">
<span class="glyphicon glyphicon-plus"></span>
</a>
<condition type="<xsl:value-of select="#type"/>"><br />
<xsl:apply-templates select="expression" />
<xsl:apply-templates select="condition" />
</condition>
</div>
</xsl:template>
<xsl:if test='name(..)=condition'>;display=none</xsl:if>
This asks if the name of the parent is equal to the value of the child whose name is condition. You probably want to know if the name of the parent is the literal value "condition":
<xsl:if test='name(..)="condition"'>;display=none</xsl:if>
However, it might be more idiomatic to write:
<xsl:if test='parent::condition'>;display=none</xsl:if>
Note also that display:none is valid css, display=none prbably won't work.
Try below code by adding attribute style
<div><xsl:attribute name ="style"><xsl:if test='name(..)=condition'>display=none;</xsl:if></xsl:attribute></div>

XSLT Parsing error when using Umbraco GetMedia

I am trying to retrieve the url to an image using the GetMedia mediapicker.
The code below works fine:
<xsl:for-each select="umbraco.library:GetXmlNodeById(1123)/* [#isDoc]">
<article>
<img width="1822" height="600">
<xsl:attribute name="src">
<xsl:value-of select="umbraco.library:GetMedia(1139, 0)/umbracoFile" />
</xsl:attribute>
</img>
<div class="contents">
<h1>
<xsl:value-of select="bannerHeading1"/>
</h1>
</div>
</article>
</xsl:for-each>
However, if I replace the key line with this:
<xsl:value-of select="umbraco.library:GetMedia(bannerImage, 0)/umbracoFile" />
I get a parsing error with the exception being an OverflowException (Value was either too large or too small for an Int32), which suggests that it's not the 1139 that is being passed in.
Is there a way I can pass in the property I want? The value of "bannerImage" is 1139 as I want it to be?
Thanks for any help.
Further: This is the XML structure being returned by GetXMLNodeById:
<?xml version="1.0" encoding="utf-8" ?>
<HomepageBanner id="1141" parentID="1123" level="3" writerID="0" creatorID="0" nodeType="1124" template="1125" sortOrder="0" createDate="2013-08-12T15:53:48" updateDate="2013-08-12T15:54:18" nodeName="Members" urlName="members" writerName="admin" creatorName="admin" path="-1,1065,1123,1141" isDoc="">
<bannerImage>1139</bannerImage>
<bannerHeading1>Members Area</bannerHeading1>
<bannerHeading2>..the place for all your needs</bannerHeading2>
</HomepageBanner>
For anyone else trying to get an image from an item in a content folder, this is how I got it to work:
<xsl:for-each select="umbraco.library:GetXmlNodeById(1123)/* [#isDoc]">
<article>
<!-- Store the ID -->
<xsl:variable name="mediaId" select="bannerImage" />
<!-- Check the ID is numeric -->
<xsl:if test="number($mediaId) > 0">
<xsl:variable name="mediaNode" select="umbraco.library:GetMedia($mediaId, false())" />
<xsl:if test="string-length($mediaNode/umbracoFile) > 0">
<img src="{$mediaNode/umbracoFile}" width="1822" height="600" />
<div class="contents">
<h1>
<xsl:value-of select="bannerHeading1"/>
</h1>
</div>
</xsl:if>
</xsl:if>
</article>
</xsl:for-each>
You first need to check that the value is numeric and then, the bit that was failing me, you need to add the "/umbracoFile" part to your media node variable.
Thanks to the contributors who helped me in the right direction.

umbraco macro XSLT not working

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.

XSL Output Text

<xsl:for-each select="$all_events[g:active = true()][g:body/g:current = true()]">
<xsl:for-each select="g:body">
<h2 class="normal"><xsl:value-of select="g:sub_title" /></h2>
<xsl:for-each select="g:paragraphs">
<xsl:text><xsl:value-of select="g:paragraph" /></xsl:text>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
Here is my XSL, take notice to the following line:
<xsl:text><xsl:value-of select="g:paragraph" /></xsl:text>
I tried this because the g:paragraph is coming from a WYSIWYG and it was printing out the <p> </p> tags and whatever else. This process of encapsulating it within xsl:text tags caused an error. What is the proper way to either hide the tags (because I want the styles to still be applied if included (i.e. bold, underlined)?
Edit:
The output currently is <p>whatever</p>
I want it to be whatever
Ah, I figured it out. I just had to use disable-output-escaping="yes"
You want to select the text content from a p element inside the g:paragraph element. You can do that this way:
<xsl:for-each select="g:paragraphs">
<xsl:value-of select="g:paragraph/p" />
</xsl:for-each>

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.