Search

I know there are some other truncate utilities floating around, but here's my take on it. This truncate template will try to truncate to an exact word, if that's not possible it cuts at the exact length specified.

Here's a rundown on the parameters:

  • $length: Should be pretty obvious.
  • $tolerance: How long a word can be, over the $length and not be chopped in half.
  • $suffix: The string to append to the end of the truncated value.
  • $delimiters: A comma separated list of characters that to match spaces between words.

Usage is as follows:

<xsl:call-template name="truncate">
    <xsl:with-param name="value" select="p[1]" />
    <xsl:with-param name="length" select="200" />
</xsl:call-template>

You can find the code on pastie, let me know what you think :)

I accidentally called this a 'trim' function before, really it's a truncate function.

Rowan this is so useful, thank you!

As an aside — is pastie the standard for posting code? I considered pasting my snippets there but wasn't sure how permanent it is going forward.

Hmmm... How about snipt or Github's Gist? Your snippets then will be associated with an account for long-term management, you can set them to public or private, and at least one of them does versioning, if not both...

Trying to figure out how to get this to retain markup. Will report back...

Trying to figure out how to get this to retain markup. Will report back...

Let us know :-)

No luck with this so far. In case anyone else wants to try it, this is what my thought/trial process has been...

Rather than deal with all the complications of trying to retain the markup during the actual truncation procedure (getting it to not count those characters, getting it to not ditch necessary closing tags, etc.), I figured let's just store two params: one for the original value-with-markup ($value), and one for the string()-ified value ($valuestring). Run the truncation procedure on $valuestring, and if it truncates the data, then store that in a third param, ($truncated). Then you just do some sort of recursion that runs through each element in the original value ($value/*) and does a str:replace on $truncated searching for $value/*[n]/text() and replacing it with $value/*[n]/node(). Not sure if that even makes sense, but it did to me at the time ;) Anyway, wasn't able to get it working, but maybe one of the XSLT gurus here can make it happen...

I've coded up a truncation utility which bases its concept from the Ninja HTML Technique. However, mind truncates by character, not by word. However adding the word functionality wouldn't be a stretch.

Hi there, great stuff.

Would it be much work to add some functionality which returns the first line of the text without truncating?

Then I could use that to generate the HTML meta description.

How do you mean first line of text? That would depend on the width of your text block wouldn't it? Or do you mean the first paragraph? If so, then you can do that in XSLT:

<xsl:copy-of select="body/p[1]"/>

Well, sort off. I meant getting the first line of a paragraph until the first '.', that would fit nicely as the meta description in a page.

You could do something like:

 <p><xsl:value-of select="substring-before(body/p[1], '.')"/>.</p>

Thanks chzeng, exactly what I need it seems.

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