This works if i edit each node and manually pick an image to use as banner, but i need it to display a default banner on all child nodes until someone chooses to insert another banner on one of the child nodes.
I've tried to find the solution on the forum and tried things such as:
Now i have the banner image from my top node on all child nodes, but if i choose another image on one of my child nodes, i still shows the top node banner image.
The [$...] syntax tells umbraco to look on the current page for a property with that name, if it can't be found, recursivly move back up the tree untill it does.
The only places i get banners is the pages i manually picked one for eventhough i've picked the banners on my container, it doesn't go up the three and find it, or maybe it can't find the property. I'm a bit confused by now because of all the different aliases (macroalias / property alias).
Get all the nodes that meet your criteria from current page to the root. XSLT brings these back in order. The [1] specifies to select the 1st node closest to the $currentPage.
Using the old format I think it would be something like:
you'll want to define a property on your macro to pass the value into, then rather than grabbing it from the current page, grab it from the macros properties instead
How is that parameter telling umbraco to run recursively through my nodes? I mean, it's just a parameter with a value set by me. I can't see how that affects the rest of the XSLT ?
Sorry, I did post a code sample with my last post, but it looks like the mobile site strips out your code (DOH!)
Anyway, yea, as per Daniel said really, define your properties on the Paramters tab of the Macro edit interface, and then just request recall them as per Daniels example. One last thing to note, whatever you call "alias" in Daniels example, as also the attribute you need to define on your macro, so:
If i create a macro parameter called "myMacroPropertyAlias" on the Parameters Tab then what would "myValue" be? As i can tell i have 3 fields when making a parameter.
"myValue" would be the property alias of the property defined on your doc type you want to pass through, so in your case it I belive it would be "bannerImage"
Just read your first reply where you answered that, sorry :)
So when i add the parameter i shouldn't care about the fields "Name" and "Type", and just type in an alias, correct?
I'm not at my workstation now, so obviously i would test it if i had the chance instead of keep asking. Hope it's alright, your help is very much appreciated!!
The type is some-what relevant, as you'll want to make sure the data types kinda match (I say kinda, as not all types are equivilant). If your macro is only ever going to be used in your template (and not be dropped in a ritch text editor), and the doc type property is of type mediaPicker, I'd be tempted to set the Type field to number, as mediaCurrent works sligtly differently to mediaPicker (mediaPicker returns the media items ID, mediaCurrent returns the actual media items XML).
Name isn't that important, but just name it something relevant to your property "Banner Image"
Actually it's going to sit firmly in the master template and is not meant for tinymce, so i'll stick with the number type (as it is a mediaPicker type)
I'll give it a go later, hopefully with great succes ;-)
I think i have some trouble also with my toppage redirecting to its first child.
Like:
-SITE LANGUAGE SOMETHING CONTAINER
- Frontpage
- Page 2
- Etc
If i turn off the redirect, my initial xslt works for the frontpage and the next page shows a different image that i picked manually. The third page then breaks with an xslt parsing error.
If i turn off redirecting, then i works like i would assume, except for one page. If i then alter something on that page and publish it, then it only shows the parent banner on all pages again.
If i then go back and set redirect back on, i works again, except for one page until i publish something.
I have no clue about what the hell is going on here :/ ?
Value was either too large or too small for an Int32. Value was either too large or too small for an Int32. at System.Convert.ToInt32(Double value) at System.Double.System.IConvertible.ToInt32(IFormatProvider provider) at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) at System.Xml.Xsl.Runtime.XmlQueryRuntime.ChangeTypeXsltArgument(XmlQueryType xmlType, Object value, Type destinationType) at System.Xml.Xsl.Runtime.XmlQueryContext.InvokeXsltLateBoundFunction(String name, String namespaceUri, IList`1[] args)
at System.Xml.Xsl.CompiledQuery.Query.<xsl:template
match="/">(XmlQueryRuntime
{urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator
{urn:schemas-microsoft-com:xslt-debug}current, Double
{urn:schemas-microsoft-com:xslt-debug}position, Double
{urn:schemas-microsoft-com:xslt-debug}last, IList`1
{urn:schemas-microsoft-com:xslt-debug}namespaces) in
C:\Inetpub\wwwroot\moderndrums2\xslt\bannerImageLeft.xslt:line 18
at
System.Xml.Xsl.CompiledQuery.Query.<xsl:apply-templates>(XmlQueryRuntime
{urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator , Double ,
Double ) at System.Xml.Xsl.CompiledQuery.Query.Root(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime) at System.Xml.Xsl.CompiledQuery.Query.Execute(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime)
at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument,
XmlResolver dataSources, XsltArgumentList argumentList,
XmlSequenceWriter results) at
System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver
dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean
closeWriter) at
System.Xml.Xsl.XmlILCommand.Execute(IXPathNavigable contextDocument,
XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter
results) at System.Xml.Xsl.XmlILCommand.Execute(IXPathNavigable
contextDocument, XmlResolver dataSources, XsltArgumentList argumentList,
TextWriter results) at System.Xml.Xsl.XslCompiledTransform.Transform(IXPathNavigable input, XsltArgumentList arguments, TextWriter results) at umbraco.macro.GetXsltTransformResult(XmlDocument macroXML, XslCompiledTransform xslt, Dictionary`2 parameters) at umbraco.macro.GetXsltTransformResult(XmlDocument macroXML, XslCompiledTransform xslt) at umbraco.macro.loadMacroXSLT(macro macro, Hashtable attributes, Hashtable pageElements)
I can't believe why i didn't just think of using an umbraco item running a richtext editor, in which i can easily insert an image/banner and assign a link to it. And just as easily make it recursive.
Recursive macro for a banner
Hi there
On my site i need a recursive banner that'll display on child nodes if nothing else is selected in a mediapicker property.
On my home page i have a macro, but i found i have to make the xslt recursive as recursive="true" won't work for macro's.
In my xslt i have the following:
select="umbraco.library:GetMedia($currentPage/data[@alias='bannerImage'], 0)/data"
This works if i edit each node and manually pick an image to use as banner, but i need it to display a default banner on all child nodes until someone chooses to insert another banner on one of the child nodes.
I've tried to find the solution on the forum and tried things such as:
<xsl:variable name="media" select="umbraco.library:GetMedia($currentPage/ancestor-or-self::* /data[@alias='bannerImage'], 0)/data" />
But not quite correct.
Can someone lead me in the direction of a solution to this?
Thanks in advance.
Ok, found it:
<xsl:variable name="media" select="umbraco.library:GetMedia($currentPage/ancestor-or-self::node/data[@alias='bannerImage'], 0)/data" />
I had two pages with the same name, that's why didn't work at first.
Gah, not quite.
Now i have the banner image from my top node on all child nodes, but if i choose another image on one of my child nodes, i still shows the top node banner image.
Any thoughts?
Hi Martin,
You can just use a recursive property for your macro.
If you setup a property on your macro, then when you drop it in your template, set the macros property as follows:
The [$...] syntax tells umbraco to look on the current page for a property with that name, if it can't be found, recursivly move back up the tree untill it does.
Matt
Hi Matt
I actually had a look at one of your posts regarding this but didn't figure it out until now.
Awesome-O virtual high five!
Hi again Matt
I don't know what just happened but i have some troubles getting this to work now.
My structure is like so:
Container page with a redirect to frontpage
Container
- Frontpage
- page 2
- page 3
i'm using this macro in my masterpage file: <umbraco:macro alias="BannerImageLeft" runat="server" myMacroPropertyAlias="[$bannerImageLeft]" />
I've made a property called Banner Image Left with the alias bannerImageLeft
My macro is called: Banner Image Left and macro alias is: BannerImageLeft
xslt is like this:
<xsl:variable name="media" select="umbraco.library:GetMedia($currentPage/data[@alias='bannerImage'], 0)/data" />
<xsl:if test="$media">
<xsl:variable name="url" select="$media [@alias = 'umbracoFile']" />
<xsl:variable name="width" select="$media [@alias = 'umbracoWidth']" />
<xsl:variable name="height" select="$media [@alias = 'umbracoHeight']" />
<img src="{$url}" width="{$width}" height="{$height}" />
</xsl:if>
The only places i get banners is the pages i manually picked one for eventhough i've picked the banners on my container, it doesn't go up the three and find it, or maybe it can't find the property. I'm a bit confused by now because of all the different aliases (macroalias / property alias).
What am i doing wrong?
If i use this method:
<xsl:variable name="media" select="umbraco.library:GetMedia($currentPage/ancestor-or-self::node/data[@alias='bannerImage'], 0)/data" />
then i can't manually override the default banner set on the container :/
You could try something like this:
This is using the new XSLT format for 4.5.
How it works:
Get all the nodes that meet your criteria from current page to the root. XSLT brings these back in order. The [1] specifies to select the 1st node closest to the $currentPage.
Using the old format I think it would be something like:
<xsl:variable name="imageSource" select="currentPage/ancestor-or-self::node/[string(data[@alias='bannerImage'])!=''] [1]/data[@alias='bannerImage']" />
<xsl:variable name="media" select="umbraco.library:GetMedia($imageSource, 0)/data" />
Cheers
Paul
Hi martin
you'll want to define a property on your macro to pass the value into, then rather than grabbing it from the current page, grab it from the macros properties instead
Matt
Hi Matt and Paul
Thanks for all your kind help.
@Matt. Ok! that makes sense as to why i can't get it to work :-)
Only one question remains (sorry). How do i add a macro property? :/
Macro property is a macro parameter.
Define it in the macro UI under the Parameters tab. Note the alias name you use.
In your xslt do this:
<xsl:param name="myparam" select="/macro/alias"/>
... where 'alias' in /macro/alias, is your alias in the macro parameter definition
You can then use the value by reference with $myparam
Hope this helps!
Ok, so my xslt would look like this then when i add the parameter?
<xsl:param name="myparam" select="/macro/alias"/>
<xsl:variable name="media" select="umbraco.library:GetMedia($currentPage/data[@alias='bannerImage'], 0)/data" />
<xsl:if test="$media">
<xsl:variable name="url" select="$media [@alias = 'umbracoFile']" />
<xsl:variable name="width" select="$media [@alias = 'umbracoWidth']" />
<xsl:variable name="height" select="$media [@alias = 'umbracoHeight']" />
<img src="{$url}" width="{$width}" height="{$height}" />
</xsl:if>
How is that parameter telling umbraco to run recursively through my nodes? I mean, it's just a parameter with a value set by me. I can't see how that affects the rest of the XSLT ?
Is it just how it is or? :-)
Hi Martin,
Sorry, I did post a code sample with my last post, but it looks like the mobile site strips out your code (DOH!)
Anyway, yea, as per Daniel said really, define your properties on the Paramters tab of the Macro edit interface, and then just request recall them as per Daniels example. One last thing to note, whatever you call "alias" in Daniels example, as also the attribute you need to define on your macro, so:
Would require that you have a macro property defined with an alias of "myMacroPropertyAlias" which you would then retreive in your xslt as follows:
Which you can then use the value of like so:
or if it's a media item
Matt
Hi Matt
Thanks for clarifying!
If i create a macro parameter called "myMacroPropertyAlias" on the Parameters Tab then what would "myValue" be? As i can tell i have 3 fields when making a parameter.
Alias - Name - Type (selectbox)
Hi Martin,
"myValue" would be the property alias of the property defined on your doc type you want to pass through, so in your case it I belive it would be "bannerImage"
Many thanks
Matt
Hi Matt
Just read your first reply where you answered that, sorry :)
So when i add the parameter i shouldn't care about the fields "Name" and "Type", and just type in an alias, correct?
I'm not at my workstation now, so obviously i would test it if i had the chance instead of keep asking. Hope it's alright, your help is very much appreciated!!
No problem,
The type is some-what relevant, as you'll want to make sure the data types kinda match (I say kinda, as not all types are equivilant). If your macro is only ever going to be used in your template (and not be dropped in a ritch text editor), and the doc type property is of type mediaPicker, I'd be tempted to set the Type field to number, as mediaCurrent works sligtly differently to mediaPicker (mediaPicker returns the media items ID, mediaCurrent returns the actual media items XML).
Name isn't that important, but just name it something relevant to your property "Banner Image"
Matt
Actually it's going to sit firmly in the master template and is not meant for tinymce, so i'll stick with the number type (as it is a mediaPicker type)
I'll give it a go later, hopefully with great succes ;-)
Thanks alot thus far!
Hi again
I'm totally bummed out by how little of this concept i am able to grasp.
I've added the macro parameter, but i'm extremely confused about how my xslt should look.
Right now i have this, not working by the way and i know it's wrong, it just gave up as i don't know what is up or down:
I think i have some trouble also with my toppage redirecting to its first child.
Like:
-SITE LANGUAGE SOMETHING CONTAINER
- Frontpage
- Page 2
- Etc
If i turn off the redirect, my initial xslt works for the frontpage and the next page shows a different image that i picked manually. The third page then breaks with an xslt parsing error.
I really need that redirect :/
Ok this is insane.
If i turn off redirecting, then i works like i would assume, except for one page. If i then alter something on that page and publish it, then it only shows the parent banner on all pages again.
If i then go back and set redirect back on, i works again, except for one page until i publish something.
I have no clue about what the hell is going on here :/ ?
xslt:
Erh...
Now i deleted the one page with the parsing error on it, and now it seems to work??
Anyone ever tried something like this?
This must be some sort of 4.0.2 -> 4.5.1 upgrade thing and i use the old schema.
Everytime i make a new node and sort it, my recursive function stops working. If i delete the new page and reublish my frontpage, then it works again.
debug gives me this:
Value was either too large or too small for an Int32.
Value was either too large or too small for an Int32.
at System.Convert.ToInt32(Double value)
at System.Double.System.IConvertible.ToInt32(IFormatProvider provider)
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at System.Xml.Xsl.Runtime.XmlQueryRuntime.ChangeTypeXsltArgument(XmlQueryType xmlType, Object value, Type destinationType)
at System.Xml.Xsl.Runtime.XmlQueryContext.InvokeXsltLateBoundFunction(String name, String namespaceUri, IList`1[] args)
at System.Xml.Xsl.CompiledQuery.Query.<xsl:template match="/">(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current, Double {urn:schemas-microsoft-com:xslt-debug}position, Double {urn:schemas-microsoft-com:xslt-debug}last, IList`1 {urn:schemas-microsoft-com:xslt-debug}namespaces) in C:\Inetpub\wwwroot\moderndrums2\xslt\bannerImageLeft.xslt:line 18
at System.Xml.Xsl.CompiledQuery.Query.<xsl:apply-templates>(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator , Double , Double )
at System.Xml.Xsl.CompiledQuery.Query.Root(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime)
at System.Xml.Xsl.CompiledQuery.Query.Execute(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime)
at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlSequenceWriter results)
at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean closeWriter)
at System.Xml.Xsl.XmlILCommand.Execute(IXPathNavigable contextDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter results)
at System.Xml.Xsl.XmlILCommand.Execute(IXPathNavigable contextDocument, XmlResolver dataSources, XsltArgumentList argumentList, TextWriter results)
at System.Xml.Xsl.XslCompiledTransform.Transform(IXPathNavigable input, XsltArgumentList arguments, TextWriter results)
at umbraco.macro.GetXsltTransformResult(XmlDocument macroXML, XslCompiledTransform xslt, Dictionary`2 parameters)
at umbraco.macro.GetXsltTransformResult(XmlDocument macroXML, XslCompiledTransform xslt)
at umbraco.macro.loadMacroXSLT(macro macro, Hashtable attributes, Hashtable pageElements)
This error is quite common it seems BUT
I can't believe why i didn't just think of using an umbraco item running a richtext editor, in which i can easily insert an image/banner and assign a link to it. And just as easily make it recursive.
God damnit :-)
Thanks to all who tried to help out.
is working on a reply...