Remove unnecessary closing slash on get_the_post_thumbnail() in WordPress


I am a pedant. I like it when validators say "nothing to report". No errors, no warnings, no information messages.

My blog is plagued with messages on the HTML validator saying

Info: Trailing slash on void elements has no effect and interacts badly with unquoted attribute values.

By default, the WordPress function get_the_post_thumbnail() spits out HTML like:

HTML HTML<img width="1024" height="593" 
    src="example.jpg"
    alt="whatever"
/>

That final / is unnecessary. Having it there doesn't do any harm. It doesn't break anything - except my calm - and is safe to leave in place.

Let's get rid of it anyway!

Place this in your theme's functions.php file:

PHP PHP//  get_the_post_thumbnail() returns <img ... /> - this removes the unnecessary closing of a void element
function remove_self_closing_slash_from_thumbnail( $html ) {
    //  Check if the string ends with " />"
    if ( substr( $html, -3 ) === " />" ) {
        //  Remove the " />" and add ">"
        $html = substr( $html, 0, -3 ) . ">";
    }
    return $html;
}

add_filter( "post_thumbnail_html", "remove_self_closing_slash_from_thumbnail" );

That adds a filter to the post_thumbnail_html hook and edits the string it returns.

There are various ways to approach this, you could load the element into a DOMDocument or have a complex regular expression - but this seems the simplest and safest.

Now, how do I remove the rest of the needless /> that WordPress scatters about?


Share this post on…

  • Mastodon
  • Facebook
  • LinkedIn
  • BlueSky
  • Threads
  • Reddit
  • HackerNews
  • Lobsters
  • WhatsApp
  • Telegram

5 thoughts on “Remove unnecessary closing slash on get_the_post_thumbnail() in WordPress”

  1. says:

    I have a trick I use to tidy my WordPress-generated HTML to exactly the specification I want. It's really, really hacky, which is a big part of why I haven't blogged about it, but it works (probably won't work on a FSE theme, though, if you're using one of those)!

    Here's the super-skinny:

    In my header.php, before any HTML is generated, I start an output buffer with a callback function: e.g. ob_start('tidy_up_entire_page'); This buffer wraps all the others, so it gets called/flushed when the last bit of content is generated. That function does a few safety checks (to allow me to bypass it) before running the buffer contents through HTMLTidy with my custom ruleset, including e.g. 'output-html' => true to force HTML5. I use ->cleanRepair() so it also attempts to do smart fixing of any accidentally-broken HTML I've produced. Ensure the output is produced before Super Cache or whatever kicks in, so you don't have to run HTMLTidy on 99% of the output (just serve the cached copy).

    It's really ugly. But I'll tell you what's not ugly: my pretty-printed source! Take a look and see what you think!

    Reply
  2. said on danq.me:

    My blog theme runs Tidy on the HTML output to help standardise it and make it more human-readable. I thought I might be the only person to care about such things, but it turns out that Terence Eden does too, so I've open-sourced my approach.

    Reply | Reply to original comment on danq.me
  3. Edward says:

    Thank you very much, it helped.

    This code works for thumbnails. And how can I make the code work for posts, so that in posts in img, the slash </> is also removed.

    Thank you!

    Reply

What are your reckons?

All comments are moderated and may not be published immediately. Your email address will not be published.

Allowed HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <p> <pre> <br> <img src="" alt="" title="" srcset="">