7

Adding images to a post with the block editor:

enter image description here

produces the code figure of:

<figure class="wp-block-image">
    <img src="http://localhost:8888/time.png" alt="alt text" class="wp-image-1391"/>
    <figcaption>This is an image test.</figcaption>
</figure>

but I'm using Bootstrap 4 and would like to add Spacing (such as mt-2) and to remove the image class wp-image-1391, result:

<figure class="mt-2">
    <img src="http://localhost:8888/time.png" alt="alt text" class="img-fluid"/>
    <figcaption>This is an image test.</figcaption>
</figure>

or be able to modify it to a div:

<div class="mt-2">
    <img src="http://localhost:8888/time.png" alt="alt text" class="img-fluid"/>
    <figcaption>This is an image test.</figcaption>
</div>

Researching I've found get_image_tag_class but testing:

function example_add_img_class($class) {
    return $class . ' img-fluid';    
}
add_filter('get_image_tag_class','example_add_img_class');

doesn't work. Reading "How can I prevent WordPress from adding extra classes to element in the WYSIWYG editor" I tested:

add_filter('get_image_tag_class','__return_empty_string');

but doesn't work. I can modify the <img> with a preg_replace using the_content add_filter:

function add_image_fluid_class($content) {
    global $post;
    $pattern        = "/<img(.*?)class=\"(.*?)\"(.*?)>/i";
    $replacement    = '<img$1class="$2 img-fluid"$3>';
    $content        = preg_replace($pattern,$replacement,$content);
    return $content;
 }
 add_filter('the_content','add_image_fluid_class');

function img_responsive($content){
    return str_replace('<img class="','<img class="img-responsive ',$content);
}
add_filter('the_content','img_responsive');

but I've read that targeting the_content with regex can yield mixed results. I could solve the issue with a simple CSS:

figure img {
    width:100%;
    height:auto;
}
figure figcaption {
    text-align:center;
    font-size:80%;
}

but I'd like to understand more of what filters I can use to modify WordPress. How can I add and remove classes and change figure to a div?

2
  • 1
    I'd like to know this as well, I have a workaround but going forward I'd like to know how to customize these default blocks. Commented Jan 18, 2019 at 4:58
  • I was ready to tear my theme's php code into pieces when I discovered that all images are stretched due to new lazy loading thingy (I guess) +1 for pointing out an easy solution!
    – Maciek Rek
    Commented May 8, 2021 at 16:17

4 Answers 4

5

After some digging and trial/error I have came up with a couple solutions. I was looking for a "Gutenberg" solution so I could avoid using str_replace.

First, we need to enqueue our JS and include the wp.blocks package

// Add to functions.php

function gutenberg_enqueue() {
    wp_enqueue_script(
        'myguten-script',
        // get_template_directory_uri() . '/js/gutenberg.js', // For Parent Themes
        get_stylesheet_directory_uri() . '/js/gutenberg.js', // For Child Themes
        array('wp-blocks') // Include wp.blocks Package             
    );
}

add_action('enqueue_block_editor_assets', 'gutenberg_enqueue');

Next, I found a couple solutions, the first is probably the best for your specific use-case.

Method #1

Use a filter function to override the default class. Well, in this case we are going to keep the "wp-block-image" class and just add the needed bootstrap class mt-2. But you could easily add whatever class you wanted. Add the code below and create a new image block, inspect it to see the figure tag now has the new class.

// Add to your JS file

function setBlockCustomClassName(className, blockName) {
    return blockName === 'core/image' ?
        'wp-block-image mt-2' :
        className;
}

wp.hooks.addFilter(
    'blocks.getBlockDefaultClassName',
    'my-plugin/set-block-custom-class-name',
    setBlockCustomClassName
);

Method #2

Add a setting in the block styles settings in the sidebar to add a class to the image.

// Add to your JS file

wp.blocks.registerBlockStyle('core/image', {
    name: 'test-image-class',
    label: 'Test Class'
});

enter image description here

This will add your class but unfortunately Gutenberg appends is-style- before the class, so it results in is-style-test-image-class. You would have to adjust your CSS accordingly.


Method #3

Manually adding the class via the Block > Advanced > Additional CSS Class option. Obviously, the class would need to be added for each image block.

enter image description here


Note: When adding or editing any of the JS above I needed to delete the block, refresh the page and then re-add the block to avoid getting a block validation error.

References:

Block Style Variations

blocks.getBlockDefaultClassName

2
  • Nice, couldn't we also add the 3. method by using the Advanced settings of the image block to manually append a CSS class to the corresponding image :-)
    – birgire
    Commented Jan 18, 2019 at 20:52
  • 2
    haha yes! I overlooked adding that :) I will update the answer Commented Jan 18, 2019 at 20:54
4

Use the render_block filter hook:

add_filter( 'render_block', 'wrap_my_gallery_block', 10, 2 );

function wrap_my_gallery_block( $block_content, $block ) {

    if ( 'core/gallery' !== $block['blockName'] ) {
        return $block_content;
    }

    $return  = 'my-gallery-block<div class="my-gallery-block">';
    $return .= $block_content;
    $return .= '</div>';

    return $return;
}

Works on WP 5.5.

Reference: https://wordpress.org/support/topic/modify-gutenberg-core-block-render-result/#post-11716464

3

The following answer is a solution for Bootstrap 4 and centering images in a <figure> tag.

WordPress generated default:

<figure class="wp-block-image">
    <img src="http://localhost:8888/time.png" alt="alt text" class="wp-image-1391"/>
    <figcaption>This is an image test.</figcaption>
</figure>

Using the preg_replace() and the_content:

function add_image_fluid_class($content) {
    global $post;
    $pattern        = "/<figure class=\"[A-Za-z-]*\"><img (.*?)class=\".*?\"(.*?)><figcaption>(.*?)<\/figcaption><\/figure>/i";
    $replacement    = '<figure class="text-center my-3"><img class="figure-img img-fluid" $1$2><figcaption class="text-muted">$3</figcaption></figure>';
    $content        = preg_replace($pattern,$replacement,$content);
    return $content;
 }
 add_filter('the_content','add_image_fluid_class');

will produce:

<figure class="text-center my-3">
    <img class="figure-img img-fluid" src="http://localhost:8888/time.png" alt="alt text" />
    <figcaption class="text-muted">This is an image test.</figcaption>
</figure>

The code could be shortened to:

function add_image_fluid_class($content) {
    global $post;
    $pattern        = "/<figure class=\"[A-Za-z-]*\"><img (.*?)class=\".*?\"(.*?)><figcaption>/i";
    $replacement    = '<figure class="text-center my-3"><img class="figure-img img-fluid" $1$2><figcaption class="text-muted">';
    $content        = preg_replace($pattern,$replacement,$content);
    return $content;
 }
 add_filter('the_content','add_image_fluid_class');

if you wanted to add <small> you could do it as:

function add_image_fluid_class($content) {
    global $post;
    $pattern       = "/<figure class=\"[A-Za-z-]*\"><img (.*?)class=\".*?\"(.*?)><figcaption>(.*?)<\/figcaption><\/figure>/i";
    $replacement   = '<figure class="text-center my-3"><img class="figure-img img-fluid" $1$2><figcaption class="text-muted"><small>$3</small></figcaption></figure>';
    $content       = preg_replace($pattern,$replacement,$content);
    return $content;
 }
 add_filter('the_content','add_image_fluid_class');

the backend result is the image block with no align selection:

enter image description here

post rendered:

enter image description here

5
  • Good to know this is an option, I ended up finding what is probably the preferred method though, see my answer. Commented Jan 18, 2019 at 18:09
  • One can also use the render_block filter (PHP) to target a specific block.
    – birgire
    Commented Jan 18, 2019 at 20:45
  • Haven't done that do you an example you can demo?
    – user9447
    Commented Jan 18, 2019 at 21:42
  • I've posted two here recently wordpress.stackexchange.com/search?q=user%3A26350+render_block
    – birgire
    Commented Jan 18, 2019 at 23:57
  • @DᴀʀᴛʜVᴀᴅᴇʀ Looks good but will it work in future versions outside the content area for full site editing Commented Nov 11, 2021 at 8:32
1

The best way to deal with core block frontend issues are "override core blocks rendering"

example :

<?php
function foo_gallery_render( $attributes, $content ) {
    /**
     * Here you find an array with the ids of all 
     * the images that are in your gallery.
     * 
     * for example: 
     * $attributes = [
     *     "ids" => [ 12, 34, 56, 78 ]
     * ]
     *
     * Now have fun querying them,
     * arrangin them and returning your constructed markup!
    */
    return '<h1>Custom rendered gallery</h1>';
}
function foo_register_gallery() {
    register_block_type( 'core/gallery', array(
        'render_callback' => 'foo_gallery_render',
    ) );
}
add_action( 'init', 'foo_register_gallery' );

This works for all core gutenberg blocks, which means you can take advantage of the great blocks already developped, and arrange their output as you wish.

Reference : https://antistatique.net/en/we/blog/2019/01/29/gutenberg-override-core-blocks-rendering

1
  • Thanks, in my opinion, this is the best solution. Commented May 8, 2020 at 18:27

Your Answer

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

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