How to get rid of annoying closing slashes that prevent HTML from validating.

WordPress Wednesday: Closing Slash Hack

It’s been a hot minute since I wrote one of these, but let’s get right to it. At some point since the last time I was paying attention, the people who run the internet decided that closing slashes on self-closing HTML tags were not only redundant, but actually wrong. When I started building web pages — near the beginning of the last decade of the previous century — you needed to open every tag you closed. (I know this will be hard to imagine for some of you, but this was before the <img> tag existed! There were simply no images on the world wide web.) So if you wanted to wrap “some text” with an anchor (<a>) tag, you had to close the anchor tag with </a>. Like so:

<a href="https://google.com/">some text</a>

Trader Vic'sBut then pretty quickly the people who run the internet realized that it was hella boring with no pictures. The <img> tag was born to solve this problem. But the people who run the internet had already started cranking out some software to read all this HTML, and that software needed to know when a tag starts and when a tag ends. It’s obvious where an <a> tag ends because of the slash in </a> that’s wrapping around the text to which the <a> applies. But an <img> doesn’t wrap anything, so there was no obvious way to know when it needed to close. Enter self-closing tags. If you put a slash inside a tag, you know that there’s no closing tag coming and you can interpret the tag as-is, like so:

<img src="../trader-vics-300x176.jpg" alt="tiki bar" />

There are were a few other self-closing tags, like <br /> and <hr /> The browser that’s reading the HTML and deciding what to show you sees the closing slash right inside the tag and knows it’s done and it can continue interpreting what’s next without waiting for the tag to close.

Because so many people started writing HTML without really knowing anything else about how computers work, and because even good web developers sometimes do just the bare minimum to get things to work, browsers started having a hard time interpreting the obscene amounts of invalid code that started appearing all over the internet. A few plucky souls created a system for validating HTML. They built software (sometimes built directly into websites or browsers or browser plugins) that would check to make sure the code was good so a developer could rest easy knowing that (at least the vast majority of) browsers would be able to display the sites they were building the way they wanted them to appear.

<rant>
// You can skip this paragraph.
Note, please, that I’m ignoring a lot of stuff that isn’t relevant to this blog post. There were tens of thousands of people, for example, using really bad WYSIWYG software to churn out terrible, terrible HTML because they didn’t know anything about the web and Microsoft (and a few other companies) gave them tools that let anyone build a site. And then Microsoft — who had the biggest baddest browser — made it so that their browser knew how to interpret the bad HTML their other software was producing, and then other browser makers had no choice but to do things that made no sense to compensate. It was really a bad scene for anyone who wanted to produce “good” HTML. And even today there are two camps, just like in any other industry. There are people who want to make things “by the book” and have their code validate and everything exactly right and there are people who either don’t know or don’t care about doing anything “the right way”; they just want to get stuff done.
</rant>

Old habits die hard.

Quite a few years ago, the people who make the browsers finally realized that their software was smart enough to know how to handle tags that didn’t require a closing slash, but pretty much everyone kept using them for years and years because old habits die hard and we’d already created an entire infrastructure for validating HTML and making sure people were not writing renegade code that might steal your social security number and poison your dog. Or, worse, display a website where columns of text aren’t aligned correctly. So the people who decide what’s good HTML and what’s bad HTML declared that we no longer need closing slashes on self-closing tags. So instead of the code (above) to display an image, you remove the closing slash:

<img src="../trader-vics-300x176.jpg" alt="tiki bar">

After twenty years of meticulously making sure our self-closing tags included a closing slash, the powers that be made it so that including a closing slash was wrong. <Law & Order sound>

Now the really crazy part: Every browser out there will happily display an image on a website regardless of whether it has a self-closing slash. Both of the code examples above will work just fine. But now the one that was “right” since we started putting images on websites is now “wrong”. This matters to nobody other than that very tiny sliver of the pie chart of people who write HTML that includes those of us who want our websites to pass the W3C validator test.

And it really, really doesn’t matter to the people who make WordPress (and/or most WordPress plugins). I know this because no matter how I tried, I couldn’t get WordPress to stop adding trailing slashes to my <img> tags! But I found a way to suppress (most of) this nincompoopery. Add this code to your WordPress Theme’s functions.php file and it will strip closing slashes from self-closing tags:

    /*----------------------------------------------------------------------------
        Filter the_content to remove closing slashes from self-closing tags.
        1. PHP_INT_MAX ensures this filter is called after all other filters.
        2. The "dvg_" prefix is just there because I prepend it to all the functions
I add in case some other plugin or theme (or WP itself) has a function with the same name.
        3. That should be impossible because of the !function_exists() wrapper, but I'm
the sort of guy that so distrusts everyone else that he looks both ways even when crossing
a one-way street.
        4. My actual dvg_replace_content() function handles filtering some other stuff, too,
but I'm not including all of it here because it's not germane to this blog post.
    ----------------------------------------------------------------------------*/
    if ( !function_exists( 'dvg_replace_content' ) ) {
        function dvg_replace_content( $content ){
            $content = str_replace( '/>', '>', $content );
            return $content;
        }
        add_filter( 'the_content', 'dvg_replace_content', PHP_INT_MAX );
    }

Post the first comment:

I'll never share your email address and it won't be published.

What Is This?

davidgagne.net is the personal weblog of me, David Vincent Gagne. I've been publishing here since 1999, which makes this one of the oldest continuously-updated websites on the Internet.

bartender.live

A few years ago I was trying to determine what cocktails I could make with the alcohol I had at home. I searched the App Store but couldn't find an app that would let me do that, so I built one.

Hemingway

You can read dozens of essays and articles and find hundreds of links to other sites with stories and information about Ernest Hemingway in The Hemingway Collection.