Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • MartinB 411 posts 512 karma points
    Apr 10, 2012 @ 21:42
    MartinB
    0

    4.7.1 XSLT default image if none selected

    Hi there

    I can't wrap my head around this little feature :/

    I'm selecting a body background image through a MediaPicker field. If no image has been picked i want to output a default image for the Media section (image id = 296).

    So far i have this working IF an image has been picked for the current page.

    <xsl:output method="xml" omit-xml-declaration="yes"/>

    <xsl:param name="currentPage"/>
    <xsl:variable name="imageRoot" select="$currentPage/bodyBg"/>
    <xsl:variable name="media" select="umbraco.library:GetMedia($currentPage/bodyBg, 1)/umbracoFile" />

    <xsl:template match="/">
    <xsl:choose>
    <xsl:when test="string($media) != ''">
    <xsl:value-of select="$media" disable-output-escaping="yes"/>
    </xsl:when>
    <xsl:otherwise>
    <!--IMAGE HERE-->
    </xsl:otherwise>
    </xsl:choose>
    </xsl:template>

    </xsl:stylesheet>

    If i navigate to a page where an image has NOT been picked, i get this with debug trace:

       Værdien var enten for stor eller for lille til en Int32.
    Værdien var enten for stor eller for lille til en Int32.
      ved System.Convert.ToInt32(Double value)
      ved System.Double.System.IConvertible.ToInt32(IFormatProvider provider)
      ved System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
      ved System.Xml.Xsl.Runtime.XmlQueryRuntime.ChangeTypeXsltArgument(XmlQueryType xmlType, Object value, Type destinationType)
      ved System.Xml.Xsl.Runtime.XmlQueryContext.InvokeXsltLateBoundFunction(String name, String namespaceUri, IList`1[] args)

    and so forth. The ol' int32 problem.

    How do i go about getting the image with the ID of 296 shown as a default image until something else has been picked?

    Thanks in advance

  • MartinB 411 posts 512 karma points
    Apr 10, 2012 @ 21:48
    MartinB
    0

    The imageroot variable is old leftovers, that i forgot to remove for this example.

  • Tom Fulton 2030 posts 4990 karma points c-trib
    Apr 10, 2012 @ 21:52
    Tom Fulton
    1

    Hi,

    The problem is that Umbraco is running the GetMedia call even when bodyBy has no value, thus causing the error.  To fix you need to check to make sure there's a value before you call GetMedia.  This should do it:

    <xsl:output method="xml" omit-xml-declaration="yes"/>

    <xsl:param name="currentPage"/>
    <xsl:variable name="imageRoot" select="$currentPage/bodyBg"/>

    <xsl:template match="/">
      <xsl:choose>
        <xsl:when test="$imageRoot &gt; 0">
          <xsl:variable name="media" select="umbraco.library:GetMedia($imageRoot, false())" />
          <img src="{$media/umbracoFile}" />
        </xsl:when>
        <xsl:otherwise>
          <!--IMAGE HERE-->
        </xsl:otherwise>
      </xsl:choose> 

    </xsl:template>

    </xsl:stylesheet>

    HTH,
    Tom

     

  • Nigel Wilson 936 posts 2058 karma points
    Apr 10, 2012 @ 22:02
    Nigel Wilson
    1

    Hi Martin

    Maybe something along the lines of:

    <xsl:output method="xml" omit-xml-declaration="yes"/>
    <xsl:param name="currentPage"/>
    <xsl:variable name="imageRoot">
    <xsl:choose>
    <xsl:when test="$currentPage/bodyBg &gt; 0">
    <xsl:value-of select="number($currentPage/bodyBg)"/>
    </xsl:when>
    <xsl:otherwise>
    <xsl:value-of select="number(296)" /> // Your hard coded media ID here
    </xsl:otherwise>
    </xsl:choose>
    </xsl:variable>

    <xsl:template match="/">
    <img>
    <xsl:attribute name="src">
    <xsl:value-of select="umbraco.library:GetMedia($imageRoot, 0)/umbracoFile" />
    </xsl:attribute>
    </img>

    </xsl:template>
    </xsl:stylesheet>

     

    I haven't tested the above - relying on the ol' grey matter...

    Cheers

    Nigel

     

  • MartinB 411 posts 512 karma points
    Apr 10, 2012 @ 22:09
    MartinB
    0

    Hi Nigel

    I got around to this in the meantime, it looks close to yours and it seems to work, all i need now is the default value.

    <xsl:template match="/">
    <xsl:variable name="mediaId" select="number($currentPage/bodyBg)" />
    <xsl:choose>
    <xsl:when test="$mediaId > 0">
    <xsl:variable name="mediaNode" select="umbraco.library:GetMedia($mediaId, 0)" />
    <xsl:if test="$mediaNode/umbracoFile">
    <xsl:value-of select="$mediaNode/umbracoFile" disable-output-escaping="yes"/>
    </xsl:if>
    </xsl:when>
    <xsl:otherwise>
    TADAA
    </xsl:otherwise>
    </xsl:choose>
    </xsl:template>

    Thank you very much for your time and suggestion . i will give it a go if the above fails

  • MartinB 411 posts 512 karma points
    Apr 10, 2012 @ 22:19
    MartinB
    0

    Alright, so far so good.

    I need to pass this value:

    <xsl:otherwise>          
    /media/296/dusk.jpg
    </xsl:otherwise>

    How do i construct a variable containg the above value so it would be inserted correctly into;

    <body style="background:#f2eee9 url('<umbraco:Macro Alias="BodyBackground" runat="server"></umbraco:Macro>') no-repeat 50% 0;">

    I know it's a bit ugly, but bear with me :-)

  • MartinB 411 posts 512 karma points
    Apr 10, 2012 @ 22:31
    MartinB
    0

    Oh! Sorry Tom, didn't see your post, it seems it's identical to what i found.

    I guess i could integrate the body tag in the macro, i just think being able to pass the value is more...well....fun. Is it doable?

  • Tom Fulton 2030 posts 4990 karma points c-trib
    Apr 10, 2012 @ 22:46
    Tom Fulton
    0

    That should work, instead of the <img> tag you can just do an <xsl:value-of select="$mediaNode/umbracoFile"/> - that should just return the path

    -Tom

  • MartinB 411 posts 512 karma points
    Apr 10, 2012 @ 22:54
    MartinB
    0

    Hi Tom

    Idk if i understand you correctly, but try taking a look at this:

    <xsl:template match="/">
    <xsl:variable name="mediaId" select="number($currentPage/bodyBg)" />
    <xsl:choose>
    <xsl:when test="$mediaId > 0">
    <xsl:variable name="mediaNode" select="umbraco.library:GetMedia($mediaId, 0)" />
    <xsl:if test="$mediaNode/umbracoFile">
    <xsl:value-of select="$mediaNode/umbracoFile" disable-output-escaping="yes"/>
    </xsl:if>
    </xsl:when>
    <xsl:otherwise>
    <xsl:value-of select="concat('/media', '/296', '/dusk.jpg')" disable-output-escaping="yes"/>
    </xsl:otherwise>
    </xsl:choose>
    </xsl:template>

    If i pick an image for any given currentpage my body tag looks like this - The WHEN part:

    <body style="background:#f2eee9 url(/media/296/dusk.jpg) no-repeat 50% 0">

    If i do not pick an image and want to fall back to the default background image value - The OTHERWISE part, i get this right now:

    <body style="background:#f2eee9 url(<div title="Macro Tag: 'BodyBackground'" style="border: 1px solid #009;">/media/296/dusk.jpg</div>) no-repeat 50% 0"> 

    The value is passed, but it breaks the body tag somehow. How can i pass '/media/2967dusk.jpg' as a variable that'll work for this?

    I know it's a bit akward but i hope it's clear what i'm trying to achieve.

  • MartinB 411 posts 512 karma points
    Apr 10, 2012 @ 23:24
    MartinB
    0

    JESUS CHRIST!

    It didn't work because i was testing a childpage with the umbdebugtrace extension in the url. What the bloody hell :(((

    Thanks to both of you for your kind assistance

  • MartinB 411 posts 512 karma points
    Apr 10, 2012 @ 23:30
    MartinB
    0

    Ok, to sum up what i did.

    I'm setting my body background through an inline style that references a macro for the url path:

    <body style="background:#f2eee9 url(<umbraco:Macro Alias="BodyBackground" runat="server"></umbraco:Macro>) no-repeat 50% 0">

    The macro where '/media/296/dusk.jpg' is the fallback image if no background image is chosen through a mediaPicker for the current page:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]>
    <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.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets" xmlns:tagsLib="urn:tagsLib" xmlns:BlogLibrary="urn:BlogLibrary"
    exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets tagsLib BlogLibrary ">

    <xsl:output method="xml" omit-xml-declaration="yes"/>

    <xsl:param name="currentPage"/>

    <xsl:template match="/">
    <xsl:variable name="mediaId" select="number($currentPage/bodyBg)" />
    <xsl:choose>
    <xsl:when test="$mediaId > 0">
    <xsl:variable name="mediaNode" select="umbraco.library:GetMedia($mediaId, 0)" />
    <xsl:if test="$mediaNode/umbracoFile">
    <xsl:value-of select="$mediaNode/umbracoFile" disable-output-escaping="yes"/>
    </xsl:if>
    </xsl:when>
    <xsl:otherwise>
    <xsl:variable name="mediaDefault" select="concat('/media', '/296', '/dusk.jpg')"/>
    <xsl:value-of select="$mediaDefault" disable-output-escaping="yes"/>
    </xsl:otherwise>
    </xsl:choose>
    </xsl:template>

    </xsl:stylesheet>

    Testing a page without a picked background and using the ?umbdebugtrace="true" will break the body tag for whatever reason.

  • Wade 43 posts 159 karma points
    Oct 04, 2012 @ 06:39
    Wade
    0

    Hi guys,

    This solution worked for what I wanted to do with a dynamic body tag, but I would like to extend it slightly.  Instead of hard coding the mediaDefault variable to be a certain image, I need to call in the value in the parent folder (the toplevel page as shown below).

     

    The structure is:

    Home

    Toplevel page

    subpage

    subpage

    subpage

     

    I've tried the following, but can't get it right.

    <xsl:template match="/">
        <xsl:variable name="mediaId" select="number($currentPage/backgroundImage)" />
        <xsl:choose>
                    <xsl:when test="$mediaId > 0">
                            <xsl:variable name="mediaNode" select="umbraco.library:GetMedia($mediaId, 0)" />
                            <xsl:if test="$mediaNode/umbracoFile">
                                    <xsl:value-of select="$mediaNode/umbracoFile" disable-output-escaping="yes"/>
                            </xsl:if>
                    </xsl:when>
                    <xsl:otherwise>
                      <xsl:variable name="parentID" select="$currentPage/ancestor-or-self::*[normalize-space(media)][2]/backgroundImage"/> 
                            <xsl:variable name="mediaDefault" select="umbraco.library:GetXmlNodeById($parentID)" />                  
                            <xsl:value-of select="$mediaDefault" disable-output-escaping="yes"/> 
                                             
                                               
                    </xsl:otherwise>
            </xsl:choose>
    </xsl:template>

     

    Any help would be greatly appreciated.

  • Tom Fulton 2030 posts 4990 karma points c-trib
    Oct 04, 2012 @ 20:06
    Tom Fulton
    1

    Hi,

    I think your code looks right, except in the recursive call I think you're using hte wrong element ('media' instead of 'backgroundImage').  Try this instead:

    <xsl:variable name="parentID" select="$currentPage/ancestor-or-self::*[normalize-space(backgroundImage)][2]/backgroundImage"/> 

    Also, no need to use GetXmlNodeById, you can jump straight into your Media stuff, using the same code as your first condition, but changing $mediaId to $parentID.  You might also create a template so you can re-use that code.  

    I think the below piece should work:

                    <xsl:otherwise>
                      <xsl:variable name="parentID" select="$currentPage/ancestor-or-self::*[normalize-space(backgroundImage)][2]/backgroundImage" /> 
                      <xsl:variable name="mediaNode" select="umbraco.library:GetMedia($parentID, 0)" />
                      <xsl:if test="$mediaNode/umbracoFile">
                                    <xsl:value-of select="$mediaNode/umbracoFile" disable-output-escaping="yes"/>
                      </xsl:if>                                           
                    </xsl:otherwise>

    Hope this helps,

    Tom

  • Wade 43 posts 159 karma points
    Oct 04, 2012 @ 23:48
    Wade
    0

    Thanks for the help Tom.

    I did try GetMedia first but it throws a System.OverflowException: Value was either too large or too small for an Int32.   error.  Your code does the same thing.  Any ideas on why it might be doing that?

  • Tom Fulton 2030 posts 4990 karma points c-trib
    Oct 05, 2012 @ 00:41
    Tom Fulton
    0

    Oh, sorry, you need to wrap GetMedia in an if statement to make sure it gets passed a value:

                    <xsl:otherwise>
                      <xsl:variable name="parentID" select="$currentPage/ancestor-or-self::*[normalize-space(backgroundImage)][2]/backgroundImage" /> 
                      <xsl:if test="$mediaNode &gt; 0">
                        <xsl:variable name="mediaNode" select="umbraco.library:GetMedia($parentID, 0)" />
                        <xsl:if test="$mediaNode/umbracoFile">
                                      <xsl:value-of select="$mediaNode/umbracoFile" disable-output-escaping="yes"/>
                        </xsl:if>                                           
                      </xsl:if>
                    </xsl:otherwise>

    -Tom

  • Wade 43 posts 159 karma points
    Oct 05, 2012 @ 00:58
    Wade
    0

    Hmm, This line keeps throwing an error.

    <xsl:iftest="$mediaNode &gt; 0">

    Could it be because it is being called before the variable is defined?

     

  • MartinB 411 posts 512 karma points
    Oct 14, 2012 @ 19:29
    MartinB
    1

    Hi Wade

    Having just looked at it briefly i think you need to to it like this:

    <xsl:otherwise>
                     

                     
    <xsl:iftest="$mediaNode &gt; 0">
                       

    <xsl:variablename="parentID"select="$currentPage/ancestor-or-self::*[normalize-space(backgroundImage)][2]/backgroundImage"/><xsl:variablename="mediaNode"select="umbraco.library:GetMedia($parentID, 0)"/>
                       
    <xsl:iftest="$mediaNode/umbracoFile">
                                     
    <xsl:value-ofselect="$mediaNode/umbracoFile"disable-output-escaping="yes"/>
                       
    </xsl:if>                                          
                     
    </xsl:if>
                   
    </xsl:otherwise>
  • MartinB 411 posts 512 karma points
    Oct 14, 2012 @ 19:30
    MartinB
    0

    and a space between "if" and "test" :-)

  • Tom Fulton 2030 posts 4990 karma points c-trib
    Oct 14, 2012 @ 19:30
    Tom Fulton
    0

    Sorry, yes, $mediaNode should be $parentId instead - copy/paste error :)

  • Wade 43 posts 159 karma points
    Oct 14, 2012 @ 21:51
    Wade
    0

    Hi guys.

    You rock! Thank you!  Tom's solution worked in the end.  All I had to do was change $mediaNode to $parentID and then change the level that it was searching in from 2 to 1 like the following, as I had made an error in where it was looking.

     

    <xsl:variablename="parentID"select="$currentPage/ancestor-or-self::*[normalize-space(backgroundImage)][2]/backgroundImage"/>
    <xsl:variablename="parentID"select="$currentPage/ancestor-or-self::*[normalize-space(backgroundImage)][1]/backgroundImage"/>

     

    Martin, thank you for your solution too, however the if test

     

    <xsl:iftest="$mediaNode &gt; 0">

     

    kept throwing an error.  Doesn't matter though as Tom's solotion worked.  

    The final code to show an image from a parent node if none is selected on the child node is:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]>
    <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.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets" xmlns:tagsLib="urn:tagsLib" xmlns:BlogLibrary="urn:BlogLibrary" 
      exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets tagsLib BlogLibrary ">

    <xsl:output method="xml" omit-xml-declaration="yes"/>

    <xsl:param name="currentPage"/>

    <xsl:template match="/">
        <xsl:variable name="mediaId" select="number($currentPage/backgroundImage)" />
        <xsl:choose>
                    <xsl:when test="$mediaId &gt; 0">
                            <xsl:variable name="mediaNode" select="umbraco.library:GetMedia($mediaId, 0)" />
                            <xsl:if test="$mediaNode/umbracoFile">
                                    <xsl:value-of select="$mediaNode/umbracoFile" disable-output-escaping="yes"/>
                            </xsl:if>
                    </xsl:when>
                    <xsl:otherwise>
                      <xsl:variable name="parentID" select="number($currentPage/ancestor-or-self::*[normalize-space(backgroundImage)][1]/backgroundImage)" /> 
                      <xsl:if test="$parentID &gt; 0">
                        <xsl:variable name="mediaNode" select="umbraco.library:GetMedia($parentID, 0)" />
                        <xsl:if test="$mediaNode/umbracoFile">
                                      <xsl:value-of select="$mediaNode/umbracoFile" disable-output-escaping="yes"/>
                        </xsl:if>                                           
                      </xsl:if>
                    </xsl:otherwise>
            </xsl:choose>
    </xsl:template>

    </xsl:stylesheet>

     

     

Please Sign in or register to post replies

Write your reply to:

Draft