Another approach would be to use the tokenize() extension to actually perform a split and get a set of results back, but that returns some weird values at times... ideally you can do:
Thank you very much for your replies. But i'm again back to my first problem.
I need to take this array out of the loop and then highlight the months with news.
if i define the array inside the loop, outside the loop it does not work. and if i define it at the top of my xslt file, the default value does not changes.
I have tried it with a flag for each months before, and now array but it does not work. my code is like this:
but the problem is as soon as i am out of the loop, the Array is not recognised. and if i put this in the loop, then i'll have multiple 12 months (depends how many months have got news)
Okay - Since you want all the months, regardless of them having events, you should be making that the main focus and have the outermost "loop" generate the months. Then simply select the DateFolder that matches the month you're currently displaying, and if you get any back, create a link - otherwise print its name... :
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
umbraco.library="urn:umbraco.library"
exclude-result-prefixes="msxsl umbraco.library"
>
<xsl:output method="html" indent="yes" omit-xml-declaration="yes" />
<xsl:param name="currentPage" select="/root/Website/YearFolder" />
<!-- Build an XML lookup variable -->
<xsl:variable name="monthsProxy">
<month id="01">January</month>
<month id="02">February</month>
<month id="03">March</month>
<month id="04">April</month>
<month id="05">May</month>
<month id="06">June</month>
<month id="07">July</month>
<month id="08">August</month>
<month id="09">September</month>
<month id="10">October</month>
<month id="11">November</month>
<month id="12">December</month>
<!-- etc. -->
</xsl:variable>
<xsl:variable name="months" select="msxsl:node-set($monthsProxy)" />
<xsl:template match="/">
<!-- Go through all the months and check for events -->
<xsl:for-each select="$months/month">
<xsl:variable name="monthFolder" select="$currentPage/DateFolder[@nodeName = current()/@id]" />
<ul>
<li>
<!-- Create a link to the month folder... -->
<xsl:apply-templates select="$monthFolder" mode="link" />
<!-- ... or write its name if no events were found -->
<xsl:value-of select="self::month[not($monthFolder)]" />
</li>
</ul>
</xsl:for-each>
</xsl:template>
<!-- Template for linking the monthname -->
<xsl:template match="DateFolder" mode="link">
<a href="{umbraco.library:NiceUrl(@id)}">
<xsl:apply-templates select="." mode="monthname" />
</a>
</xsl:template>
<!-- Template to write the monthname -->
<xsl:template match="DateFolder" mode="monthname">
<xsl:value-of select="$months/month[@id = current()/@nodeName]" />
</xsl:template>
</xsl:stylesheet>
Note: If your DateFolders have single digit names (e.g., "3" instead of "03") just change them in the XML variable.
Hope I've explained it sufficiently - otherwise, let me know :-)
It works by the magic of nodesets :-) Whenever you make a selection in XSLT/XPath you're actually getting a nodeset (unless you specifically select a string, a number or a boolean value). Even if a nodeset is empty, it's still a nodeset that you can query.
So when we select all DateFolder nodes below $currentPage where the @nodeName is the current value in the loop:
This will take every node in the set and find a matching template in the "link" mode, and execute that template with the node as the context. Now, if the set was empty, no templates will have been executed - we didn't even need to do any counting or checking of any kind; neat, right?
...translates into "Write the value of the current node (of the for-each loop) if it's a <month> element and the $monthFolder was empty".
The not() function expects a boolean value, so when we send in a nodeset, the processor will run the variable through the boolean() function first - and that will return false() for an empty nodeset and true() for a nodeset with one or more nodes. So if the $monthsFolder is an empty nodeset, the not() function will return true()...
Oh my god - Thank you so much - i have to play with it a little to undretand it better.
Thanks a lot for your reply. Do you know with this method if i can set the hyperlinks on for the months, even after clicking to the month. What i mean is when i click the month with news, it shows me the relevent news but the hyperlink for all the months will disappear...
(You may need to tweak this a little - the idea is to go up through the ancestors of the current page
to find the "year" folder - use its DocumentType Alias where I've put "YearFolder")
Then base the $monthFolder variable off of $yearFolder instead:
Splitting a string to array
Does anyone know how can i split a @nodename like this 091106 to an array like 09,11,06 in xslt file?
I need to split every two digit in order to get the months like this later:
April
Thanks,
Mitra
Hi Mitra,
If the format is very strict, you can use the substring() function to grab the pieces you need:
/Chriztian
Another approach would be to use the
tokenize()
extension to actually perform a split and get a set of results back, but that returns some weird values at times... ideally you can do:(The
tokenize()
method seems to return an empty<match>
for every "real" match it finds)/Chriztian
Hi Mitra,
Both of Chriztian's solutions will work very well.
An alternative solution, if you are using the uComponents package, then you could try the
ParseExact
method (from the Dates XSLT extension:(I'm assuming that the date format is
ddMMyy
- please change accordingly)The benefit of this approach is that it will use .NET globalization to output the month name in the current culture.
Cheers,
- Lee
Thank you very much for your replies. But i'm again back to my first problem.
I need to take this array out of the loop and then highlight the months with news.
if i define the array inside the loop, outside the loop it does not work. and if i define it at the top of my xslt file, the default value does not changes.
I have tried it with a flag for each months before, and now array but it does not work. my code is like this:
Hi Mitra,
I can see your comments are somehow being caught by the SPAM filter here (the emails go through, so I think I'm able to get what you mean).
I'll be back with a take on your problem - hang on!
/Chriztian
Thanks :(
Hi Mitra,
You should be able to post again now - "SORRY", I'm told :)
Now let's tackle your problem - could you try posting the structure you have in Content - and the output you're hoping for?
/Chriztian
Thanks a lot Chriztian :)
I'm hoping to see all the months, and hyperlink the once with news.
All the news system works ok, i am using UNews and DateFolder.
I have a loop like this:
<xsl:for-each select="$currentPage/DateFolder">
<xsl:variable name="Array" select="substring(@nodeName, 1, 2)" />
<xsl:variable name="count" select="count(preceding-sibling::*) + 1" />
</xsl:for-each>
Array for each year i select shows me string with the months something like this 11120410 (means i have got a news in Nov, Dec, April, ... )
after the look finished i want to check if the month have any news, then hyperlink, otherwise write the month normal, like this:
February
March
May
June
August
September
October
November
December
so i say
<xsl:choose>
<xsl:when test="contains($Array,'10')"><a href='{umbraco.library:NiceUrl(@id)}' class="news">October</a></xsl:when>
<xsl:otherwise>October</xsl:otherwise>
</xsl:choose><br/>
but the problem is as soon as i am out of the loop, the Array is not recognised. and if i put this in the loop, then i'll have multiple 12 months (depends how many months have got news)
Sorry for this long message :(
Hi Mitra,
Okay - Since you want all the months, regardless of them having events, you should be making that the main focus and have the outermost "loop" generate the months. Then simply select the DateFolder that matches the month you're currently displaying, and if you get any back, create a link - otherwise print its name... :
Note: If your DateFolders have single digit names (e.g., "3" instead of "03") just change them in the XML variable.
Hope I've explained it sufficiently - otherwise, let me know :-)
/Chriztian
Many many thanks - The code was great. It worked perfectly ( Although I couldn't really understand how :( )
I have to learn what you did and how you checked if there is any news...
Mitra
Hi Mitra,
It works by the magic of nodesets :-) Whenever you make a selection in XSLT/XPath you're actually getting a nodeset (unless you specifically select a string, a number or a boolean value). Even if a nodeset is empty, it's still a nodeset that you can query.
So when we select all DateFolder nodes below
$currentPage
where the@nodeName
is the current value in the loop:Even if no DateFolder matches, the
$monthFolder
variable is still a nodeset, and we can use it as usual, e.g. use the apply-templates instruction:This will take every node in the set and find a matching template in the "link" mode, and execute that template with the node as the context. Now, if the set was empty, no templates will have been executed - we didn't even need to do any counting or checking of any kind; neat, right?
Last piece of the puzzle; this line:
...translates into "Write the value of the current node (of the for-each loop) if it's a
<month>
element and the$monthFolder
was empty".The
not()
function expects a boolean value, so when we send in a nodeset, the processor will run the variable through theboolean()
function first - and that will returnfalse()
for an empty nodeset andtrue()
for a nodeset with one or more nodes. So if the$monthsFolder
is an empty nodeset, thenot()
function will returntrue()
...Phew, hope that's better :-)
/Chriztian
Oh my god - Thank you so much - i have to play with it a little to undretand it better.
Thanks a lot for your reply. Do you know with this method if i can set the hyperlinks on for the months, even after clicking to the month. What i mean is when i click the month with news, it shows me the relevent news but the hyperlink for all the months will disappear...
You're welcome, no problem :-)
You can pretty easily make that adjustment - create a variable after the
$currentPage
param near the top:(You may need to tweak this a little - the idea is to go up through the ancestors of the current page to find the "year" folder - use its DocumentType Alias where I've put "YearFolder")
Then base the
$monthFolder
variable off of$yearFolder
instead:Now, any page below (or on) the "Year" node that has this macro, will show the linked months view.
/Chriztian
It works :)
Thanks again.
is working on a reply...