Copied to clipboard
  • Sam 209 karma points
    Feb 27, 2011 @ 22:12
    Sam
    0

    Making an image gallery

    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.

     

  • Jan Skovgaard19239 karma points admin mvp c-trib
    Feb 27, 2011 @ 22:28
    Jan Skovgaard
    0

    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

  • Sam209 karma points
    Feb 27, 2011 @ 22:32
    Sam
    0

    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 :)

    Sam.

  • Jan Skovgaard19239 karma points admin mvp c-trib
    Feb 27, 2011 @ 22:36
    Jan Skovgaard
    0

    Hi Sam

    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.

    /Jan

  • Chriztian Steinmeier6737 karma points admin mvp c-trib
    Feb 28, 2011 @ 09:06
    Chriztian Steinmeier
    1

    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 

  • Sam209 karma points
    Feb 28, 2011 @ 09:36
    Sam
    0

    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,

    Sam.

  • Chriztian Steinmeier6737 karma points admin mvp c-trib
    Feb 28, 2011 @ 12:33
    Chriztian Steinmeier
    0

     

    Hi Sam,

    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...

    /Chriztian

     

  • Jeroen Breuer9854 karma points admin mvp c-trib
    Feb 28, 2011 @ 12:44
    Jeroen Breuer
    0

    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

  • Sam209 karma points
    Feb 28, 2011 @ 13:20
    Sam
    0

    @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 :)

    Sam.

  • Sam209 karma points
    Feb 28, 2011 @ 18:49
    Sam
    0

    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.

    Sam.

  • Chriztian Steinmeier6737 karma points admin mvp c-trib
    Feb 28, 2011 @ 20:44
    Chriztian Steinmeier
    0

    Hi Sam,

    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).

    /Chriztian

  • Sam209 karma points
    Feb 28, 2011 @ 21:16
    Sam
    0

    Thanks Chriztian,

    Unfortunately, I'm getting an error on this part of the code, line 43 character 17 which is in the link:

              <a href="{umbracoExtension.library:NiceUrl($currentPage/@id)}?img={@id}">
                <img src="{concat(substring-before(umbracoFile, $ext), '_thumb', $ext)}" alt="{@nodeName}" />
              </a>

    Sorry I can't be of much assistance knowing why it's incorrect or sorting it out.

    Sam.

     

     

     

  • Sam209 karma points
    Feb 28, 2011 @ 21:54
    Sam
    0

    ...and if I try skip testing and save:

    Error reading XSLT file: \xslt\listPics.xslt

    Sam.

  • Chriztian Steinmeier6737 karma points admin mvp c-trib
    Feb 28, 2011 @ 22:37
    Chriztian Steinmeier
    0

    Hi Sam,

    Sorry 'bout that - a typo on my part - umbracoExtension.library should of course be umbraco.library

    Let me know of anything else-

    /Chriztian

  • Sam209 karma points
    Feb 28, 2011 @ 22:49
    Sam
    0

    Hi Chriztian,

    Thanks for your help, I actually tried that and renamed accordingly earlier. The result of the xslt is clicking on a gallery gives me the pics, clicking on the pics gives me a url like this:

    www.mysite.com/pictures/htc-desire-pics.aspx?img=1246

    ...but no larger image! (awwww!) Just an empty space where template 'Image' should have loaded. Sorry to be a pest!

    I will look over the xslt again to see if I can spot what's wrong. Thanks again :)

    Sam.

     

  • Chriztian Steinmeier6737 karma points admin mvp c-trib
    Feb 28, 2011 @ 23:13
    Chriztian Steinmeier
    1

    Hi Sam,

    Sorry for rushing half-baked code out the door like this :-)

    The apply-templates for the Image fails (of course - Duh! Chriz) because we haven't even fetched the XML from Media yet at that point :-) 

    Try these replacements for the "/" and "picturesFolder" templates:

    <xsl:template match="/">
        <!-- Process the picturesFolder (if one is specified) -->
        <xsl:apply-templates select="$currentPage/picturesFolder[normalize-space()]" />
    </xsl:template>
    
    <!-- Template for the property -->
    <xsl:template match="picturesFolder">
        <xsl:choose>
            <xsl:when test="$imgId">
                <!-- Process a single Image -->
                <xsl:variable name="mediaImage" select="umbraco.library:GetMedia($imgId, false())" />
                <xsl:apply-templates select="$mediaImage[not(error)]" mode="single" />
            </xsl:when>
            <xsl:otherwise>
                <!-- Process the folder -->
                <xsl:variable name="mediaFolder" select="umbraco.library:GetMedia(., true())" />
                <xsl:apply-templates select="$mediaFolder[not(error)]" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>   
    
    - And if that works, let's get the full code posted "for future reference" as they say...

    /Chriztian

  • Sam209 karma points
    Feb 28, 2011 @ 23:39
    Sam
    0

    What can I say? Spot on!

    Thanks a bunch Chriztian, I'll buy you a beer one day :)

    In case anyone wants an image gallery made from bulk uploading into the media section, then here ya go:

    <?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="/">
            <!-- Process the picturesFolder (if one is specified) -->
            <xsl:apply-templates select="$currentPage/picturesFolder[normalize-space()]" />
              </xsl:template>
            
    <!-- Template for the property -->
    <xsl:template match="picturesFolder">
            <xsl:choose>
                    <xsl:when test="$imgId">
                            <!-- Process a single Image -->
                            <xsl:variable name="mediaImage" select="umbraco.library:GetMedia($imgId, false())" />
                            <xsl:apply-templates select="$mediaImage[not(error)]" mode="single" />
                    </xsl:when>
                    <xsl:otherwise>
                            <!-- Process the folder -->
                            <xsl:variable name="mediaFolder" select="umbraco.library:GetMedia(., true())" />
                            <xsl:apply-templates select="$mediaFolder[not(error)]" />
                    </xsl:otherwise>
            </xsl:choose>
    </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="{umbraco.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>

    Sam.

Please Sign in or register to post replies

Write your reply to:

Draft
Our.umbraco.org is the community mothership for Umbraco, the open source asp.net cms. With a friendly forum for all your questions, a comprehensive documentation and a ton of packages from the community.