How to use umbraco.library GetMedia in XSLT

From time to time I notice a reoccurring post over at the Our Umbraco forum; how to display an image (from the Media section) in XSLT?

A quick answer can be found on the Our Umbraco wiki for the umbraco.library GetMedia method.

For most uses, the last example in the wiki works great.  But I want to show you a “super safe” way of dealing with GetMedia in XSLT.

Where I find a lot of the examples go wrong is that they make the assumption that a media node (XML) is returned from the GetMedia call, e.g.

<xsl:value-of select="umbraco.library:GetMedia($currentPage/data[@alias='mediaId'], 'false')/data[@alias='umbracoFile']" />

If the ‘mediaId’ property didn’t contain either a numeric value or a valid media node id, then it would return null … meaning that the following “/data” would throw an Exception! (Displaying “Error parsing XSLT file” message on the front-end.)  Not what you or your users want to see!

In order to consider any user inputs, like media IDs not being selected, or even a referenced media node is deleted in the back-office, here is the “super safe” approach:

<xsl:template match="/">
	<xsl:variable name="mediaId" select="number($currentPage/data[@alias='mediaId'])" />
	<xsl:if test="$mediaId &gt; 0">
		<xsl:variable name="mediaNode" select="umbraco.library:GetMedia($mediaId, 0)" />
		<xsl:if test="count($mediaNode/data) &gt; 0">
			<xsl:if test="string($mediaNode/data[@alias='umbracoFile']) != ''">
				<img src="{$mediaNode/data[@alias='umbracoFile']}" alt="[image]">
					<xsl:if test="string($mediaNode/data[@alias='umbracoHeight']) != ''">
						<xsl:attribute name="height">
							<xsl:value-of select="$mediaNode/data[@alias='umbracoHeight']" />
						</xsl:attribute>
					</xsl:if>
					<xsl:if test="string($mediaNode/data[@alias='umbracoWidth']) != ''">
						<xsl:attribute name="width">
							<xsl:value-of select="$mediaNode/data[@alias='umbracoWidth']" />
						</xsl:attribute>
					</xsl:if>
				</img>
			</xsl:if>
		</xsl:if>
	</xsl:if>
</xsl:template>

Here’s what happens:

  1. The “mediaId” is pulled from a property of the “currentPage” and cast as a number.  Optionally the “mediaId” could be passed in via a macro parameter, or somewhere else?
  2. The first condition checks the the “mediaId” is numeric, and greater-than zero.
  3. The “mediaId” is passed through to “GetMedia”, along with the false flag to only pull-back the required node (not it’s children, for Folder media items).
  4. We check if the media node has any child “data” elements – which contain the data about the image/media.
  5. Then we check if the “umbracoFile” property has any data – if not, then there is no point displaying an image.
  6. There are extra conditions for the “height” and “width” properties – these are optional.

Personally, I add an “altText” property to the Image media-type … and use that in the XSLT – again this is optional, but strongly recommended!

I can see how this “super safe” approach is overkill – especially compared with a single line of XSLT … but from my experience, it’s better to be safe than sorry – especially when dealing with user data-input – your assumptions and expectations of how users will use the system aren’t always correct!

Update: OK, I agree the extra “if” statements are overkill… so here’s a condensed version – assuming that the “umbracoHeight” and “umbracoWidth” properties are always there…

<xsl:template match="/">
	<xsl:variable name="mediaId" select="number($currentPage/data[@alias='mediaId'])" />
	<xsl:if test="$mediaId &gt; 0">
		<xsl:variable name="mediaNode" select="umbraco.library:GetMedia($mediaId, 0)" />
		<xsl:if test="count($mediaNode/data) &gt; 0 and string($mediaNode/data[@alias='umbracoFile']) != ''">
			<img src="{$mediaNode/data[@alias='umbracoFile']}" alt="[image]" height="{$mediaNode/data[@alias='umbracoHeight']}" width="{$mediaNode/data[@alias='umbracoWidth']}" />
		</xsl:if>
	</xsl:if>
</xsl:template> 

15 thoughts on “How to use umbraco.library GetMedia in XSLT

  1. This is definitely one of the methods that I would like to get simplified. I would like to just pass an id and some parameters. Something like this:

    umbraco.library:Image(data[@alias='myphoto']) returns

    umbraco.library:Image(data[@alias='myphoto'],’@src’) returns /path/image.gif”

  2. I see the form stripped out image tag. I wanted to show you that Image(data[@alias='myphoto']) should return full image tag and when using second parameter then you can access img attributes as shown in Image(data[@alias='myphoto','@src'])

  3. Hi Lee

    Just starting out with Umbraco and have found your article invaluable.

    I was wondering if it’s possible to create a xlst/macro where the editor can also manually enter the alt text. I was hoping that this could be achieved with the Textstring datatype?

    Any advice or pointers would be greatly appreciated.

    Thanks in advance.

    Eddie

  4. Hi Eddie,

    My advice would be to modify the Image media-type to add a new textstring field called “altText” (or similar), then it is associated with that media item.

    If you want to have an adhoc alternative text for each media-item (in the richtext-editor), then you could add a new ‘text’ parameter to your Macro and use that in the XSLT.

    If you need further help, please post a message on the Our Umbraco forums… we’re always happy to help over there!

    http://our.umbraco.org/

    Cheers, Lee.

  5. Hey Lee,

    Good stuff! How will this change with the new v4.1 xml format? Or are media items unaffected by this?

    Cheers,

    David

  6. Hi David,

    I haven’t heard anything about the XML schema for GetMedia in v4.1 but my guess would be that it would follow the content schema, with docType and property aliases as the tag names. Might be worth keeping an eye on the CodePlex commits for v4.1? ;-)

    Cheers, Lee.

  7. Hey Lee,

    An update to the new schema would be mega-handy – still use this snippet reference loads, but working much more with 4.5 schema now.

    Cheers

  8. Pingback: How to use umbraco.library GetMedia in XSLT for Umbraco v4.5 « Lee Kelleher’s Weblog

  9. I’m having trouble with this.. why isn’t this working?

    I’m trying to pass in the nodeId (as selected from a mediapicker) as the mediaId param of the macro, but it isn’t working :(
    Any suggestions would be much appreciated.

  10. Hi Colm, Pedro,

    I’m thinking that you are using the new XML schema for Umbraco. My example in this blog post uses the legacy XML scheme (which was current when I wrote this post in 2009).

    Take a look at my post for GetMedia in Umbraco 4.5+: http://blog.leekelleher.com/2010/08/11/how-to-use-umbraco-library-getmedia-in-xslt-for-umbraco-v4-5/

    Any specific problems, please post on the Our Umbraco forum, there are a lot of people wanting to help there!

    Cheers, Lee.