Search In
Learn from 350 other Umbracians at the annual Umbraco Conference - CodeGarden '13. More than twenty high quality sessions, open spaces, hackathons and social events you'll remember. Not to be missed! Less than 25 tickets left - get yours now!
Hi everyone,
I'm trying to make a simple image gallery. I have a doctype which has a media picker to select a root folder from the media section alias 'picturesFolder'. The code is as follows:
<?xml version="1.0" encoding="utf-8" ?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:umbraco.library="urn:umbraco.library" exclude-result-prefixes="umbraco.library"> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" /> <xsl:param name="currentPage" /> <xsl:template match="/"> <!-- This makes sure to only do something if there is a value in the property --> <xsl:apply-templates select="$currentPage/picturesFolder[normalize-space()]" /> </xsl:template> <!-- Template for the property --> <xsl:template match="picturesFolder"> <!-- Fetch the media XML and start the processing --> <xsl:variable name="mediaFolder" select="umbraco.library:GetMedia(., true())" /> <!-- ...but only if we did not get an error back --> <xsl:apply-templates select="$mediaFolder[not(error)]" /> </xsl:template> <!-- Template for the root folder --> <xsl:template match="node[@nodeTypeAlias = 'Folder']/node"> <h3><xsl:value-of select="@nodeName" /></h3> <ul> <!-- Render all Files or (sub-)Folders in this folder --><xsl:apply-templates select="node[@nodeTypeAlias = 'File'] | node[@nodeTypeAlias = 'Folder']" /> </ul> </xsl:template> <!-- Template for a file --> <xsl:template match="node[@nodeTypeAlias = 'File']"><li><a href="{data[@alias = 'umbracoFile']}"> <xsl:value-of select="@nodeName" /></a></li> </xsl:template></xsl:stylesheet>
Thanks to Chriztian for helping me out with this a while back but I want to develop this into a gallery. I am having trouble converting this to 4.6.1 schema, could anyone help? The <li> item at the bottom will be an <img> when I'm done rather than just a text link.
Does this:
<xsl:apply-templates select="node[@nodeTypeAlias = 'File'] | node[@nodeTypeAlias = 'Folder']" />
simply change to this in the new schema?
<xsl:apply-templates select="File | Folder" />
So far my output is like this:
media/1237/20100503_123326_.jpg64048026171jpg/media/1238/IMG_0136.jpg36048089463jpg/media/1239/Image0255.jpg48064037951jpg/media/1240/Photo001.jpg24483264626198jpg
rather than the images showing, which is a good start! :)
Also, do I use the word 'Image' instead of 'File' too or is file generic and covers all types of file?
Thanks in advance :)
Sam.
Hi Sam
Yes, use "Image", since it's an Image gallery you're building. By using file you will only get files like pdf, word documents etc. and no images. So you're spot on with that.
This could be me being tired...but are you getting the output above from the code you have now? Because in that case all you really need to do is replace the <xsl:value-of select="@nodeName" /> with <img src="{data[@alias = 'umbracoFile']}" alt="" />, which should render the image for you if I'm not mistaken? :-)
Hope this helps.
/Jan
Thanks Jan,
I forgot to mention the output has NO styling on it at all, so it isn't even rendered in a list. And also:
media/1237/20100503_123326_.jpg64048026171jpg
would not be the path to my image:
media/1237/20100503_123326_.jpg <----- this would be
I'm pretty tired myself, will have another crack at it tomorrow :)
Ehm, if the above outputs something I guess it is rendered as an unstyled list? And the path shoud be correct asuming that the XSLT you have posted is outputting the image paths etc.
But maybe we could both use a bit of sleep ;-)
If the galleri is "just" going to cycle I recommend you consider using the cycle plugin for jQuery. I've used it a couple of times and it's working like a charm :-)
Sleep well.
Hi Sam,
Here's an updated version - easier to read and yes, you just need a template for the Image elements, to have them render in some way:
<?xml version="1.0" encoding="utf-8" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:umbraco.library="urn:umbraco.library" exclude-result-prefixes="umbraco.library"> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" /> <xsl:param name="currentPage" /> <xsl:template match="/"> <!-- This makes sure to only do something if there is a value in the property --> <xsl:apply-templates select="$currentPage/picturesFolder[normalize-space()]" /> </xsl:template> <!-- Template for the property --> <xsl:template match="picturesFolder"> <!-- Fetch the media XML and start the processing --> <xsl:variable name="mediaFolder" select="umbraco.library:GetMedia(., true())" /> <!-- ...but only if we did not get an error back --> <xsl:apply-templates select="$mediaFolder[not(error)]" /> </xsl:template> <!-- Template for the root folder --> <xsl:template match="Folder"> <h3><xsl:value-of select="@nodeName" /></h3> <ul> <!-- Render all Images, Files or (sub-)Folders in this folder --> <xsl:apply-templates select="Image | File | Folder" /> </ul> </xsl:template> <!-- Template for an Image (thumbnail liked to fullsize)--> <xsl:template match="Image"> <xsl:variable name="ext" select="concat('.', umbracoExtension)" /> <a href="{umbracoFile}"> <img src="{concat(substring-before(umbracoFile, $ext), '_thumb', $ext)}" alt="{@nodeName}" /> </a> </xsl:template> <!-- Template for a file --> <xsl:template match="File"> <li> <a href="{umbracoFile}"> <xsl:value-of select="@nodeName" /> </a> </li> </xsl:template> </xsl:stylesheet>
/Chriztian
Hi Chriztian,
That's brilliant thanks :) you helped me with this a while ago, it was for a list of file downloads, I figured the same could be applied to an image gallery. Could you do me a huge favour and explain the following:
<!-- Template for an Image (thumbnail liked to fullsize)--> <xsl:template match="Image"> <xsl:variable name="ext" select="concat('.', umbracoExtension)" /> <a href="{umbracoFile}"> <img src="{concat(substring-before(umbracoFile, $ext), '_thumb', $ext)}" alt="{@nodeName}" /> </a> </xsl:template>
I was going to ask how to link to a fullsize image after getting the gallery working, but you seem to be one step ahead of me. Any chance you could briefly explain the above code? I kind of get it but not fully. I have used concat and substring in the last few weeks but never substring-before.
How do you set the size of the thumbnail? Say I wanted to add a property to the doctype alias 'thumbnailSize', which would be a number.
Also, I wanted the fullsize image to display in a template.
What I get now is: gallery 1, gallery 2, gallery 3 --->>>>> (click on one) list of pics from gallery 1 --->>>>> (click on one) single pic from gallery 1 (single pic in browser - no template).
<a href="{umbracoFile}"> <img src="{concat(substring-before(umbracoFile, $ext), '_thumb', $ext)}" alt="{@nodeName}" /> </a>
I'm not sure how you would go about this. Can the image be loaded into a new template via the xslt - maybe by altering the link above? Or loaded into the same template as the thumbnails, replacing the thumbnails with the single image, (query string) like on news pages, page1, page2 etc? I wanted the single image to be on a page of it's own (within a template) but I can see each single image has no doctype or associated template.
ie ww.mysite.com/pictures/phone-pictures-1/picture-of-me-looking-at-pc-with-confused-face.aspx
lol, does this make sense?
Thanks and best regards,
The substring-before() function looks for the first occurrence of a string (second argument) within another string (first argument) - both arguments can be XPaths in which case the actual value used will be equivalent of string(XPath) (or what you'd get with <xsl:value-of select="XPath" />)
I start by creating a variable ($ext) to hold the concatenation of a dot and the file's extension (found in the umbracoExtension child of a File or Image). I set the src of the img to the concatenation of everything in the fullsize image's URL before the $ext, the string '_thumb' and the $ext string. (The automatic thumbnails are generated with "_thumb" appended to the name.)
Regarding the size of the thumbnails: The Image type uses the Upload datatype and if you go to the Developer section in Umbraco and edit that datatype you can actually set max. width/height values for any autogenerated thumbnail(s).
(Another option would be to use the awesome Image Cropper datatype for this, 'coz then you'd be able to define the exact crop of the fullsize image to use as a thumbnail.) But that warrants a separate forum post I'd say...
If you want a very simple image galery example you can watch this video: http://screenr.com/TEY. It uses the Digibiz Advanced Media Picker.
Jeroen
@Jeroen: thanks, I will watch that :)
@Chriztian: thanks for the explanation. I am ideally looking for a way to set the thumbnail size (only need to set width) in the doctype (and full size width). I used mtt gallery before now so there is a way to do this, I will look into it further. I will also look into the image cropper datatype.
However, the big problem I have is I also need the (zoomed) image to display inside a template within my site. It's no good them opening up in a blank browser window.
Any ideas? Thanks for the help everyone :)
I've been playing with this for awhile longer today. Is the only way to have a single image display on a page after clicking the thumbnail by having to create an image node in the content area (so it then has a doctype and template associated with it), ie:
Content
Pictures (doctype 'listGalleries')
- Gallery 1 (doctype 'listPics')
---- Picture 1 (doctype 'showPic')
---- Picture 2 (doctype 'showPic')
is this the only way to achieve this? Would take an awful long time to add 100 nodes to make a gallery one image at a time.
Still trying to find a decent solution to this, I don't want a pop up or a lightbox, just a full size image on the page, but in my template.
Maybe I need the thumbnails to link to a page like:
www.mysite.com/pictures/gallery-1/showpic.aspx?imgID=112
where the image with the ID of 112 will be displayed on my page. I'm not sure how to achieve this.
No need to create documents for every image - adding a moded template for displaying a single Image (by id form QueryString) and then linking the thumbnail to the same page, adding the querystring parameter should do the trick. Like this:
<?xml version="1.0" encoding="utf-8" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:umbraco.library="urn:umbraco.library" exclude-result-prefixes="umbraco.library"> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" /> <xsl:param name="currentPage" /> <!-- Grab QueryString parameter (if present) --> <xsl:variable name="imgId" select="umbraco.library:RequestQueryString('img')" /> <xsl:template match="/"> <!-- If an image id was specified in queryString, display that image --> <xsl:apply-templates select="Image[@id = $imgId]" mode="single" /> <!-- Alternatively, display the thumbnails from picturesFolder (if specified) --> <xsl:apply-templates select="$currentPage/picturesFolder[normalize-space()][not($imgId)]" /> </xsl:template> <!-- Template for the property --> <xsl:template match="picturesFolder"> <!-- Fetch the media XML and start the processing --> <xsl:variable name="mediaFolder" select="umbraco.library:GetMedia(., true())" /> <!-- ...but only if we did not get an error back --> <xsl:apply-templates select="$mediaFolder[not(error)]" /> </xsl:template> <!-- Template for the root folder --> <xsl:template match="Folder"> <h3><xsl:value-of select="@nodeName" /></h3> <ul> <!-- Render all Images, Files or (sub-)Folders in this folder --> <xsl:apply-templates select="Image | Folder" /> </ul> </xsl:template> <!-- Template for an Image (thumbnail linked to fullsize view of image)--> <xsl:template match="Image"> <xsl:variable name="ext" select="concat('.', umbracoExtension)" /> <a href="{umbracoExtension.library:NiceUrl($currentPage/@id)}?img={@id}"> <img src="{concat(substring-before(umbracoFile, $ext), '_thumb', $ext)}" alt="{@nodeName}" /> </a> </xsl:template> <!-- Template for displaying single Image --> <xsl:template match="Image" mode="single"> <div class="image"> <img src="{umbracoFile}" width="{umbracoWidth}" height="{umbracoHeight}" alt="{@nodeName}" /> </div> </xsl:template> </xsl:stylesheet>
What I usually do then, is add a JavaScript Lightbox component which Hijacks the link, and displays the single image in an overlay of some sorts, using Ajax...
(The root template ("/") could just as easily be created with a choose/when/otherwise construct - I just like to do the mutually exclusive thing instead).