3

Before the Block Editor was implemented, the <figure> tag used to have an inline width styling, matching the value of the image inside, example:

<figure style="width:300px;">
    <img src="https://example.com/image.jpg" width="300" height="100">
    <figcaption> text </figcaption>
</figure>

But since the Block Editor, this inline styling is removed:

<figure>
    ...
</figure>

How can we add this inline width styling back to the <figure> tag (avoiding a jQuery approach)?

  • Why? Or: what is it you are trying to achieve with this? Setting it to display: inline-block; might already solve many problems – kero Apr 12 at 14:00
  • I was just about to ask and suggest the exact same thing. I don't know if there is an easy way to do this without recreating the block, although there may be. – RiddleMeThis Apr 12 at 14:04
  • @kero @RiddleMeThis This is one of the cases where a simply display: inline-block; won't resolve it unfortunately. – Christine Cooper Apr 12 at 14:07
  • Could you do it similar to this solution? I've been trying with a pure JS method but cannot get the store working (blocks.getSaveElement filter gets URL and ID as third argument, but I've been unable to query given that ID to get the size) – kero Apr 12 at 14:36
2

I am assuming you want this value on the front-end as opposed to needing it in the block editor due to the <figure> somehow not displaying correctly when viewed in the block editor.

If that is the case then you can use something similar to DOMDocument as per the following example:

Assume HTML of:

<div>
    <figure>
        <img src="https://example.com/image.jpg" width="300" height="100">
        <figcaption> text </figcaption>
    </figure>
    <figure>
        <img src="https://example.com/image.jpg" width="300" height="100">
        <figcaption> text </figcaption>
    </figure>
    <figure>
        <img src="https://example.com/image.jpg" width="300" height="100">
        <figcaption> text </figcaption>
    </figure>
</div>

Processing logic:

$html = '<!-- YOUR HTML -->';

libxml_clear_errors();
$libxml = libxml_use_internal_errors(true);

$dom = new DOMDocument;
$dom->loadHTML($html);

$elements = $dom->getElementsByTagName('figure');

foreach ($elements as $element) {
    foreach ($element->getElementsByTagName('img') as $img) {
        if ( $img->hasAttribute('width') ) {
            $width = $img->getAttribute('width');
            $element->setAttribute('style', "width:{$width}px;");
        }
    }
}

libxml_clear_errors();
libxml_use_internal_errors($libxml);

// for debugging purposes print out the modified HTML
echo $dom->saveHTML();

Feel free to add more conditional guards/checks for existing style attributes so you can append/parse accordingly as my example shows a basic use-case only to get you started assuming this method is suitable for you.

Resulting output $dom->saveHTML():

<div>
    <figure style="width:300px;">
        <img src="https://example.com/image.jpg" width="300" height="100">
        <figcaption> text </figcaption>
    </figure>
    <figure style="width:300px;">
        <img src="https://example.com/image.jpg" width="300" height="100">
        <figcaption> text </figcaption>
    </figure>
    <figure style="width:300px;">
        <img src="https://example.com/image.jpg" width="300" height="100">
        <figcaption> text </figcaption>
    </figure>
</div>

Notes:

  • you could filter the content and/or resulting template prior to rendering on client via the_content and or similar
  • you could optionally filter the content prior to save via save_post

LibXML/DOMDocument:

Due to issues with processing HTML5, DOMDocument will generate warnings as a result of errors raised within libxml. Word on the street is that these are fine to suppress however I was only able to suppress them via using:

  • libxml_clear_errors();
  • libxml_use_internal_errors();
  • libxml_clear_errors();
  • libxml_use_internal_errors();

Alternatively you could use @ suppresion on:

  • @$dom->loadHTML($html);

...which is a little cleaner than the verbosity of four extra function calls.

Apparently this should work (since it was fixed):

$doc->loadHTML($html, LIBXML_NOWARNING);

...however I was unable to get this constant to work (could be version issues etc), see this and this.

  • 1
    This is great @userabuser - I am yet to test it out, but the code makes perfect sense. I would probably add a check to see whether if the <figure> tag may already have the width statement added. My initial hopes was to find a way to hook into the block code and add the styling there (so it is implemented naturally), but the fallback was DOMDocument so thank you very much for posting this solution! – Christine Cooper Apr 15 at 9:17
  • 1
    @ChristineCooper you are welcome, let us know how you get on or if you need further help. I'd be interested to know, if you end up using save_post hook before insertion, if the editor does not parse out the attributes on load (I'd assume not). – Adam Apr 16 at 10:07
  • 1
    Ended up solving it via a bizarre CSS approach which I never anticipated. Anyway, accepting this one! – Christine Cooper May 7 at 15:30

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.