Select your language

All developers love to know the right way to achieve something. Often it's through trial and error but in this article Dimitris Grammatiko shares his insights and presents the definitive way to add images in Joomla 4 as well as how you can backport these advantages into older Joomla versions. Dimitris explains the history and usage of native support for lazy loading images and also with a new concept of adapters for storing images, both of which shipped in Joomla 4.0.5.

Making it work correctly is simple as illustrated below.

But first some context.
Joomla 3.10 release lead,Tobias Zulauf has been in many areas of the Joomla project. Some are better known than others. One of the projects Tobias tackled was the communication with the Google developers for implementing all the nice recommendations that appear whenever you run a Google lighthouse report in Google chrome's developer console. 

Tobias also created the plugin that would allow a new feature called “images lazy loading” The project decided not to go with the plugin approach but rather to use the native support for lazy loading as the default behaviour for all images. 

There was much discussion about this approach and not all were in favour. The reason that some had concerns was because the first iteration of the code treated every image as a lazy loadable image. 

That was rectified a few months later, when the image picker code had to be revisited to allow remote storage of images (what is known as Media Adapters). 

Google developers also supported the approach that didn't require a plugin. The plugin  approach had the overhead that a portion of the rendered HTML had to be parsed with some regular expression and an attribute was then added on that portion of the HTML. 

Apart from the obvious performance impact there was a usability impact as the plugin wouldn't be able to add the attribute to some images, it was either all or none. 

These are the historical events leading to where we are now. One consequence of the change is the effect it has on the way developers need to work with images. 

Until Joomla 4.0.5 the task of adding an image to the output HTML was up to the developer. They had to work out a way to do it. The project already shipped two different helpers to do this, but it turned out that most, if not all developers completely ignored the helpers and thus the images had a weird # with some random words and numbers at the end of the URL.

The solution

To put an end to this situation, a new JLayout was introduced that will allow developers to output the image tags correctly with the added bonus that it is far easier.

So instead or writing something like this:

<?phpecho '<img src="' . $imageURL .'" alt="' . htmlspecialchars($imageAlt, ENT_COMPAT, 'UTF-8') . '">';?>

 

The recommended way is to use JLayout:

<?php echo LayoutHelper::render('joomla.html.image', ['src' => imageURL, 'alt' => $imageAlt]); ?>

Benefits:

  • The URL and the alt attribute will be correctly escaped
  • The image tag is rendered correctly and the developer doesn't have to worry about the # at the end of the URL
  • The image tag will get a loading="lazy" attribute if the image has defined width and height attributes
  • The alt attribute will be ignored if the value passes is false (boolean)
  • Any additional attributes will be rendered correctly, just pass them in the named array: (e.g. 'class' => 'my-class')

What about backward compatibility

JLayout is available in Joomla 4.0.5 and later but was backported to Joomla 3.10.6 so that developers can use it in their extensions for both major versions of Joomla. For those that want to support earlier versions of Joomla, the recommended way is to distribute a copy of the layouts/joomla/html/image.php file in your extension and copy it to the exact location using a simple is_file() check in your update script.

Here is a simple example of how to do this:

public function install($type, $parent)

 {

// After your existing code

if (!is_file(JPATH_ROOT . '/layouts/joomla/html/image.php'))

{

copy(

$parent->getParent()->getPath('source') . '/image.php',

JPATH_ROOT . '/layouts/joomla/html/image.php'

);

}

 }

Hopefully this approach will help developers save time, create cleaner and safer code, making our lives easier.

No comments