Search

guys, you have a great community here!

i started to read about symphony 3 days ago and i must say that for a designer it’s the most easy cms to use and customize. i know some php but xslt is very different and it will take some for me time to learn it… so i need some help.

this is is what i made: a portfolio website that has 3 types of content, categories, cases and images. everything works fine, case are associated with categories and images with the cases.

each case can have multiple images.

what i want to do: i’m working at the homepage, where i want to show teasers of some cases, title + description + image

what i don’t know how to do it (and i hope you can help me with..)

-i want to display only the first image

when you view a case i use this code: xsl:for-each select=”images/item” to start a loop.

so, how do I say “only-for-first”?

second:

this is how i display the description that is a text field: xsl:value-of select=”description”/

-i want to truncate it. let’s say 200 characters of 20 words.

thank you very much and sorry for my english….

[EDIT]: ratdoesit had some severe problems posting here. We talked about this via email. Maybe the team is working on the website. Maybe it was the code which was posted by ratdoesit.

[EDIT 2]: Well, it feels like there are severe things going on under the hood of the forum… We should wait.

What exactly is happening?

ratdoesit started the thread, but the post was displayed as empty. In the RSS feed I saw the following:

<p>guys, you have a great community here!</p> <p>i started to read about symphony 3 days ago and i must say that for a designer it&#8217;s the most easy cms to use and customize. i know some php but xslt is very different and it will take some for me time to learn it&#8230; so i need some help.</p> <p>this is is what i made: a portfolio website that has 3 types of content, categories, cases and images. everything works fine, case are associated with categories and images with the cases.</p> <p>each case can have multiple images.</p> <p>what i want to do: i&#8217;m working at the homepage, where i want to show teasers of some cases, title + description + image</p> <p>what i don&#8217;t know how to do it (and i hope you can help me with..)</p> <p>*i want to display only the first image</p> <p>when you view a case i use this code: <xsl:for-each select="images/item"> to start a loop.</p> <p>so, how do I say &#8220;only-for-first&#8221;?</p> <p>second:</p> <p>this is how i display the description that is a text field: <xsl:value-of select="description"/></p> <p>*i want to truncate it. let&#8217;s say 200 characters of 20 words.</p> <p>thank you very much and sorry for my english&#8230;.</p>

I thought that maybe the HTML entities (like &#8217;) had broken the post. While we talked via email, the post suddenly appeared. (I am not sure if ratdoesit edited the post, but you might check this in the forum admin).

ratdoesit worked on Safari, so there shouldn’t be any browser-related problems. I also informed ratdoesit that Markdown is preferred over HTML.

Maybe there has been a problem in XSLT or in the forum backend. But it works for him now.

so, how do I say “only-for-first”?

instead of using a for-each loop, you can do an apply-templates and limit to one:

<xsl:apply-templates select="images/item[1]" />

and then you can have a matched template if you want to do something specifically for the first one:

<xsl:template match="images/item[1]">
    <!-- do stuff in here -->
</xsl:template>

I suppose you can do the same logic on a for-each, but i think (not positive though) this method would be more efficient in an apply-templates.

Another common way to limit your output would be to modify your datasource to only 1 entry (I am not sure this would apply in your case however). Also, in order to output all the HTML in your description field, you can use

<xsl:copy-of select='description/*' />

which will copy all the HTML elements and text. You’ve probably noticed that <value-of /> will just give the text.

There are also a few truncate XSLT utilities you can try.

thank you for your help guys,

so, i tried to make exactly how wtdtan said:

<xsl:apply-templates select="images/item[1]" />

        <xsl:template match="images/item[1]">
                <img><xsl:attribute name="src">
                    <xsl:value-of select="$root"/>
                    <xsl:text>/image/1/460/0</xsl:text>
                    <xsl:value-of select="file/@path"/>
                    <xsl:text>/</xsl:text>
                    <xsl:value-of select="file/filename"/>
                </xsl:attribute></img>          
          </xsl:template>

and i got this error:

XSLTProcessor::importStylesheet(): element template only allowed as child of stylesheet XSLTProcessor::transformToXml(): No stylesheet associated to this object

also i tried to limit the loop to first element with [1] and it worked…

but i don’t feel it to be a good way

what do you think?

That <xsl:template match="images/item[1]"> block needs to be outside of the xsl:template block that contains the apply-templates element.

oh, that was fast, now is working, thanks!

because i have 2 places on the same page where i want to display only the first image of some entries but at different sizes, i can’t use this way:

 <xsl:template match="images/item[1]">
                <img><xsl:attribute name="src">
                    <xsl:value-of select="$root"/>
                    <xsl:text>/image/1/460/0</xsl:text>
                    <xsl:value-of select="file/@path"/>
                    <xsl:text>/</xsl:text>
                    <xsl:value-of select="file/filename"/>
                </xsl:attribute></img>          
          </xsl:template>

the jit size of first image is overwrited when i declare the template for the smaller images…. i guess i can’t change it’s name from “images/item[1]” to lets say “small_images” and declare inside the second sizes that Jit should use.

my xml looks like this:

<entry>
      <images>
           <item></item>
           <item></item>
      </images>
</entry>
<entry>
      <images>
           <item></item>
      </images>
</entry>
<entry>
      <images>
           <item></item>
           <item></item>
           <item></item>
      </images>
</entry>

but, i found another way on google that works prety fine for me. but before i use it i want to get a confirmation from a real developer if it’s ok.

<xsl:for-each select="images/item">
    <xsl:if test="position() = 1"> 
          bla bla
     </xsl:if>
 </xsl:for-each>

so? what do you say?

You could use modes to allow you to template the image more than once.

<xsl:apply-templates select="images/item[1]" mode="thumbnail"/>
...
<xsl:apply-templates select="images/item[1]" mode="full-size"/>

and then…

<xsl:template match="images/item[1]" mode="thumbnail">
...
</xsl:template>

<xsl:template match="images/item[1]" mode="full-size">
...
</xsl:template>

yeah! that’s better, thanks!

I think what Craig means is:

<xsl:apply-templates select="images/item[1]" mode="thumbnail"/>
...
<xsl:apply-templates select="images/item[2]" mode="full-size"/>

and then…

<xsl:template match="images/item" mode="thumbnail">
...
</xsl:template>

<xsl:template match="images/item" mode="full-size">
...
</xsl:template>

Except that he wants to use the first image more than once.

Ah, I see, so the first part was right. The second, however, was too special, wasn’t it? The strength of modes lies in using them in a more generic manner.

i want to use the first image every time… so [1] is correct

OK, OK, I give up.

But just in case you ever want to use one of the modes for another image…

:-)

:) yep actualy you just told me how to make an “select teaser image” drop down option for each entry. thanks!

cheers!

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