Raw HTML Shortcode WordPress Plugin—preserve raw HTML formatting in the classic editor

The short version

I've written a WordPress plugin which gives you a short code [raw]content[/raw] that exempts the enclosed content block from WordPress's wpautop() processing, so you can include raw <style>, <script>, or other html into posts in the code tab of the classic editor without WordPress breaking them by inserting paragraph or line break tags into the code.

If that's enough explanation for you, the plugin can be found on Github at https://github.com/kupietools/ktwp-wp-plugin-raw-html-shortcode.

The longwinded version

In HTML5, it's acceptable to put <style>...</style> tags in page bodies. Even if it wasn't sometimes it's expedient in WordPress to include custom CSS or javascript in a single post. The correct WordPress way to do this is to enqueue CSS and javascript... but this requires writing PHP, and, if you ask me, is one of those case where the "correct" way of doing things doesn't always confer any advantages in exchange for the extra work and complexity it creates.

Now, as I do a bit of writing about code, and including live demos and toys and things in WordPress posts, it's sometimes just much easier for me to stick any necessary CSS and javascript in the body of the post.

Now it should be said, I use the Code tab in the classic editor. if you use the block editor, or just type into the Visual Editor tab of the classic editor, more power to you, this shouldn't concern you.

So, anyway, in the Code tab of the classic editor, the HTML in a post might look like this:


blah blah blah

<style>

  .pclass {
      font-weight: 700;
      line-spacing: 1.4em;
      animation: 3s infinite alternate slide-in;
  }

</style>

<p class="pclass">blahblah blahblah</p>

Then, you save the page, go to look at it, and... it doesn't work.

So you open the browser inspector, look at the page code, and see something like this:


blah blah blah

<p><style>
<p>
  .pclass {<br>
      font-weight: 700; <br>
      line-spacing: 1.4em; <br>
      animation: 3s infinite alternate slide-in; <br>
  }
<p>
</style></p>

<p class="pclass">blahblah blahblah</p>

Your CSS has had <p> and <br> tags strewn throughout it, breaking it, so the browser is simply ignoring it. The same thing will happen if you include javascript inline in <script> tags.

You've become the victim of wpautop().

What is wpautop()?

wpautop() is a very important WordPress function that silently does a lot of formatting work behind the scenes. wpautop() takes plain-ish text and automatically wraps it in HTML paragraph tags.

So if you write something like:

Hello there.

This is another paragraph.

WordPress can turn it into something like:

<p>Hello there.</p>
<p>This is another paragraph.</p>

That is the basic idea.

What wpautop() does

The name is short for "WordPress auto paragraph." Its job is to look at text content and say:

"Ah, this looks like a paragraph break. I’ll add <p> tags."

"This looks like a single line break. I’ll probably add a <br>."

For example, this:

Line one
Line two

may become:

<p>Line one<br />
Line two</p>

Whereas this:

First paragraph.

Second paragraph.

becomes:

<p>First paragraph.</p>
<p>Second paragraph.</p>

So it mainly handles:

  • turning double line breaks into paragraphs
  • turning some single line breaks into <br> tags
  • avoiding paragraph tags around certain block-level HTML elements
  • trying not to totally mangle existing HTML

The last point is important: wpautop() is not just a dumb "replace blank lines with <p>" function. It has a bunch of rules to avoid doing things like this:

<p><div>Something</div></p>

because that would be invalid HTML.

Why it exists

wpautop() exists because WordPress was designed to make publishing easy for people who do not want to write HTML. Most people writing blog posts expect this:

I write a paragraph.

I press Enter twice.

Now I have another paragraph.

They do not expect to manually write:

<p>I write a paragraph.</p>

<p>I press Enter twice.</p>

<p>Now I have another paragraph.</p>

So WordPress steps in and says:

"Don’t worry, author. You type like you would in an email or text editor, and I’ll convert that into web-friendly HTML."

That is the heart of wpautop().

Where you see it

Historically, wpautop() has been applied to post content through WordPress’s automatic formatting functions (internally called 'filters'). So when content is displayed on the front end, WordPress may run it through a chain of functions, including wpautop(), before showing it.

If you're a php developer poking around in the back end, in theme or plugin files, you may also see it used with things like:

echo wpautop( $text );

or removed from filters when developers want tighter control over markup.

For example:

remove_filter( 'the_content', 'wpautop' );

That tells WordPress:

"Please stop automatically adding paragraph tags to post content."

Developers sometimes do this when they are generating precise HTML and do not want WordPress inserting paragraphs or line breaks unexpectedly.

Why developers sometimes complain about it

wpautop() is helpful if you are just writing prose, but it can also be annoying. If you are writing custom HTML, shortcodes, forms, embeds, or complex layouts, it can feel like a tiny goblin sneaking into your markup and adding <p> tags where you did not ask for them.

For example, you might write a custom block-like bit of markup and end up with <style> tags in the code <br> tags, or even more simply just want to insert <p> and <br> tags into your post and keep them where you want them, rather than have WordPress try to interpret what you meant.

That is why you will sometimes hear developers say things like:

"Ugh, wpautop() is ruining my markup."

But from WordPress’s perspective, it is trying to help normal writing behave like normal web content.

The tradeoff

The tradeoff is basically this:

For writers:
wpautop() is convenient. You write naturally, and WordPress handles paragraph markup.

For developers:
wpautop() can be surprising. If you need exact HTML output, automatic formatting can get in the way.

So it exists because WordPress has always tried to balance being friendly for non-technical users with being flexible for developers. wpautop() is very much from the "make publishing easy" side of that balance.

Why not just turn wpautop() off?

As mentioned above, by adding some PHP code to your theme or a plugin, you can turn wpautop() off, even on a post-by-post basis. But that's as fine-grained as you can get... you can't say "Turn it off for this section of this post, but leave it on for the introductory paragraphs and the conclusion.

Enter the [raw] tag... you can exempt whatever part of whatever post you want from being ravaged by wpautop() without turning it off for anything else.

The plugin

Following are the explanatory README, the script code, and license, embedded from the plugin' repo on Github at https://github.com/kupietools/ktwp-wp-plugin-raw-html-shortcode.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply