Joomla

Extending the ItemHelper for Joomla

Published October 8th, 2019

Important: The information in this article is over 12 months old, and may be out of date or no longer relevant.

But hey, you're here anyway, so give it a read see if it still applies to you.

Update August 2021:

Item Helper has evolved since this blog post, and is now a plugin that you can install for your own Joomla site.

You can download it and see all documentation at https://github.com/mitydigital/joomla-item-helper

There are times in Joomla where you want a bit of control over your content at the template override level – such as showing the first X characters of a string.

PHP can do this really easily – but again, following on from the ItemHelper blog post for Custom Fields, wouldn’t it be great to centralise that?

What we are going to do now is extend our ItemHelper class – given we’re using it for our overrides anyway given we have our Custom Fields – and write a truncate method.

Our function is going to take a string, and return the first X characters, and NOT break a word. Because who wants a string to finish mid senten…

For simplicity, and typical usage, I’ve found that working with a plain string – i.e. no HTML – is far easier. When working with tags, it gets more complicated – so that can be left for another day. If you’re curious, there are libraries that can help with parsing HTML and truncating by words or characters – but let’s keep it simple.

The basic logic of what we’re going to do is:

  1. break our string in to individual words

  2. loop through the array of words, and add the word to the array, and add the length of that word to the tally plus 1 (to count for its space)

  3. on each iteration, check the current tally – if that is greater than or equal to X, our number of characters, stop looping

  4. finally, join the used words back to a string

This does mean that the string may become longer than the number of characters - because we don't want to chop off a word - just a heads up.

There’s one finer detail too – if the length of the string is actually less than the number of characters we want, we can just return the string before any processing. And conversely, when we have a “trimmed” string, we also want to add the ellipsis to the string to indicate there’s more. So we’ll cover these two bases too.

Let’s get started.

First step – let’s define our function. I’m calling it “truncate”, and need it to accept a string, and a number of characters, with a default of 160 if one is not provided. We can define a default for this now-optional parameter by specifying the default in the function declaration. And don’t forget your comments too!

1/**
2 * Truncate a string to a given number of characters, keeping whole words.
3 *
4 * The final string may be longer than the defined $numberOfCharacters because we don't want to break words.
5 * Behaviour could be tweaked to make the string be NO LONGER THAN, however this behaviour has worked better for us.
6 *
7 * @param string $string The string to process
8 * @param int $numberOfCharacters Optional. The number of characters for our string.
9 * Default 160 if not supplied.
10 *
11 * @return string
12 * @since 1.1
13 */
14public static function truncate($string, $numberOfCharacters = 160)
15{
16 
17 
18}
Copied!

Righto, let’s strip any tags from our string so we’re looking at just a plain string. At this point, we can check if the string is less than the number of characters – if so, we can just return it.

1// strip the tags
2$string = strip_tags($string);
3 
4// if the length of the string is less than the number of characters, simply return
5if (strlen($string) < $numberOfCharacters)
6{
7 return $string;
8}
Copied!

If we make it this far, we have a string that is longer than the number of characters. We can now break our string in to an array – so we can iterate really easily. I really do love the explode function – makes this sort of things so handy.

1// the individual words of our input string
2$words = explode(' ', $string);
Copied!

We can now process our array of words – a simple foreach is useful here. What we are going to do is loop through each word, and as we go:

  1. check if our tally of number of characters has been met – this is our exit condition. If we’ve reached our limit, we can exit out of the loop

  2. otherwise, add the word to our array of new words, and increase our tally of characters by the length of that word plus 1 (again, to account for the spaces in our string)

1// the current number of characters in our new string
2$counter = 0;
3 
4// an array for storing our words
5$use = array();
6 
7// loop through all of the words
8foreach ($words as $word)
9{
10 // if the tally of characters is greater than or equal to the total number needed, leave the loop
11 if ($counter >= $numberOfCharacters)
12 {
13 // exit the loop
14 break;
15 }
16 
17 // use the word
18 $use[] = $word;
19 
20 // update the counter
21 $counter += strlen($word) + 1; // add 1 to add a space after the word
22}
Copied!

So far so good – and so easy! Finally, we’re ready to return our string. So let’s use explode’s sister function, implode, and join our words together with a space between them. Finally, I like to include ellipsis, so will add that too:

1// join the array, add the ellipsis, and return
2return implode(' ', $use) . '...';
Copied!

And that’s all we need to do.

To use our new truncate function, let's say on our introtext and for 120 characters, we can simply call:

1echo ItemHelper::truncate($this->item->introtext, 120);
Copied!

Take a look at the Github repository for the ItemHelper to see the completed source code.

You may be interested in...