Music: PHP

Extending the ItemHelper for Joomla

Published

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!

/**
 * Truncate a string to a given number of characters, keeping whole words.
 *
 * The final string may be longer than the defined $numberOfCharacters because we don't want to break words.
 * Behaviour could be tweaked to make the string be NO LONGER THAN, however this behaviour has worked better for us.
 *
 * @param string $string             The string to process
 * @param int    $numberOfCharacters Optional. The number of characters for our string.
 *                                   Default 160 if not supplied.
 *
 * @return string
 * @since 1.1
 */
public static function truncate($string, $numberOfCharacters = 160)
{


}

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.

// strip the tags
$string = strip_tags($string);

// if the length of the string is less than the number of characters, simply return
if (strlen($string) < $numberOfCharacters)
{
    return $string;
}

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.

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

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)
// the current number of characters in our new string
$counter = 0;

// an array for storing our words
$use = array();

// loop through all of the words
foreach ($words as $word)
{
    // if the tally of characters is greater than or equal to the total number needed, leave the loop
    if ($counter >= $numberOfCharacters)
    {
        // exit the loop
        break;
    }

    // use the word
    $use[] = $word;

    // update the counter
    $counter += strlen($word) + 1; // add 1 to add a space after the word
}

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:

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

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:

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

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

Blog

View all
JS

Integrating Tiny with Vue in a real world application

TinyMCE 5 has made the setup process more straightforward - and even easier with the Cloud version. And as there are so many JS frameworks out there, Tiny have...

Continue reading...

PHP

Extending the ItemHelper for Joomla

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...

Continue reading...

JS

How Tiny helps me deliver the best content authoring experience

At Joomla Day Australia 2019 in Brisbane, I spoke about how TinyMCE helps deliver the best content authoring experience. And for those who couldn’t make it on...

Continue reading...

Photo

How to show real-time highlights and shadows clipping in Photoshop

I’ve used Photoshop for years. Decades even. Yikes, showing age there. But for my photography, I tended to use Photoshop for specific things – such as cleaning...

Continue reading...

I am the Development Director (and co-owner) at Mity Digital, a Melbourne-based digital agency specialising in responsive web design, custom web development and graphic design.
Mity Digital