I'm creating a macro that sources a property from the current member. The property uses the "multiple textstrings" datatype, and each textstring contains a media ID, the version number and the date and time added.
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:param name="currentPage"/>
<xsl:template match="/">
<xsl:if test="count(umbraco.library:GetCurrentMember()/assetDownloads/values/value) > 0">
<ul>
<xsl:for-each select="umbraco.library:GetCurrentMember()/assetDownloads/values/value">
<li>
<xsl:if test="./preview != ''">
<img>
<xsl:attribute name="src">
<xsl:value-of select="./preview" />
</xsl:attribute>
</img>
</xsl:if>
<p><xsl:value-of select="current()"/></p>
</li>
</xsl:for-each>
</ul>
</xsl:if>
</xsl:template>
This results in the following:
1475,1,28-Dec-12 01:26:45
1475,1,28-Dec-12 01:27:03
The first values are the media types ID, the second value is its version number and the third value is the date and time it was downloaded.
This is how to display the first value as the preview image and the nodeName:
<!-- First value as preview image and nodeName -->
<xsl:if test="position() = 1">
<img>
<xsl:attribute name="src">
<xsl:value-of select="umbraco.library:GetMedia(., 0)/preview" />
</xsl:attribute>
</img>
<p><xsl:value-of select="umbraco.library:GetMedia(., 0)/#nodeName" /></p>
</xsl:if>
How can I seperate the string so I can display details from the media type? I'd like to display the preview image from media type and the nodeName of the media type.
Try using Umbraco split function separated via , (Comma) as following
<xsl:variable name="contentSplit" select="umbraco.library:Split(current(), ',')" />
Refactored code:
<xsl:if test="count(umbraco.library:GetCurrentMember()/assetDownloads/values/value) > 0">
<ul>
<xsl:for-each select="umbraco.library:GetCurrentMember()/assetDownloads/values/value">
<li>
<xsl:if test="./preview != ''">
<img>
<xsl:attribute name="src">
<xsl:value-of select="./preview" />
</xsl:attribute>
</img>
</xsl:if>
<p>
<!-- Split values via , comma using below function -->
<xsl:variable name="contentSplit" select="umbraco.library:Split(current(), ',')" />
<xsl:for-each select="$contentSplit/value">
<!-- First value as media type id -->
<xsl:if test="position() = 1">
Media Type Id: <xsl:value-of select="." />
</xsl:if>
<!-- Second value as version number -->
<xsl:if test="position() = 2">
Version: <xsl:value-of select="." />
</xsl:if>
<!-- Third value as date and time of download -->
<xsl:if test="position() = 3">
Date Time: <xsl:value-of select="." />
</xsl:if>
</xsl:for-each>
</p>
</li>
</xsl:for-each>
</ul>
</xsl:if>
Let me know if you need more explanation, Thanks
Related
Is there a way to determine if a a root level node contains any child nodes?
I have this code file that builds up a navigation menu for a drop-down menu, but for the root nodes that have no nodes below them I want to apply a different template to them:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="/Home">
<xsl:apply-templates select="root" />
</xsl:template>
<xsl:template match="root">
<ul class="nav navbar-nav">
<xsl:apply-templates select="node">
<xsl:with-param name="level" select="0"/>
</xsl:apply-templates>
</ul>
</xsl:template>
<xsl:template match="node">
<xsl:param name="level" />
<xsl:choose>
<xsl:when test="$level=0">
<li>
<xsl:attribute name="class">
<xsl:if test="#breadcrumb = 1">active</xsl:if>
<xsl:if test="node">
<xsl:text> dropdown</xsl:text>
</xsl:if>
</xsl:attribute>
<xsl:choose>
<xsl:when test="#enabled = 1">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<xsl:attribute name="class">
<xsl:if test="node">
<xsl:text>dropdown-toggle</xsl:text>
</xsl:if>
</xsl:attribute>
<xsl:if test="node">
<xsl:attribute name="data-toggle">dropdown</xsl:attribute>
</xsl:if>
<xsl:value-of select="#text" />
<xsl:if test="node">
<b class="caret"></b>
</xsl:if>
</a>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="#text" />
</xsl:otherwise>
</xsl:choose>
<xsl:if test="node">
<ul class="dropdown-menu">
<xsl:apply-templates select="node">
<xsl:with-param name="level" select="$level + 1" />
</xsl:apply-templates>
</ul>
</xsl:if>
</li>
</xsl:when>
<xsl:otherwise>
<li>
<xsl:attribute name="class">
<xsl:if test="#breadcrumb = 1">active</xsl:if>
<xsl:if test="node">
<xsl:text> dropdown</xsl:text>
</xsl:if>
</xsl:attribute>
<xsl:choose>
<xsl:when test="#enabled = 1">
<a href="{#url}">
<xsl:value-of select="#text" />
</a>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="#text" />
</xsl:otherwise>
</xsl:choose>
</li>
<xsl:if test="node">
<!-- no extra level in default bootstrap -->
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Your question is not clear. If the root node does not have any child nodes, then the XML document is empty. Perhaps you meant the root element; there will be exactly one element like that and it's easy to see if it has any child nodes by using:
test="/*/node()"
in an xsl:if or xsl:when instruction.
Alternatively, you could use two templates - one matching a root element with child nodes:
<xsl:template match="/*[node()]">
and one for the other case:
<xsl:template match="/*[not(node())]">
You can use this XSLT-file:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" />
<xsl:template match="/*[count(descendant::*) = 0]">
No siblings
</xsl:template>
<xsl:template match="/*[count(descendant::*) > 0]">
Has siblings
</xsl:template>
</xsl:stylesheet>
With an input XML file with one or more siblings of the root element like this
<?xml version="1.0"?>
<root>
<a />
</root>
it will output "Has siblings".
And with an input file with an empty root tag like this
<?xml version="1.0"?>
<root>
</root>
it will output "No siblings".
If I understand the question correctly, try adding the template rule
<xsl:template match="root[not(*)]"/>
pls check the below code. I am matching the list element and as per the below code the position() function returns correct number of the element with in ul elements i.e 1,2,3 where as if i do the test with position i get only ss,ss,ss . Can anyone let me know where am missing ?
XSL-FO
<xsl:template match="html:li" priority="2">
<fo:list-item>
...
<xsl:value-of select="position()"/> -- this returns 1,2,3
<xsl:if test="position() = 1">
<xsl:text>ss</xsl:text> -- only executes
</xsl:if>
<xsl:if test="position() = 2">
<xsl:text>ssddddd</xsl:text> -- does not only execute
</xsl:if>
<xsl:if test="position() = 3">
<xsl:text>sskkkkkkkkk</xsl:text> -- does not only execute
</xsl:if>
</fo:list-item>
</xsl:template
XSL
<xsl:template match="list">
<xsl:if test="list.item">
<xsl:variable name="styleAttr">
<xsl:text>margin-top: 1em;</xsl:text>
</xsl:variable>
<div>
<xsl:if test="string-length($styleAttr) > 0">
<xsl:attribute name="style">
<xsl:value-of select="$styleAttr"/>
</xsl:attribute>
</xsl:if>
<ul>
<xsl:apply-templates select="node()[not(self::list)]" />
</ul>
</div>
</xsl:if>
</xsl:template>
<xsl:template match="list.item" priority="1">
<li style="padding: 0;">
<div style="margin-bottom: 0.5em;">
<xsl:apply-templates />
<xsl:if test="following-sibling::node()[1][self::list]">
<xsl:apply-templates select="following-sibling::node()[1]" />
</xsl:if>
</div>
</li>
</xsl:template>
I'm trying to get the value of a text string of page, assign a url to it, and then display the result on a different page using xslt. I'm not sure how to get the value of the textstring.
Here is my macro:
<!-- Input the related links property alias here -->
<xsl:variable name="fieldName" select="/macro/fieldName"/>
<xsl:template match="/">
<xsl:if test="$fieldName != ''">
<!-- The fun starts here -->
<xsl:element name="a">
<xsl:if test="./new-window[. = 'True']">
<xsl:attribute name="target">_blank</xsl:attribute>
</xsl:if>
<xsl:attribute name="href">
<xsl:value-of select="/myUrl.aspx"/>
</xsl:attribute>
<xsl:value-of select="./#title"/>
</xsl:element>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Found it! select="$parent/*[name() = $fieldName]
I have an xsl template that I want to call to put into an HTML node attribute:
<xsl:variable name="onClickJavaScript">
<xsl:call-template name="GetOnClickJavaScript" />
</xsl:variable>
<a id="123">
<xsl:attribute name="onclick">
<xsl:value-of select="$onClickJavaScript" />
</xsl:attribute>
</a>
My problem is that the call-template returns a node set and the attribute value wants to be a string. I can't seem to find any way to transform the node set into a string that works.
I have tried changing the value-of line to:
<xsl:value-of select="$onClickJavaScript/text()" />
But it complains that it needs to return a node set and that does not (which is what I was hoping, without the complaining part).
In the Visual Studio debugger I can see that $onClickJavaScript is a NodeSet with a single dimension and item. My string is buried in there, but not accessible :-(.
UPDATE...
When I call my template, it goes through a big case statement and calls another template. This other template has a <xsl:choose> and it goes down the following path in this case:
<xsl:when test="$isPrimary='true'">
<!-- Just provide the onclick event JavaScript -->
<xsl:value-of select='concat($launchMethod, "(this, '", $id, "', '", $nodeid, "', '", $instanceid, "')")' />
</xsl:when>
With the information provided, your first sample should work, i.e.
<xsl:attribute name="onclick">
<xsl:value-of select="$onClickJavaScript" />
</xsl:attribute>
should insert an onclick attribute with the (string) value of $onClickJavaScript.
You can even simplify your XSLT by using an attribute value template:
<a id="123" onclick="{$onClickJavaScript}">...</a>
Or get rid of the variable and call the template inside the attribute node:
<xsl:attribute name="onclick">
<xsl:call-template name="GetOnClickJavaScript" />
</xsl:attribute>
My problem is that the call-template
returns a node set and the attribute
value wants to be a string. I can't
seem to find any way to transform the
node set into a string that works.
The problem is in the code you haven't shown.
In fact, I cannot reproduce this problem at all.
This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="onClickJavaScript">
<xsl:call-template name="GetOnClickJavaScript" />
</xsl:variable>
<xsl:variable name="onClickJavaScript2">
<xsl:call-template name="GetOnClickJavaScript2" />
</xsl:variable>
<a id="123">
<xsl:attribute name="onclick">
<xsl:value-of select="$onClickJavaScript" />
</xsl:attribute>
</a>
<a id="123456">
<xsl:attribute name="onclick">
<xsl:value-of select="$onClickJavaScript" />
</xsl:attribute>
</a>
</xsl:template>
<xsl:template name="GetOnClickJavaScript">Hello</xsl:template>
<xsl:template name="GetOnClickJavaScript2">
<a>Hello</a>
</xsl:template>
</xsl:stylesheet>
when applied on any XML document (not used) produces its output without any errors:
<a id="123" onclick="Hello"/>
<a id="123456" onclick="Hello"/>
I'm not able to reproduce this either... here's what I tried, the onclick on the a gets "foo(this, '3', 'test')". What else is different? What is the result-tree-fragment that you're trying to call xsl:value-of on?
<xsl:template match="/">
<xsl:variable name="onclick-val">
<xsl:call-template name="foo" />
</xsl:variable>
<a>
<xsl:attribute name="onclick">
<xsl:value-of select="$onclick-val" />
</xsl:attribute>
</a>
</xsl:template>
<xsl:template name="foo">
<xsl:choose>
<xsl:when test="false()">
false
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="callme" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="callme">
<xsl:choose>
<xsl:when test="true()">
<xsl:value-of select='concat("foo", "(this, '", "3", "', '", "test", "')")' />
</xsl:when>
<xsl:otherwise>
false
</xsl:otherwise>
</xsl:choose>
</xsl:template>
I have the following XSLT:
<xsl:template match="/">
<div id="dokumentliste">
<xsl:variable name="alleNyheder" select="$currentPage//node" />
<xsl:for-each select="$alleNyheder">
<xsl:sort data-type="text" select="#createDate" order="descending" />
<xsl:if test="./data[#alias='manchet'] != ''">
<div class="newsitem">
<h2>
<xsl:value-of select="./data[#alias='title']"/>
</h2>
<xsl:if test="./data[#alias = 'manchet'] != ''">
<div class="nyhedContent">
<p>
<span class="dokumentListeDato">
<xsl:choose>
<xsl:when test="./data[#alias='date'] != ''">
<xsl:value-of select="umbraco.library:FormatDateTime(./data[#alias='date'], 'dd. MMMM yyyy')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="umbraco.library:FormatDateTime(./#createDate, 'dd. MMMM yyyy')"/>
</xsl:otherwise>
</xsl:choose>
</span>
<xsl:value-of select="./data[#alias = 'manchet']"/>
</p>
</div>
</xsl:if>
<div class="dokumentListe_laes_mere">
<a href="{umbraco.library:NiceUrl(#id)}">
Læs mere<img src="/frontend/images/macro/macro_laes_mere.png" alt="Læs mere"/>
</a>
</div>
</div>
<!-- End newsitem -->
</xsl:if>
</xsl:for-each>
</div>
</xsl:template>
I am making a newslist, and would like to make some sort of pagination. Almost the same one as seen on Google. You know "the usual one".
But I can't figure out how to do this.
The number of newsitems on each page isn't that important, but lets say 10 on each page. When the 10 first newsitems are shown, I would like the pagination to show up. With the "Next" and "Previous" buttons to the right and the left of the numbers.
Is it possible to make this, and have I explained my problem good enough? I use the Umbraco CMS by the way :)
Thank you very much.
-Kim
Something like this:
I've left some code in there for dealing with images in your listing too :-)
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:param name="currentPage"/>
<xsl:template match="/">
<xsl:variable name="recordsPerPage" select="2"/>
<xsl:variable name="pageNumber">
<xsl:choose>
<!-- first page -->
<xsl:when test="umbraco.library:RequestQueryString('page') <= 0 or string(umbraco.library:RequestQueryString('page')) = '' or string(umbraco.library:RequestQueryString('page')) = 'NaN'">0</xsl:when>
<!-- what was passed in -->
<xsl:otherwise>
<xsl:value-of select="umbraco.library:RequestQueryString('page')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="numberOfRecords" select="count($currentPage/node)"/>
<!-- The fun starts here -->
<xsl:call-template name="pagination">
<xsl:with-param name="pageNumber" select="$pageNumber"/>
<xsl:with-param name="recordsPerPage" select="$recordsPerPage" />
<xsl:with-param name="numberOfRecords" select="$numberOfRecords" />
</xsl:call-template>
<ul class="listing self-clear">
<xsl:for-each select="$currentPage/node [string(data [#alias='umbracoNaviHide']) != '1']">
<xsl:sort order="descending" select="data[#alias='releasedOn']"></xsl:sort>
<xsl:if test="position() > $recordsPerPage * number($pageNumber) and position() <= number($recordsPerPage * number($pageNumber) + $recordsPerPage )">
<li>
<xsl:attribute name="class">
<xsl:if test="data[#alias='image'] = ''">
no-img
</xsl:if>
<xsl:if test="position() = $recordsPerPage * (number($pageNumber) + 1)">
last
</xsl:if>
</xsl:attribute>
<h3>
<a href="{umbraco.library:NiceUrl(#id)}">
<xsl:value-of select="#nodeName"/>
</a>
</h3>
<xsl:if test="data[#alias='image'] != ''">
<img src="{data[#alias='image']}" class="drop-shadow" />
</xsl:if>
<p class="date"><xsl:value-of select="umbraco.library:LongDate(data[#alias='releasedOn'])"/></p>
<xsl:value-of select="data[#alias='abstract']" disable-output-escaping="yes"/>
Read More
</li>
</xsl:if>
</xsl:for-each>
</ul>
<xsl:call-template name="pagination">
<xsl:with-param name="pageNumber" select="$pageNumber"/>
<xsl:with-param name="recordsPerPage" select="$recordsPerPage" />
<xsl:with-param name="numberOfRecords" select="$numberOfRecords" />
</xsl:call-template>
</xsl:template>
<xsl:template name="pagination">
<xsl:param name="pageNumber"/>
<xsl:param name="recordsPerPage"/>
<xsl:param name="numberOfRecords"/>
<div class="pagination">
<div class="wrapper">
<xsl:if test="(($pageNumber +1 ) * $recordsPerPage) < ($numberOfRecords)">
Next
</xsl:if>
<xsl:if test="$pageNumber > 0">
Prev
</xsl:if>
<span class="page-nos">
Page
<xsl:call-template name="for.loop">
<xsl:with-param name="i">1</xsl:with-param>
<xsl:with-param name="page" select="$pageNumber +1"></xsl:with-param>
<xsl:with-param name="count" select="ceiling(count($currentPage/node)div $recordsPerPage)"></xsl:with-param>
</xsl:call-template>
</span>
</div>
</div>
</xsl:template>
<xsl:template name="for.loop">
<xsl:param name="i"/>
<xsl:param name="count"/>
<xsl:param name="page"/>
<xsl:if test="$i <= $count">
<span>
<xsl:if test="$page != $i">
<a href="{umbraco.library:NiceUrl($currentPage/#id)}?page={$i - 1}" >
<xsl:value-of select="$i" />
</a>
</xsl:if>
<xsl:if test="$page = $i">
<xsl:value-of select="$i" />
</xsl:if>
</span>
</xsl:if>
<xsl:if test="$i <= $count">
<xsl:call-template name="for.loop">
<xsl:with-param name="i">
<xsl:value-of select="$i + 1"/>
</xsl:with-param>
<xsl:with-param name="count">
<xsl:value-of select="$count"/>
</xsl:with-param>
<xsl:with-param name="page">
<xsl:value-of select="$page"/>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
I figured this one out now. I can see that you have just copy/pasted the pagination that where made by Tim Geyssens here: http://www.nibble.be/?p=11
And the code is also kind'a good, but I changed some of it to get it working. I don't know if I should just accept my own answer as the right one, the answer from Myster as the right one or if I can delete this post?