x First time here? Check out the FAQ
  • Avatar184posts209karma

    Making an image gallery

    Sam started this topic February 27, 2011 @ 10:12, Go directly to the topic solution

    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 Skovgaard posted this reply February 27, 2011 @ 10:28

    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


  • Avatar184posts209karma
    Comment with ID: 66979
    Sam posted this reply February 27, 2011 @ 10:32

    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 Skovgaard posted this reply February 27, 2011 @ 10:36

    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 Steinmeier posted this reply February 28, 2011 @ 09:06

    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 


  • Avatar184posts209karma
    Comment with ID: 67017
    Sam posted this reply February 28, 2011 @ 09:36

    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 Steinmeier posted this reply February 28, 2011 @ 12:33

     

    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 Breuer posted this reply February 28, 2011 @ 12:44

    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


  • Avatar184posts209karma
    Comment with ID: 67103
    Sam posted this reply February 28, 2011 @ 01:20

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


  • Avatar184posts209karma
    Comment with ID: 67191
    Sam posted this reply February 28, 2011 @ 06:49

    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 Steinmeier posted this reply February 28, 2011 @ 08:44

    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


Pages:

Please login or Sign up To post replies