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.

4
  • 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 ? Aug 13, 2014 at 7:22
  • @SébastienGicquel: Can you elaborate on this? How he could add a class with only CSS?
    – FFrewin
    Aug 14, 2014 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. Aug 14, 2014 at 10:37
  • Thanks for your comments. I've updated the question with an explanation.
    – Bogowoe
    Aug 14, 2014 at 16:25

2 Answers 2

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;
    }
}
?>
4
  • 1
    I think that you're missing a $dom->loadHtml($content) in there somewhere. Aug 11, 2014 at 4:25
  • Yes, good observation (and silly mistake)... thank you, fixed it now.
    – johanpw
    Aug 11, 2014 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, 2014 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, 2014 at 17:08
4

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.

2
  • 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, 2014 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? Aug 15, 2014 at 15:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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