Display image from another node - xslt

I have a front page where i need to display a selected news item from the news section of the site, including an image.
I started off by trying to do a simple modification of the standard image, and promptly got nowhere.
I have verified that the images work when shown via currentpage directly on the node, but the following does not work:
<xsl:param name="currentPage"/>
<xsl:template match="/">
<xsl:variable name="mediaID" select="$currentPage/forsidenyhed/billede" />
<xsl:value-of select="$currentPage/forsidenyhed" />
<xsl:if test="string($mediaID) != ''">
<xsl:variable name="media" select="umbraco.library:GetMedia($currentPage/forsidenyhed/billede, false)" />
<xsl:if test="string($media) != ''">
<div class="forsidebillede">
<img src="{$media/umbracoFile}" alt="{$media/altText}" />
</div>
</xsl:if>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
The value-of outputs the correct node-id for the node containing the image i am looking for.
Edit: For anybody having problems with the same exact situation (umbraco cms) i recomend using a Razor macro instead of XSLT.

Following code provides the functionality i was looking for:
#inherits umbraco.MacroEngines.DynamicNodeContext
#using umbraco.MacroEngines
#{
dynamic settingsNode = Model.AncestorOrSelf();
dynamic searchPageNode = new DynamicNode(settingsNode.forsidenyhed);
dynamic mediaItem = new DynamicMedia(#searchPageNode.billede);
}
<img src="#mediaItem.umbracoFile">

Related

(Umbraco) How can I list related pages by tags?

In the last node of my site is where the articles are shown, and everyone has its own tags that of course can be the same between some of them, so I wrote a Macro for tags that is working (it lists the tags of the article the user is viewing), I've used the Tag datatype for my 'Article' doctype, and that Macro works correctly; but I got problems with the Macro I wrote to list those articles that have the same tags, I called it RelatedContent.xslt. Here is the code for AllTags.xslt that I found in Umbraco TV Tutorials that works:
<xsl:template match="/">
<div class="tags">
<xsl:variable name="Factor" select="6 div Exslt.ExsltMath:max(tags:getAllTagsInGroup('default')/tags/tag/#nodesTagged)"/>
<xsl:for-each select="tags:getAllTagsInGroup('default')/tags/tag">
<a class="tag{round($Factor * #nodesTagged)}x" href="?tag={.}">
<xsl:value-of select="."/>
</a><br/>
</xsl:for-each>
</div>
</xsl:template>
And the code for RelatedContent.xslt is this:
<xsl:template match="/">
<ul>
<xsl:for-each select="$currentPage/node [string(data [#alias='umbracoNaviHide']) != '1'] and (umbraco.library:Request('tag') = '' or contains(data [#alias = 'tags'], umbraco.library:Request('tag')))">
<li>
<a href="{umbraco.library:NiceUrl(#id)}">
<xsl:value-of select="#nodeName"/>
<xsl:value-of select="newsTitle"/>
</a>
</li>
</xsl:for-each>
</ul>
</xsl:template>
I have not found anything to help me understand this, so I cannot realize how to do it. I will appreciate some help from you. Thanks for your advices.
(Umbraco 6.1.3)
The code for the related content is using the old XML Schema.
Replace this bit:
<xsl:for-each select="$currentPage/node [string(data [#alias='umbracoNaviHide']) != '1']
and (umbraco.library:Request('tag') = '' or contains(data [#alias = 'tags'],
umbraco.library:Request('tag')))">
</xsl:for-each>
With
<xsl:variable name="tag" select="umbraco.library:Request('tag')"/>
<xsl:for-each select="$currentPage/*[#isDoc][umbracoNaviHide != 1][contains($tag,./tag)]">
</xsl:for-each>
The /node element does not exist in the 4.6+ schema, and the element name is replaced with the name of the documentTypeAlias.
So if you have a document type article with a property articleTitle it would be like this:
$currentPage/article/
$currentPage/article/articleTitle
Instead of the old schema (this is incorrect for anything above 4.5)
$currentPage/node[#nodeTypeAlias = 'article']
$currentPage/node[./data[#alias] = 'articleTitle']
You can see the difference between the 2 schemas at the Umbraco wiki:
http://our.umbraco.org/wiki/reference/xslt/45-xml-schema

How-to Test if Umbraco property is empty

I'm can't figure out how to test if a non-mandatory property is empty in my umbraco site, and currently my pages cause an XSLT parsing error if said property is empty. My current code is simple:
<xsl:variable name="media" select="umbraco.library:GetMedia(sectionImage, 0)" />
<xsl:if test="$media"> <!-- or $media != null -->
<xsl:variable name="url" select="$media/umbracoFile" />
<xsl:element name="img">
<xsl:attribute name="src"><xsl:value-of select="$url" />
</xsl:attribute>
</xsl:element>
</xsl:if>
I'm running Umbraco v6.0.6 and I've using the error checking solution as provided on the umbraco wiki, at http://our.umbraco.org/wiki/reference/umbracolibrary/getmedia
When I tried a similar style logic in C# I found that the test variable, $media, would have a value such as "umbraco.presentation.nodeFactory.Property." This filler content would wrongly bypass the if test, and then cause a break down.
This is happening on a variety of data types; media files, text strings, integers, etc.
Thank you for your time reading my post.
umbraco.library:GetMedia cannot return null, you may get an error back if no media was matched, in example
<error>No media is maching '123123'</error>
The thing is that your code works but you dont close the <xsl:attribute name="src"> as you should
<xsl:attribute name="src">
<xsl:value-of select="$url" />
</xsl:attribute>
If you for some reason really like to ensure that there is an image in there you should write a "test" and count values in the nodeTypeAlias
<xsl:variable name="media" select="umbraco.library:GetMedia(sectionImage, 0)" />
<xsl:if test="count($media[#nodeTypeAlias='Image']) > 0">
<xsl:variable name="url" select="$media/umbracoFile" />
<xsl:element name="img">
<xsl:attribute name="src">
<xsl:value-of select="$url" />
</xsl:attribute>
</xsl:element>
</xsl:if>
The xpath becomes a bit "odd" since you work with zero depth selection, if you fetch media with a greater depth you must adjust the count a bit
<xsl:variable name="media" select="umbraco.library:GetMedia(sectionImage, 0)" />
<xsl:if test="count($media/*[#nodeTypeAlias='Image']) > 0">
...
</xsl:if>
To test if a folder was selected simply check for folder instead
<xsl:variable name="media" select="umbraco.library:GetMedia(sectionImage, 0)" />
<xsl:if test="count($media[#nodeTypeAlias='Folder']) > 0">
...
</xsl:if>
Good luck
Okay so the initial IF condition has to do this:
<xsl:if test = "sectionImage != ''">
Which is how XSLT/Xpath checks if a XML tag is null. Then Eric Herlitz's solution can be used, or a dummy approach to just start assigning values without the secondary IF condition.

Umbraco library getMedia parent node property xslt

How can I get a property from the parent node of a media item using "umbraco.library:GetMedia"?
This allows me to get the current nodes "#nodeName"
<xsl:value-of select="umbraco.library:GetMedia(., 0)/#nodeName" />
I want to get the parent of the current nodes "#nodeName", I've tried the following but it doesn't work:
<xsl:value-of select="umbraco.library:GetMedia(., 0)/../#nodeName" />
Can anyone help me out?
Cheers, JV
With a call to GetMedia() and the #parentID attribute in a variable, I've got it working using the following:
<xsl:template match="/">
<!-- Do not call unless an image was picked -->
<xsl:apply-templates select="$currentPage/image[normalize-space()]" />
</xsl:template>
<xsl:template match="image">
<!-- Note: These WILL fail if no media is selected -->
<xsl:variable name="mediaNode" select="umbraco.library:GetMedia(., false())" />
<xsl:variable name="parentMedia" select="umbraco.library:GetMedia($mediaNode/#parentID, false())" />
<p>
Media: <xsl:value-of select="$mediaNode/#nodeName" />
</p>
<p>
Parent: <xsl:value-of select="$parentMedia/#nodeName" />
</p>
</xsl:template>

Select check box from check box list xsl umbraco

I have a check box list with two check boxes. I want to output a link when either of them are checked. Both check boxes can be checked at the same time, or just one checked, or none at all.
I have a a variable named value where I am getting the dataType 2084 which is the check box list.
How can I target an individual check box within the list when it is checked. There preValues are 99 and 101.
Anyone who can help I am very much thankful!
Here is my attempt below.
<xsl:param name="currentPage"/>
<xsl:param name="parentNode" select="/macro/parentNode"/>
<xsl:template match="/">
<xsl:for-each select="$currentPage/OperationsMap[#id=$parentNode]/MarkerItem">
<xsl:variable name="value" select="umbraco.library:GetPreValues('2084')"/>
<div class="popup-box">
<xsl:if test="$value/preValue[#alias='99'] = '1'">
<div class="colorbox-link-container">
View current gallery
</div>
</xsl:if>
<xsl:if test="$value/preValue[#alias='101'] = '1'">
<div class="colorbox-link-container">
View historical project progress
</div>
</xsl:if>
</div>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
GetPreValues returns a data set for the umbraco raw data type, not the status if they're checked or not on any particular content node.
Assumptions (as not specified in question):
Your data type is going to look something like the following:
<preValues>
<preValue id="99">Red</preValue>
<preValue id="100">Green</preValue>
<preValue id="101">Blue</preValue>
</preValues>
Not knowing the property alias you gave the checkbox list when adding the data type to the document type, I'm just going to use the following
MarkerItem/colours
Code:
This code was written on the fly, so haven't had time to test it.
<xsl:for-each select="$currentPage/OperationsMap[#id=$parentNode]/MarkerItem">
<div class="popup-box">
<!-- get the colours checked on MarkerItem -->
<xsl:variable name="colours" select="./colours"/>
<xsl:variable name="coloursValues" select="umbraco.library:Split($colours, ',')" />
<!-- cycle through each of the checked colours -->
<xsl:for-each select="$coloursValues/value">
<xsl:choose>
<xsl:when test=". = 'Red'">
<div class="colorbox-link-container">
View current gallery
</div>
</xsl:when>
<xsl:when test=". = 'Blue'">
<div class="colorbox-link-container">
View historical project progress
</div>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</div>
Hopefully, that does the trick for you. Obviously, update any reference to colours and their value to what is specific to you.

Hyperlinks within XSLT Templates

I am trying to create hyperlinks using XML information and XSLT templates. Here is the XML source.
<smartText>
Among individual stocks, the top percentage gainers in the S. and P. 500 are
<smartTextLink smartTextRic="http://investing.domain.com/research/stocks/snapshot
/snapshot.asp?ric=HBAN.O">Huntington Bancshares Inc</smartTextLink>
and
<smartTextLink smartTextRic="http://investing.domain.com/research/stocks/snapshot
/snapshot.asp?ric=EK">Eastman Kodak Co</smartTextLink>
.
</smartText>
I want the output to look like this, with the company names being hyperlinks based on the "smartTextLink" tags in the Xml.
Among individual stocks, the top percentage gainers in the S.&P. 500 are Eastman Kodak Co and Huntington Bancshares Inc.
Here are the templates that I am using right now. I can get the text to display, but not the hyperlinks.
<xsl:template match="smartText">
<p class="smartText">
<xsl:apply-templates select="child::node()" />
</p>
</xsl:template>
<xsl:template match="smartTextLink">
<a>
<xsl:apply-templates select="child::node()" />
<xsl:attribute name="href">
<xsl:value-of select="#smartTextRic"/>
</xsl:attribute>
</a>
</xsl:template>
I have tried multiple variations to try to get the hyperlinks to work correctly. I am thinking that the template match="smartTextLink" is not being instantiated for some reason. Does anyone have any ideas on how I can make this work?
EDIT: After reviewing some of the answers, it is still not working in my overall application.
I am calling the smartText template from within my main template
using the following statement...
<xsl:value-of select="marketSummaryModuleData/smartText"/>
Could this also be a part of the problem?
Thank you
Shane
Either move the xsl:attribute before any children, or use an attribute value template.
<xsl:template match="smartTextLink">
<a href="{#smartTextRic}">
<xsl:apply-templates/>
</a>
</xsl:template>
From the creating attributes section of the XSLT 1 spec:
The following are all errors:
Adding an attribute to an element after children have been added to it; implementations may either signal the error or ignore the attribute.
Try this - worked for me:
<xsl:template match="smartText">
<p class="smartText">
<xsl:apply-templates/>
</p>
</xsl:template>
<xsl:template match="smartTextLink">
<a>
<xsl:attribute name="href">
<xsl:value-of select="#smartTextRic"/>
</xsl:attribute>
<xsl:value-of select="text()"/>
</a>
</xsl:template>
Trick is - <xsl:attribute> first, before you do any other processing.
Marc