Jump to content

ProcessWire-Textformatter-AutoSchema: Problems with image markup


Recommended Posts

Hello,

I made a copy of the Textformatter Autoschema module to add additional Markups.

I have included a additional regex to fetch all images which are inside a link. They should be modified with a little bit of additional markup to make CSS3 effects possible.

Here is the copy of the module code with the changes.

<?php

/**
 * @author  FlipZoom Media Inc. - David Karich
 * @contact David Karich <david.karich@flipzoom.de>
 * @website www.flipzoom.de
 * @create  201401-10
 * @style   Tab size: 4 / Soft tabs: YES
 * ----------------------------------------------------------------------------------
 * @licence
 * Copyright (c) 2013 FlipZoom Media Inc. - David Karich
 * Permission is hereby granted, free of charge, to any person obtaining a copy 
 * of this software and associated documentation files (the "Software"), to deal 
 * in the Software without restriction, including without limitation the rights 
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
 * copies of the Software, and to permit persons to whom the Software is furnished 
 * to do so, subject to the following conditions: The above copyright notice and 
 * this permission notice shall be included in all copies or substantial portions 
 * of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * ----------------------------------------------------------------------------------
 */

class TextformatterBootstrapMarkups extends Textformatter {

    /**
     * ------------------------------------------------------------------------
     * getModuleInfo is a module required by all modules to tell 
     * ProcessWire about them
     * ------------------------------------------------------------------------
     * @return array
     */
    public static function getModuleInfo() {

        return array(

            // ------------------------------------------------------------------------
            // The module'ss title, typically a little more descriptive than the 
            // class name
            // ------------------------------------------------------------------------
            'title' => 'Bootstrap Markup changer with Schema.org', 

            // ------------------------------------------------------------------------
            // Version: major, minor, revision, i.e. 100 = 1.1.0
            // ------------------------------------------------------------------------
            'version' => 100, 

            // ------------------------------------------------------------------------
            // Summary is brief description of what this module is
            // ------------------------------------------------------------------------
            'summary' => 'Converts standard tags into Bootstrap markup classes enriched with schema.org data.',
            

            // ------------------------------------------------------------------------
            // singular=true: indicates that only one instance of the module is allowed.
            // This is usually what you want for modules that attach hooks.
            // ------------------------------------------------------------------------
            'singular' => true, 

            // ------------------------------------------------------------------------
            // autoload=true: indicates the module should be started with ProcessWire.
            // This is necessary for any modules that attach runtime hooks, otherwise those
            // hooks won't get attached unless some other code calls the module on it's own.
            // Note that autoload modules are almost always also 'singular' (seen above).
            // ------------------------------------------------------------------------
            'autoload' => false, 
        );
    }

    /**
     * ------------------------------------------------------------------------
     * Searches for tags and adds the right attribute.
     * ------------------------------------------------------------------------
     * @param  string $string
     * @return string $string
     */
    public function format(&$string) {

        // ------------------------------------------------------------------------
        // H1 headlines
        // ------------------------------------------------------------------------
        $string = preg_replace('/<h1(.*)>/Uis', '<h1$1 itemprop="headline">', $string);

        // ------------------------------------------------------------------------
        // H2, H3, H4, H5, H6 headlines
        // ------------------------------------------------------------------------
        $string = preg_replace('/<h([2|3|4|5|6]{1})(.*)>/Uis', '<h$1$2 itemprop="alternativeHeadline">', $string);

        // ------------------------------------------------------------------------
        // Tables
        // ------------------------------------------------------------------------
        
        //$string = preg_replace('/<table(.*)>/Uis', '<table class="table" $1 itemscope itemtype="http://schema.org/Table">', $string);
        $string = str_replace('<table', '<div class="table-responsive"><table itemscope itemtype="http://schema.org/Table"', $string);
        $string = str_replace('</table>', '</table></div>', $string);
        
        
        // ------------------------------------------------------------------------
        // Unordered lists
        // ------------------------------------------------------------------------
        //$string = preg_replace('/<ul(.*)>/Uis', '<ul itemscope itemtype="http://schema.org/ItemList">', $string);
        
        // ------------------------------------------------------------------------
        // Ordered lists
        // ------------------------------------------------------------------------
        //$string = preg_replace('/<ol(.*)>/Uis', '<ol class="itemscope itemtype="http://schema.org/ItemList">', $string);

        // ------------------------------------------------------------------------
        // Paragraphs
        // ------------------------------------------------------------------------
        $string = preg_replace('/<p(.*)>/Uis', '<p$1 itemprop="text">', $string);

        // ------------------------------------------------------------------------
        // Links
        // ------------------------------------------------------------------------
        //$string = preg_replace('/<a(.*)>/Uis', '<a$1 itemprop="url">', $string);

        // ------------------------------------------------------------------------
        // Address
        // ------------------------------------------------------------------------
        //$string = preg_replace('/<address(.*)>/Uis', '<address itemscope itemtype="http://schema.org/PostalAddress">', $string);

        // ------------------------------------------------------------------------
        // Images
        // ------------------------------------------------------------------------
        // THIS IS WHERE THE PROBLEM IS LOCATED
        //add additional markup to linked images
        $regeximg = '/<a(.*?)><img(.*?)(\/)?><\/a>/Ui';//grab all images inside links
        $imgsubstitute = '<a$1 itemprop="image" data-lightbox="gallery" class="img-responsive thumbnail"><div class="scalecontainer"><span class="roll"></span><img$2/></div></a>';
        $string = preg_replace($regeximg, $imgsubstitute, $string);
        
   
    }    
}

?>

Take a look at the code for images near the bottom. This is what I have added.

Unfortunately this only works if the images are in a figure tag like this:

<figure class="align_left"><a title="" data-original-title="" href="/site/assets/files/1807/bora_bora_3.jpg"><img alt="Rochen" src="/site/assets/files/1807/bora_bora_3.132x0-is.jpg" width="132"></a>
<figcaption>Rochen</figcaption></figure>

But it doesnt work if the figure tag is not there like:

<a title="" data-original-title="" href="/site/assets/files/1807/bora_bora_3.jpg"><img alt="Rochen" class="align_left" src="/site/assets/files/1807/bora_bora_3.150x0-is.jpg" width="150"></a>

I have tested the regex with a Regex-Tester and it works. Take a look here.

But this is the result on my webpage:

post-2257-0-63112000-1432114844_thumb.jp

As you can see the first image has errors in the markup - this is the image which is not in a figure tag.

The markup of the first image after the manipulation looks like this:

<p>
<a title="" data-original-title="" href="/site/assets/files/1807/bora_bora_3.jpg" itemprop="image" data-lightbox="gallery" class="img-responsive thumbnail"></a>
</p>
<div class="scalecontainer">
<a title="" data-original-title="" href="/site/assets/files/1807/bora_bora_3.jpg" itemprop="image" data-lightbox="gallery" class="img-responsive thumbnail">
<span class="roll"></span>
<img alt="Rochen" class="align_left" src="/site/assets/files/1807/bora_bora_3.150x0-is.jpg" width="150">
</a>
</div>

instead of this

<a title="" data-original-title="" href="/site/assets/files/1807/bora_bora_3.jpg" class="thumbnail"><div class="scalecontainer"><span class="roll"></span><img title="" data-original-title="" href="/site/assets/files/1807/bora_bora_3.jpg"></div></a>

So it makes always a strange markup and I dont know why because everthing seems ok to me.

Maybe someone has an idea :undecided:

Edited by LostKobrakai
Moved Topic
Link to comment
Share on other sites

Hello LostKobrakai and netcarver,

your code works in regex tester but on the page I got the same result as in my regex. It seems that in a textformatter module the regex doesnt work as expected. Images without figure tag will not be rendered correctly.

You can try it by adding this textformatter module to the body field of your installation. Add 2 images via the editor to the body field. One without caption (so no figure tag will be added by the editor) and on with caption.

After you check the source code of the output you will see that the manipulation of the first image fails.

Best regards

Link to comment
Share on other sites

@Juergen

Sorry that it is not working in a textformatter - I don't know why that is. Do you have any other textformatters working on the field before yours gets a go at it?

By the way, the results may be the same in the regex tester but the way our 2 regular expressions work is very different. This does matter the more text that needs to be searched. Keeping text formatters speedy is always nice. Check out the number of steps needed between your regex (over 4000 steps to search 5 paragraphs) and the one here (66 steps.)

I incorporated LostKobrakai's suggestion that allows whitespace between the '>' closing tags and the '<' starting the next tag in the link above.

@LostKobrakai - thank you for adding the code block to my post above - the forum didn't give me the option to use a code block when I was on mobile!

Link to comment
Share on other sites

Hello netcarver,

I am a little bit closer to the source of the cause, but it is a strange behaviour.

It is not the regex syntax which doesnt work, because it works quite well (mine, yours and LostKobrakais)

The problem of the first image is that is is wrapped in an anchor element only. If I add an additional div around the anchor like

<div class="imageholder"><a$1 itemprop="image" data-lightbox="gallery" class="img-responsive thumbnail"><div class="scalecontainer"><span class="roll"></span><img$2></div></a></div>

the strange markup  will be gone. Unfortunately the alignment behaviour (left, right) will be gone after adding the new div (imageholder) because the "imageholder-div" has to be the alignment class, but it has not.

post-2257-0-68806500-1432288829_thumb.jp

Link to comment
Share on other sites

Both of you are right!

Substitute the div elements with span makes the validator happy (but this is not the reason that the image doesnt float left to the text).

The CSS for the thumbnails makes them not floating left to the text. Here is the main problem.

The alignment will be added to the image tag at the first image.

<a.....<img class="align-left">.....

If the anchor has no CSS-styling the image will be floated left - OK.

If the anchor has the class property "display:inline-block", which is necessary in this context, the image will not be floated.

The best way would be to add the alignment class to the anchor tag too.

So I have to figure out the best way, how to add the alignment class to the anchortag too (not only to the image).

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...