5

I'm trying to build a plugin that adds a class to all images in my articles. So far I have the following code:

<?php
// no direct access
defined('_JEXEC') or die;
jimport('joomla.plugin.plugin');
class plgContentAddImageClass extends JPlugin
{
    public function __construct(&$subject, $params)
    {
        parent::__construct($subject, $params);
    }
    public function onContentPrepare($context, &$article, &$params, $offset = 0)
    {
        // Article Content
        $content = &$article->text;
        // Find images and add a class
    }
?>

But I'm stuck as to how I can find images in the content and add a class to them. Also, the images might have a class already, in that case I want to add a new one to the existing classes.

Edit:
I have a plugin that watermarks any image with a certain class, but because the site already has lots of images, I would like to add the class to the images dynamically instead of going through each <img> tag on the site and add the classes.

I'm aware that I can target all images with CSS, it just doesn't help in this case.

  • I know the question is how to build a plugin but did you consider that you can add a class to all your images with only CSS ? – Sébastien Gicquel Aug 13 '14 at 7:22
  • @SébastienGicquel: Can you elaborate on this? How he could add a class with only CSS? – FFrewin Aug 14 '14 at 10:16
  • @FFrewin Sorry, i'm confused, I made a mistake, he can't add a class only with CSS. I said "add a class" but i wanted to say "target' : if he wants to add a class to all images in articles, he can easily target all images with CSS (.article img {/*code*/}) But i understand that he asked how to make a plugin. Maybe he should explain a bit more what he is trying to do in order to find the best solution. – Sébastien Gicquel Aug 14 '14 at 10:37
  • Thanks for your comments. I've updated the question with an explanation. – Bogowoe Aug 14 '14 at 16:25
3

You can load the content into a DOMDocument(), and manipulate it.

<?php
// no direct access
defined('_JEXEC') or die;
jimport('joomla.plugin.plugin');
class plgContentAddImageClass extends JPlugin
{
    public function __construct(&$subject, $params)
    {
        parent::__construct($subject, $params);
    }
    public function onContentPrepare($context, &$article, &$params, $offset = 0)
    {
        // Article Content
        $content = &$article->text;
        // Find images and add a class
        $dom = new DOMDocument();
        @$dom->loadHTML(mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'));
        $dom->preserveWhiteSpace = false;
        $images                  = $dom->getElementsByTagName('img');
        foreach($images as $image) {
            // the existing classes already on the images
            $existing_classes   = $image->getAttribute('class');
            // the class you want to add
            $new_class          = ' yourclass';
            // the existing classes plus the new class
            $class_names_to_add = $existing_classes . $new_class;
            $image->setAttribute('class', $class_names_to_add);
        }
        // $dom now contains a complete HTML source, remove unnecessary tags
        $content = preg_replace('/^<!DOCTYPE.+?>/', '', str_replace( array('<html>', '</html>', '<body>', '</body>'), array('', '', '', ''), $dom->saveHTML()));
        return true;
    }
}
?>
  • 1
    I think that you're missing a $dom->loadHtml($content) in there somewhere. – David Fritsch Aug 11 '14 at 4:25
  • Yes, good observation (and silly mistake)... thank you, fixed it now. – johanpw Aug 11 '14 at 11:44
  • Thank you, that worked fine. What is the @ before $dom->loadHTML mean, and why are you using $dom->loadHtml(mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8')); instead of just $dom->loadHtml($content) – Bogowoe Aug 11 '14 at 15:20
  • 1
    The @ is a PHP error control operator, forcing any possible error to be ignored. loadHTML(mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8')) will force UTF-8 encoding, it might not be necessary, but as I often work with Norwegian characters (æ, ø, å), I add this to avoid garbled letters (like ü¥ó). – johanpw Aug 11 '14 at 17:08
3

Why would you want to do this?

You can easily target all images in an article with css without using a plugin, all you need is a bit of css;

.view-article img { // My awesome styles here ;}

Targets all images in your articles and doesn't add any the overhead, or complexity, a plugin would. The simplest way is always the best way.

Maintainable, scalable, secure.

  • Thank you, but in this case I need to add the class because I'm using a plugin that adds a watermark to images with a certain class. – Bogowoe Aug 14 '14 at 16:27
  • Still don't see why you would need to add a class dynamically. If your plugin can find images in articles it can then just add the watermark to those images. If you want it to only target images with a certain class, then your plugin doesn't need to add that class dynamically, does it? – Seth Warburton Aug 15 '14 at 15:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.