If you don't have any other fields on your document type that contains 'Story' in the alias, you can loop through the five fields with something like this:
Are you asking about like ad rotator? so each time page is refresh different text is displayed. e.g. storyOne for first time and after page refresh story two
I think the problem is the upper S in 'Story'. When you create a new property name like Story1, umbraco automatically creates an alias name with lowercase s as first letter. Try this for the loop:
<msxsl:script language="c#" implements-prefix="randomTools"> <msxsl:assembly href="../bin/umbraco.dll"/> <![CDATA[ /// <summary> /// Gets a random integer that falls between the specified limits /// </summary> /// <param name="lowerLimit">An integer that defines the lower-boundary of the range</param> /// <param name="upperLimit">An integer that defines the upper-boundary of the range</param> /// <returns>A random integer within the specified range</returns> public static int GetRandom(int lowerLimit,int upperLimit) { Random r = umbraco.library.GetRandom(); int returnedNumber = 0; lock (r) { returnedNumber = r.Next(lowerLimit, upperLimit); } return returnedNumber; } ]]> </msxsl:script> <xsl:output method="xml" omit-xml-declaration="yes" />
Dirk's solution looks the best for what you are trying to do, however you may want to change the fields to 'Story1', 'Story2' etc.... instead of 'StoryOne', 'StoryTwo' etc...
That could be your problem... because I noticed you had those field names in your initial post, but not in your follow up posts.
If you use Dirk's method, make sure that the alias' for each of your fields are exactly (case sensitive) 'story1', 'story2' etc....
Is your issue that the macro isn't being run at all? Check that the alias of the macro (XSLTFeatureNews) is the same as is listed for that macro in the developer section. Check for case sensitivity as well.
Maybe just put some text in the start of your XSLT to see that it's being hit. So....
which version of umbraco are you using? My first xslt script was for version 4.7 (should work since 4.5). But if your version is below 4.5 you may try this:
<msxsl:script language="c#" implements-prefix="randomTools"> <msxsl:assembly href="../bin/umbraco.dll"/> <![CDATA[ /// <summary> /// Gets a random integer that falls between the specified limits /// </summary> /// <param name="lowerLimit">An integer that defines the lower-boundary of the range</param> /// <param name="upperLimit">An integer that defines the upper-boundary of the range</param> /// <returns>A random integer within the specified range</returns> public static int GetRandom(int lowerLimit,int upperLimit) { Random r = umbraco.library.GetRandom(); int returnedNumber = 0; lock (r) { returnedNumber = r.Next(lowerLimit, upperLimit+1); } return returnedNumber; } ]]> </msxsl:script>
Hmmm, the code looks ok (I think). Dirk, can you see any issues with it? The XSLT is obviously working as the macro code...
I think I had a similar issue the other day with the field names, but only after I had changed the field names.
If you have changed the field names in the Document Type, you should go and save and publish the document(s) that use that Document Type again. This way they will have the new field names in the xml they produce.
A good thing you may want to do to check the data:-
outside of your <xsl:for-each loop, just output the data of everything in the currentPage.
<xsl:for-each select="$currentPage/ancestor-or-self::node/data [starts-with(@alias,'story')]"> TEST 1 <p> story <xsl:value-of select="position()"/>: <strong><xsl:value-of select="." /></strong> </p> </xsl:for-each>
<xsl:for-each select="$currentPage/ancestor-or-self::node/data [contains(@alias,'story')]"> TEST 2
<p> story <xsl:value-of select="position()"/>: <strong><xsl:value-of select="." /></strong> </p> </xsl:for-each> TEST 3
I dont think you have access to the property alias, but at least I am not an xslt expert. And for the given problem I can not see a problem with this - you should not need to reed the name. position might be satisfying.
@praveen: Have you tried my second random script for version below 4.5 e. g. 4.0?
I'd highly recommend that you don't use the inline <msxml:script> code blocks - they are bad, bad, bad news! (No offense to Dirk!)
My suggestion is to make use of the ExsltDatesAndTimes extensions, like so...
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY nbsp " ">
]>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxml="urn:schemas-microsoft-com:xslt"
xmlns:umbraco.library="urn:umbraco.library"
xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes"
exclude-result-prefixes="msxml umbraco.library Exslt.ExsltDatesAndTimes">
<xsl:output method="xml" omit-xml-declaration="yes" />
<xsl:param name="currentPage"/>
<xsl:template match="/">
<!--
Uses the 'secondinminute' to return a value between 0 and 59,
then take the modulus of the seconds (by the total nodes) and increment by 1 (as e.g. 30 % 5 == 0)
-->
<xsl:variable name="index" select="(Exslt.ExsltDatesAndTimes:secondinminute() mod 5) + 1" />
<!-- Use concat to construct the alias name -->
<xsl:value-of select="$currentPage/data[@alias = concat('story', $index)]"/>
</xsl:template>
</xsl:stylesheet>
The idea here is that you make a call "Exslt.ExsltDatesAndTimes:secondinminute()", this will return a value between 0 and 59 ... then you take the modulus of 5 from that value (plus 1 ... as you don't want a value of zero!)
Once you've got that index number, you can then use it in a <xsl:value-of> to return the "random" story.
If you wanted to slow down the random/rotation - you could switch the "secondinminute" to something else like "hourinday" or "dayinweek"?
Loop through Page Fields
Hi There,
I am new to umbraco and xslt, thanks for your help in advance.
I have 5 page fields on the home page as follows:
<umbraco:Item field="Story1" runat="server"></umbraco:Item>
<umbraco:Item field="Story2" runat="server"></umbraco:Item>
<umbraco:Item field="Story3" runat="server"></umbraco:Item>
<umbraco:Item field="Story4" runat="server"></umbraco:Item>
<umbraco:Item field="Story5" runat="server"></umbraco:Item>
I want to write some XSLT so that on every page refresh a diffrent story text is displayed.
Many thanks in advance.
Kind Regards
Hi praveen
If you don't have any other fields on your document type that contains 'Story' in the alias, you can loop through the five fields with something like this:
/Kim A
Hi Kim
Many thanks of your help, how can I print fieldname.value in the loop, please let me know
<xsl:for-each select="$currentPage/*[contains(name(),'Story')]">
fieldName.value
<umbraco:Item field="StoryOne" runat="server"/>
</xsl:for-each>
Kind Regards
Hi praveen,
You can print values using the value-of instruction, e.g.:
/Chriztian
Hi Chriztian
Many thanks for your help.
<!-- This does not code works-->
<xsl:for-each select="$currentPage/*[starts-with(name(), 'Story')]">
<p>
<xsl:value-of select="name()" />: <strong><xsl:value-of select="." /></strong>
</p>
</xsl:for-each>
<!-- This code works-->
<xsl:for-each select="$currentPage/*[contains(name(),'Story')]">
<umbraco:Item field="StoryOne" runat="server"></umbraco:Item>
<umb raco:Item field="StoryTwo" runat="server"></umbraco:Item>
<umb raco:Item field="StoryThree" runat="server"></umbraco:Item>
<umb raco:Item field="StoryFour" runat="server"></umbraco:Item>
<umbraco:Item field="StoryFive" runat="server"></umbraco:Item>
</xsl:for-each>
I need to diplay a diffrent story on every page refresh
Kind Regards
Hi praveen
Are you asking about like ad rotator? so each time page is refresh different text is displayed. e.g. storyOne for first time and after page refresh story two
Thanks
Hi Pasang,
Yes thats right, but I want to flexiability to dispaly text content only and in some cases images and text content.
Going back to my original question, how can we read "umbraco:item field" value in the for loop.
Kind Regards
Hi praveen,
Did you perhaps copy/paste the XSLT code directly into the template? For the XSLT to work you will have to create a macro first:
1) In the Developer section under "XSLT files" create a new XSLT file
2) Copy/Paste Chriztian's XSLT code into the XSLT file (right under xsl:template)
3) Go back to the template in the Settings section and insert the macro (4th icon from the left)
Hi praveen,
I think the problem is the upper S in 'Story'. When you create a new property name like Story1, umbraco automatically creates an alias name with lowercase s as first letter. Try this for the loop:
<xsl:for-each select="$currentPage/*[starts-with(name(), 'story')]">
<p>
<xsl:value-of select="name()" />: <strong><xsl:value-of select="." /></strong>
</p>
</xsl:for-each>
Your initial question was how to select a random property value.
May be this helps
/Dirk
Hi praveen,
Dirk's solution looks the best for what you are trying to do, however you may want to change the fields to 'Story1', 'Story2' etc.... instead of 'StoryOne', 'StoryTwo' etc...
That could be your problem... because I noticed you had those field names in your initial post, but not in your follow up posts.
If you use Dirk's method, make sure that the alias' for each of your fields are exactly (case sensitive) 'story1', 'story2' etc....
- Sean
Hi Dirk
I tried lower/upercase 'story' and it dose not help.
As advised I created an XSLT file in the developer section and inserted the Macro in the template
and it dose not work.
<!--CODE FROM THE XSLT FILE -- >
<xsl:template match="/">
<!-- start writing XSLT -->
<xsl:for-each select="$currentPage/*[contains(name(),'Story')]">
<xsl:value-of select="data [@alias = 'StoryOne']"/>
</xsl:for-each>
<xsl:for-each select="$currentPage/*[starts-with(name(), 'Story')]">
<p>
<xsl:value-of select="name()" />: <strong><xsl:value-of select="." /></strong>
</p>
</xsl:for-each>
</xsl:template>
<!--MACRO FROM THE TEMPLATE-- >
<umbraco:Macro Alias="XSLTFeatureNews" runat="server"></umbraco:Macro>
However when I directly insert the page field in the template it WORKS.
<umbraco:Item field="Story1" runat="server"></umbraco:Item>
Many thanks for your help and thanks for your patience.
Best Regards
Hi there
I have recreated the page fields and used Dirk XSLT macro, and it dose not work. please help
Hi praveen,
Is your issue that the macro isn't being run at all? Check that the alias of the macro (XSLTFeatureNews) is the same as is listed for that macro in the developer section. Check for case sensitivity as well.
Maybe just put some text in the start of your XSLT to see that it's being hit. So....
<xsl:template match="/">
TEST
<!-- start writing XSLT -->
<xsl:for-each select="$currentPage/*[contains(name(),'Story')]">
<xsl:value-of select="data [@alias = 'StoryOne']"/>
</xsl:for-each>
<xsl:for-each select="$currentPage/*[starts-with(name(), 'Story')]">
<p>
<xsl:value-of select="name()" />: <strong><xsl:value-of select="." /></strong>
</p>
</xsl:for-each>
</xsl:template>
Then you should at least see the word 'TEST' on the page.
- Sean
Hi praveen,
which version of umbraco are you using? My first xslt script was for version 4.7 (should work since 4.5). But if your version is below 4.5 you may try this:
Dirk
Hi Sean,
Thanks for the reply TEST 0 and TEST 3 does print
TEST 1 and TEST2 DOES NOT PRINT
Dirk, I am using umbraco 4.0
TEST 0
<!-- start writing XSLT -->
<xsl:for-each select="$currentPage/*[starts-with(name(), 'story')]">
TEST 1
<p>
<xsl:value-of select="name()" />: <strong><xsl:value-of select="." /></strong>
</p>
</xsl:for-each>
<xsl:for-each select="$currentPage/*[contains(name(),'story')]">
TEST 2
<p>
<xsl:value-of select="name()" />: <strong><xsl:value-of select="." /></strong>
</p>
</xsl:for-each>
TEST 3
Thanks for y our help
Kind Regards
Hmmm, the code looks ok (I think). Dirk, can you see any issues with it? The XSLT is obviously working as the macro code...
I think I had a similar issue the other day with the field names, but only after I had changed the field names.
If you have changed the field names in the Document Type, you should go and save and publish the document(s) that use that Document Type again. This way they will have the new field names in the xml they produce.
A good thing you may want to do to check the data:-
outside of your <xsl:for-each loop, just output the data of everything in the currentPage.
<xsl:value-of select="$currentPage" />
Hi Dirk, Many thanks for your help, I did saved and published the page, but it does not help
This code works displays all the data.
<xsl:value-of select="$currentPage" />
Hi praveen,
Can you post what it displays?
- Sean
Hi praveen, Hi Sean,
well I think praveen has already mentioned the issue ;-) - using version 4.0!
4.5 chanded the xslt parser schema there are a wiki about the changes: http://our.umbraco.org/wiki/reference/xslt/45-xml-schema
Sean Test snippet should look like this:
I dont think you have access to the property alias, but at least I am not an xslt expert. And for the given problem I can not see a problem with this - you should not need to reed the name. position might be satisfying.
@praveen: Have you tried my second random script for version below 4.5 e. g. 4.0?
Dirk
Hi praveen,
Here's an alternative take on the problem...
I'd highly recommend that you don't use the inline <msxml:script> code blocks - they are bad, bad, bad news! (No offense to Dirk!)
My suggestion is to make use of the ExsltDatesAndTimes extensions, like so...
The idea here is that you make a call "Exslt.ExsltDatesAndTimes:secondinminute()", this will return a value between 0 and 59 ... then you take the modulus of 5 from that value (plus 1 ... as you don't want a value of zero!)
Once you've got that index number, you can then use it in a <xsl:value-of> to return the "random" story.
If you wanted to slow down the random/rotation - you could switch the "secondinminute" to something else like "hourinday" or "dayinweek"?
Good luck!
Cheers, Lee.
Hi Lee,
goog idea to use the timer. I was also not happy about the inline code but found that hack somewhere in this forum.
I would give High Five but my karma is still to low ;-)
Dirk
High five to Dirk, LEE, LEE,LEE :),Sean, Kim, Chriztian, Pasang, Lennart
Many many many thanks to all you guys,
Lees, example worked !!!
Guys you have every right to shoot me down, I should have told you Umbraco Version that I am using in the first place :(
Many thanks for your help.
Best Regards
Haha.... nice one Praveen... that one slipped by me. Good work to the guys for their solutions.
Glad you got it working.
- Sean
is working on a reply...