WP Post Encode — a WordPress Plugin for Including Raw Code in Posts

This is the official plugin page for WP Post Encode, a WordPress plugin for including raw code in your posts.

Note: This is an updated continuation of the article: “Adding and Filtering Raw HTML in WordPress Posts”. It’s recommended you read that article before this to get a background on this plugin.

That said, let’s dive into this plugin! WP Post Encode is a plugin written with developers in mind, or anyone who includes a lot of code in their articles. As anyone who includes scripts in their tutorials, posts, or articles knows, manually encoding any included code–whether it’s HTML, PHP, JavaScript, or any others–is a huge pain and colossal time killer. That’s where WP Post Encode comes in; it allows authors to simply write out any code script he/she wants without worrying about encoding it. All you have to two is wrap it custom quicktags, which are created automatically on plugin installation.

For the geeks, err, developers out there, continue reading for an in-depth look at the functions that make up the plugin.

If you’re just looking to install and use the plugin, click here to skip to the bottom of this article.

The Code

function dbdb_post_encode_activate() {
    if ( '' == get_option( 'dbdb_post_encode') ) {
        $name = 'dbdb_post_encode';
        $value = array();
        $value['buttons'][0]['text']  = 'encode';
        $value['buttons'][0]['start'] = '<!--encode-->';
        $value['buttons'][0]['end']   = '<!--/encode-->';
        $autoload = 'yes';
        add_option($name, $value, $autoload);
        }
}

function dbdb_post_encode_deactivate() {
    delete_option( 'dbdb_post_encode' );
}

if ( strpos( $_SERVER['REQUEST_URI'], 'post.php' ) || strpos( $_SERVER['REQUEST_URI'], 'post-new.php' ) || strpos( $_SERVER['REQUEST_URI'], 'page-new.php' ) || strpos( $_SERVER['REQUEST_URI'], 'page.php' ) ) {

    add_action( 'admin_footer', 'dbdb_post_encode_buttons' );
    
    function dbdb_post_encode_buttons() {
    
        $o = get_option( 'dbdb_post_encode' );
        
        if ( count( $o['buttons'] ) > 0 ) {
            echo <<<EOT
            <script type="text/javascript">
                <!--
                    if (dbencToolbar = document.getElementById("ed_toolbar")) {
                        var dbencNr, dbencBut, dbencStart, dbencEnd;
EOT;
                        for ($i = 0; $i < count($o['buttons']); $i++) {
                            $b = $o['buttons'][$i];
                            $txt = html_entity_decode(stripslashes($b['txt']), ENT_COMPAT, get_option('blog_charset'));
                            $text = stripslashes($b['text']);
                            $b['text'] = stripslashes($b['text']);
                            $start = preg_replace('![\n\r]+!', "\\n", $b['start']);
                            $start = str_replace("'", "\'", $start);
                            $end = preg_replace('![\n\r]+!', "\\n", $b['end']);
                            $end = str_replace("'", "\'", $end);
                            echo <<<EOT
                            dbencStart = '{$start}';
                            dbencEnd = '{$end}';
                            dbencNr = edButtons.length;
                            edButtons[dbencNr] = new edButton('ed_dbenc{$i}','{$b['txt']}',dbencStart, dbencEnd,'');
                            var dbencBut = dbencToolbar.lastChild;
                            while (dbencBut.nodeType != 1) {
                                dbencBut = dbencBut.previousSibling;
                            }
                            dbencBut = dbencBut.cloneNode(true);
                            dbencToolbar.appendChild(dbencBut);
                            dbencBut.value = '{$b['text']}';
                            dbencBut.title = dbencNr;
                            dbencBut.onclick = function () {edInsertTag(edCanvas, parseInt(this.title));}
                            dbencBut.id = "ed_dbenc{$i}";
EOT;
                        }
                    echo <<<EOT
                    }
                //-->
            </script>
EOT;
        }
    }
}

if ( function_exists( 'register_activation_hook' ) ) {
    register_activation_hook( __FILE__, 'dbdb_post_encode_activate' );
}
if ( function_exists('register_deactivation_hook') ) {
    register_deactivation_hook(__FILE__, 'dbdb_post_encode_deactivate');
}

function dbdb_quick_encode($content_text) {
    $charset = get_bloginfo('charset');
    $replaced_text = preg_replace('#(<!--encode-->)(.*?)(<!--/encode-->)#isme', "'$1'.str_replace(array('<!--nextpage-->', '<!--more-->'), array('&lt;!--nextpage--&gt;', '&lt;!--more--&gt;'), '$2').'$3'", $content_text);
    foreach($replaced_text as $k => $v ) {
        $encoded_text[$k] = str_replace(array('\"'),array('"'), $v);
    }
    return $encoded_text;
};
add_filter('wp_insert_post_data','dbdb_quick_encode', 1, 1);

function dbdb_post_encode($text) {
    $text = str_replace(array("\r\n", "\r"), "\n", $text);
    $text = preg_replace_callback("#(<!--encode-->)(.*?)(<!--/encode-->)#is", 'dbdb_code_encode', $text);
    return $text;
};
add_filter('the_content','dbdb_post_encode', 1, 1);

function dbdb_code_encode( $matches ) {
    $charset = get_bloginfo('charset');
    $text = trim($matches[2]);
    $text = str_replace(array('&lt;!--nextpage--&gt;', '&lt;!--more--&gt;'), array('<!--nextpage-->', '<!--more-->'), $text);
    $text = htmlspecialchars($text, ENT_QUOTES, $charset);
    $text = str_replace('[','[', $text);
    $text = str_replace(array("\r\n", "\r"), "\n", $text);
    $text = preg_replace("#\n\n\n+#", "\n\n", $text);
    return $text;
};

The Code Explained

The first function defines the action the plugin will take when the plugin is activated . It checks to see if the plugin’s option has been added to the wp_options table, and if not, add it. It defines the name of the option (“dbdb_post_encode”), creates an array named “buttons” which contain the values for the quicktag buttons created by the plugin’s javascript script, and tells WordPress to load the plugin automatically on page-load.

function dbdb_post_encode_activate() {
    if ( '' == get_option( 'dbdb_post_encode') ) {
        $name = 'dbdb_post_encode';
        $value = array();
        $value['buttons'][0]['text']  = 'encode';
        $value['buttons'][0]['start'] = '<!--encode-->';
        $value['buttons'][0]['end']   = '<!--/encode-->';
        $autoload = 'yes';
        add_option($name, $value, $autoload);
        }
}

The second function of the plugin defines the action the plugin should take if it’s deactivated. In this case, it deletes the option from the wp_options table.

function dbdb_post_encode_deactivate() {
    delete_option( 'dbdb_post_encode' );
}

The next section of the plugin is the javascript that displays the actual buttons on the HTML editor toolbar. The plugin will only load this script on Post/Page add/edit screens:

if ( strpos( $_SERVER['REQUEST_URI'], 'post.php' ) || strpos( $_SERVER['REQUEST_URI'], 'post-new.php' ) || strpos( $_SERVER['REQUEST_URI'], 'page-new.php' ) || strpos( $_SERVER['REQUEST_URI'], 'page.php' ) ) {

    add_action( 'admin_footer', 'dbdb_post_encode_buttons' );
    
    function dbdb_post_encode_buttons() {
    
        $o = get_option( 'dbdb_post_encode' );
        
        if ( count( $o['buttons'] ) > 0 ) {
            echo <<<EOT
            <script type="text/javascript">
                <!--
                    if (dbencToolbar = document.getElementById("ed_toolbar")) {
                        var dbencNr, dbencBut, dbencStart, dbencEnd;
EOT;
                        for ($i = 0; $i < count($o['buttons']); $i++) {
                            $b = $o['buttons'][$i];
                            $txt = html_entity_decode(stripslashes($b['txt']), ENT_COMPAT, get_option('blog_charset'));
                            $text = stripslashes($b['text']);
                            $b['text'] = stripslashes($b['text']);
                            $start = preg_replace('![\n\r]+!', "\\n", $b['start']);
                            $start = str_replace("'", "\'", $start);
                            $end = preg_replace('![\n\r]+!', "\\n", $b['end']);
                            $end = str_replace("'", "\'", $end);
                            echo <<<EOT
                            dbencStart = '{$start}';
                            dbencEnd = '{$end}';
                            dbencNr = edButtons.length;
                            edButtons[dbencNr] = new edButton('ed_dbenc{$i}','{$b['txt']}',dbencStart, dbencEnd,'');
                            var dbencBut = dbencToolbar.lastChild;
                            while (dbencBut.nodeType != 1) {
                                dbencBut = dbencBut.previousSibling;
                            }
                            dbencBut = dbencBut.cloneNode(true);
                            dbencToolbar.appendChild(dbencBut);
                            dbencBut.value = '{$b['text']}';
                            dbencBut.title = dbencNr;
                            dbencBut.onclick = function () {edInsertTag(edCanvas, parseInt(this.title));}
                            dbencBut.id = "ed_dbenc{$i}";
EOT;
                        }
                    echo <<<EOT
                    }
                //-->
            </script>
EOT;
        }
    }
}

The next two functions in the plugin register the functions that need to run when the plugin is activated or deactivated. In this case, we’re calling the first two functions we defined; “dbdb_post_encode_activate()” and “dbdb_post_encode_deactivate()”.

if ( function_exists( 'register_activation_hook' ) ) {
    register_activation_hook( __FILE__, 'dbdb_post_encode_activate' );
}

if ( function_exists('register_deactivation_hook') ) {
    register_deactivation_hook(__FILE__, 'dbdb_post_encode_deactivate');
}

The next function encodes two default WordPress quicktags, <!--nextpage--> and <!--more--> if you wrap them in the plugin’s custom <!--encode--> quicktags. Why do we have to do this? Because WordPress processes the core quicktags before anything else when displaying content on the screen. So if you want to show these two quicktags in sample markup in a post, they need to be encoded or the post will display weird.

Since we’re hooking this function to the “wp_insert_post_data” filter hook, it will encode the WP default quicktags as the post is added to the posts table. (If you hit “save draft” as you’re writing a post, you’ll see these two quicktags encoded when your page refreshes.)

function dbdb_quick_encode($content_text) {
    $charset = get_bloginfo('charset');
    $replaced_text = preg_replace('#(<!--encode-->)(.*?)(<!--/encode-->)#isme', "'$1'.str_replace(array('<!--nextpage-->', '<!--more-->'), array('&lt;!--nextpage--&gt;', '&lt;!--more--&gt;'), '$2').'$3'", $content_text);
    foreach($replaced_text as $k => $v ) {
        $encoded_text[$k] = str_replace(array('\"'),array('"'), $v);
    }
    return $encoded_text;
};
add_filter('wp_insert_post_data','dbdb_quick_encode', 1, 1);

The next function, “dbdb_post_encode()”, gets attached to the “the_content” filter hook (which is fired before a post is displayed on-screen) and looks for any content between the plugin’s custom <!--encode--> quicktags. When it finds a match, it calls the “dbdb_code_encode()” function, which does the actual encoding.

function dbdb_post_encode($text) {
    $text = str_replace(array("\r\n", "\r"), "\n", $text);
    $text = preg_replace_callback("#(<!--encode-->)(.*?)(<!--/encode-->)#is", 'dbdb_code_encode', $text);
    return $text;
};
add_filter('the_content','dbdb_post_encode', 1, 1);

The “dbdb_code_encode()” function is based off a function I found while reading through the bbPress source code. It takes the match provided it by “dbdb_post_encode()” and performs the following actions:

  1. Gets the blog’s character set (for encoding)
  2. Trims any whitespace from the matched content
  3. Un-encodes the quicktags previously encoded
  4. Encodes the matched content using PHP’s htmlspecialchars function (this will double-encode anything HTML entity found, so “&amp;” will become “&amp;amp;”)
  5. Encodes any shortcodes being shown as sample markup (discovered this while re-writing the WP Columnize plugin)
  6. Cleans up any multiple lines (used for large blocks of script)
function dbdb_code_encode( $matches ) {
    $charset = get_bloginfo('charset');
    $text = trim($matches[2]);
    $text = str_replace(array('&lt;!--nextpage--&gt;', '&lt;!--more--&gt;'), array('<!--nextpage-->', '<!--more-->'), $text);
    $text = htmlspecialchars($text, ENT_QUOTES, $charset);
    $text = str_replace('[','[', $text);
    $text = str_replace(array("\r\n", "\r"), "\n", $text);
    $text = preg_replace("#\n\n\n+#", "\n\n", $text);
    return $text;
};

Installing the Script

Manually:

  1. Download the “wp-post-encode.zip” folder from the WordPress plugin repository.
  2. Unzip the folder and upload to your plugins directory (..wp-content/plugins)
  3. Activate in the Plugins section of your Admin Dashboard

Automatically:

  1. Download the “wp-post-encode.zip” folder from the WordPress plugin repository.
  2. Naviagte to the Plugins section of your Admin Dashboard (Plugins→Add New→Upload).
  3. Click the “browse” button, select the zip folder from your computer, and then click the “install” button.
  4. Follow the install prompts after the folder has been uploaded.

Using the Script

Once you’ve installed the script, using it is as easy as typing your post as normal and wrapping your markup in <!--encode--> quicktags. I find it easiest to write out the code first, then highlight anything I want to encode, then click the “encode” button in the HTML editor.

To encode an in‐line piece of code, wrap it like so:

<code><!--encode-->$variable = 'value';<!--/encode--></code>

To display a block of text do it like so:

<pre>
<!--encode-->
<html>
    <head>
        <title>Lorem ipsum dolor sit amet</title>
    </head>
<body>
<!--/encode-->
</pre>

Notes & Resources

Some plugins that offer similar functionality:

First the Article,
Now the Comments

The individual views expressed within are those of the respective commenter and are not reflective of my own or my clients’. Skip to Comment Form →

I’ve try with manual input but do not work in comment :/
Any way to add also for comments? :/

@DarkWolf: It’s a separate process for comments. I have a function working for comments (as you can see in my comment box), but I haven’t released it yet. I’ll do that soon!

Hi darrinb, just want say thank to you! Very nice and helpfull plugin you wrote, its working!

<a href="">Link</a>

@ Peter Thanks! Glad you like it!

<html>
    <head>
        <title>Lorem ipsum dolor sit amet</title>
</html>

Make Yourself Read, Leave a Comment

Comment moderation is enabled. If you don’t see your comment, either it’s your first time commenting, you’re spam, or there was a glitch. If it’s two of the three, no worries, it’ll show up soon. (* Indicates a required field.)

If you want a commenter avatar, check them out here.

Allowed XHTML: <a> <abbr> <blockquote> <em> <strong>
Enclose code in backticks (`); no need to encode, the filter will do that for you.