Search

I already put this in the bug tracker but I want to see if anyone can provide a quick fix for this.

I added a couple of images to one of my posts and they are somehow being attached to every post that is on the home page. I have my Symphony set up to show 4 posts on the home page. If you go to the individual article, those images are not there, only for the article that the images are attached to.

Hhere's the code that is calling the images now in get-article.xsl:

<xsl:copy-of select="body/*[1]"/>
<xsl:apply-templates select="/data/article-images[entry]"/>
<xsl:copy-of select="body/*[position() &gt; 1]"/>

This is not a bug. The default ensemble is only designed to accommodate a single post on its home page. You'll need to make changes to the XSLT to achieve your desired outcome. Take a look at the key() function.

Thanks for the link Lewis but this XSLT business is still way over my head. I attempted to try it but I don't really know where to start. I'm looking over other articles and tutorials right now. For now, I just left it at 1 post on the home page.

In my symphony project I find it quite common to have an 'overview'-page, where some section linked entries have to be grouped by the 'parent'-entry, so the key() function comes in handy.

But I have problems using it. I try to use it with xsl:apply-templates, where for example I have galleries that can have several section-linked pictures. This is in get-galleries.xsl, from where I call get-pictures.xsl. The parameter '$gallery' contains the value of a gallery's title/@handle:

<xsl:apply-templates select="entry">
  <xsl:with-param name="gallery" select="$gallerie"/>
</xsl:apply-templates>

Defintion of the key in get-pictures.xsl:

<xsl:key name="gallery-key" match="/data/pictures/entry" use="gallery/@link-handle"/>

Now I try to limit the pictures by using the key:

<xsl:template match="key('gallery-key', '$gallery')">

But it seems like the parameter $gallery is not evaluated, the templates do not match.

Any hints on how to use key()?

The key function is not evaluating your parameter because you have it surrounded in single quotes. Try:

<xsl:template match="key('gallery-key', $gallery)">

Also, change key's match attribute to only name the element you want to match i.e.

<xsl:key name="gallery-key" match="entry" use="gallery/@link-handle"/>

Leaving out the single quotes throws an error:

XSLTProcessor::importStylesheet(): xsltCompilePattern : failed to compile 'key('gallery-key', $gallery)'

Can you provide some XML and additional XSLT?

The following doesn't actually make sense to me. Did you mean apply-templates?

<xsl:template match="key('gallery-key', $gallery)">

Posted the XML and XSLT at http://pastie.org/220061.

I will post an example with your solution shortly.

Below is a typical use of the key element to associate one or more images with an entry when there are multiple entries on a page. You do not need to utilize the key element when only displaying a single entry because you can filter the images' data source by a URL parameter (i.e. $gallerie) to only return images for that entry.

<xsl:key name="bilder-by-gallerie" match="entry" use="gallerie/@link-handle" />

<xsl:template match="data">
    <xsl:choose>
        <xsl:when test="$gallerie = not('')">
            <!- Key() not necessary if you filter your data sources by the URL parameter $gallerie ->
            <xsl:apply-templates select="gallerien/entry" mode="full" />
        </xsl:when>
        <xsl:otherwise>
            <!-  Display summary of galleries. Display the first image in every gallery ->
            <xsl:apply-templates select="gallerien/entry" mode="brief" />
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template match="gallerien/entry" match="brief">
    <h2><xsl:value-of select="titel" /></h2>
    <!- Give our key bilder-by-gallerie the id of our gallery to grab all images that have a section link with the same id ->
    <xsl:for-each select="key('bilder-by-gallerie', @id)">
        <a href="{$workspace}{bild/@path}/{bild}" rel="lightbox[{gallerie/@link-handle}]" title="{beschreibung}">
           <img src="{$root}/image/2/140/88/2{bild/@path}/{bild/filename}" title="{beschreibung}"/>
        </a>
    </xsl:for-each>
</xsl:template>

The full template for a gallery does not utilize keys so I did not do the template for full mode (post if you need help with it).

Sorry Lewis, I don't get it. The code you posted doesn't work for me. And there are a few things in it I don't quite understand.

1: The key matches an 'entry'-node, and then uses the link-handle attribute of the child node 'gallerie'. I don't understand which node this should be. I'm sometimes getting confused what the context node is, so in this case. I thought the node I am interested in would be /data/bilder/entry/gallerie/@link-handle.

2: In the for-each-loop, you give the key an id to test on. @link-handle is a name (string?), @id is a number. How does this match?

But thanks for your replies anyway, perhaps I should try some more to get it to work.

I'm still confused where I sould use for-each-loops, call-template or apply-template.

In my current sollution, I iterate through all pictures with apply-templates but display only those who matches the gallery from where the template was called like this:

<xsl:template match="bilder" mode="brief">
  <xsl:param name="gallerie"/>
  <xsl:apply-templates select="entry" mode="brief">
    <xsl:with-param name="gallerie" select="$gallerie"/>
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="bilder/entry" mode="brief">
  <xsl:param name="gallerie"/>
  <xsl:if test="$gallerie = gallerie/@link-handle">
    <a href="{$workspace}/bilder/{bild}" rel="lightbox[{gallerie/@link-handle}]" title="{beschreibung}">
      <img src="{$root}/image/2/140/88/2/bilder/{bild}" title="{beschreibung}"/>
    </a>
  </xsl:if>
</xsl:template>

This works but is not flexible enough. You allways iterate through all pictures belonging to the gallery, I can't think of a way to limit the number of the displayed pictures. I thought perhaps this would work with the key()-trick. What I want is: Just display the first four pictures belonging to a gallrey.

Thanks again!

Okay, I've got It working, including the limitation of the pictures!

I just changed the @id to titel/@handle so that it matches the gallerie/@link-handle and used a predicate. Here are the changes I made to Lewis' code:

<xsl:template match="gallerien/entry" match="brief">
    <h2><xsl:value-of select="titel" /></h2>
    <!- Give our key bilder-by-gallerie the title handle of our gallery to grab all images that have a section link with the same link handle  ->
    <xsl:for-each select="key('bilder-by-gallerie', titel/@handle)[position() &lt; 5]">
        <a href="{$workspace}{bild/@path}/{bild}" rel="lightbox[{gallerie/@link-handle}]" title="{beschreibung}">
           <img src="{$root}/image/2/140/88/2{bild/@path}/{bild/filename}" title="{beschreibung}"/>
        </a>
    </xsl:for-each>
</xsl:template>

Thank you Lewis. And: I love this forum! You are all doing a great job.

In the for-each-loop, you give the key an id to test on. @link-handle is a name (string?), @id is a number. How does this match?

Nice catch, sorry for the mistake. Yes, they too must match so you can use either the handle or the id. I have a personal preference for using IDs but it doesn't matter as long as there is a relationship.

Thank you Lewis. And: I love this forum! You are all doing a great job.

Glad you got it working!

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