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 4996 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 939 posts 2061 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 4996 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 4996 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 4996 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 4996 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>

     

     

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies