Search

I have a page which displays multiple images.

These images can be either landscape or portrait format.

If they are all landscape format, I'd like them to have a certain width (e.g. 100% screen width).

However, if any of the images are portrait format, I'd like all of the images to have a smaller width (e.g. %66 screen width).

How can I use the images' meta information to find out if any of them have shorter width than height?

You can use a choose statement. Something like:

<xsl:choose>
    <xsl:when test="image/meta/width &gt; image/meta/height">
        <img class="landscape" ...
    </xsl:when>
    <xsl:otherwise>
        <img class="portrait" ...
    </xsl:otherwise>
</xsl:choose>

Thanks, Stuart. I don't think that addresses my problem fully, though.

If I use your code and I have some portrait images and some landscape images, they will appear at different widths, whereas I want it such that if any of the images are portrait, then all of them should be the same width.

I would add a conditional class like Stu suggests, but agree that the logic could be seen as flawed there. It all depends on the context of where it is used.

Can you provide some XML to aid us in helping you out? I have the solution, but the forum rules are quite clear and I can't tailor it for you without seeing your XML.

Thanks, designermonkey.

Here's some xml: https://gist.github.com/3800708

I came up with a solution, but I'm not convinced it's the most parsimonious:

<xsl:template match="project/entry/images/item">
<!-- check if *any* of the images are portrait format -->
<xsl:variable name="smallwidth">
    <xsl:choose>
        <xsl:when test="*[(/data/project/entry/images/item/image/meta/@width &lt; /data/project/entry/images/item/image/meta/@height)]">
            <xsl:text>1</xsl:text>
        </xsl:when>
        <xsl:otherwise>
            <xsl:text>0</xsl:text>
        </xsl:otherwise>
    </xsl:choose>
</xsl:variable>

<div class="largeimagecontainer">
    <xsl:choose>
        <!-- if there were *any* portrait format images, make all images span two columns -->
        <xsl:when test="$smallwidth = '1'">
            <img src="{$root}/image/1/585/0/0/assets/images/{image/filename}" width="66%" height="auto" />
        </xsl:when>
        <!-- otherwise, they were all landscape, so make 'em all span three columns -->
        <xsl:otherwise>
            <img src="{$root}/image/1/885/0/0/assets/images/{image/filename}" width="100%" height="auto" />
        </xsl:otherwise>
    </xsl:choose>
</div> <!-- end .largeimagecontainer -->
    </xsl:template>

I'd love to hear if there's a more elegant way of tackling it.

I believe the following should also work:

<xsl:template match="/">
    <xsl:apply-templates select="data/project/entry/images/item" />
</xsl:template>

<xsl:template match="project/entry/images/item">
    <img src="/image/1/885/0/0/assets/images/{image/filename}" width="100%" height="auto" />
</xsl:template>

<xsl:template match="project/entry/images/item[../../../entry/images/item/image/meta/@width &lt; ../../../entry/images/item/image/meta/@height]">
    <img src="/image/1/585/0/0/assets/images/{image/filename}" width="66%" height="auto" />
</xsl:template>

It makes use of the fact that project/entry/images/item[../../../entry/images/item/image/meta/@width &lt; ../../../entry/images/item/image/meta/@height] matches all images in all entries and compares their aspect ratio. So you're implicitely doing a comparison on the whole set while being in the context of each single image.

Nice!

parsimonious

I had to look that up.

Anyhoo, basically the same, although I like to be a little more verbose for readability, and don't be afraid of templates and splitting code out. It's better to remain in context of the current node than start the crawl from the root for things like this.

<xsl:template match="project/entry">
    <xsl:variable name="has-portrait">
        <xsl:choose>
            <xsl:when test="images/item/image/meta/@width &lt; images/item/image/meta/@height">
                <xsl:value-of select="true()"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="false()"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>

    <div class="largeimagecontainer">
        <xsl:apply-templates select="item">
            <xsl:with-param name="has-portrait" select="$has-portrait"/>
        <xsl:apply-templates>
    </div>
</xsl:template>

<xsl:template match="project/entry/item">
    <xsl:param name="has-portrait"/>
    <xsl:variable name="width">
        <xsl:choose>
            <xsl:when test="$has-portrait">
                <xsl:text>66%</xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text>100%</xsl:text>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>

    <img src="{$root}/image/1/885/0/0/assets/images/{image/filename}" alt="{title/text()}" width="{$width}" height="auto"/>

</xsl:template>

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details