0

For example, say I created a shortcode called [sourcecode] using the Shortcode API function, which is used to share code in posts like so:

[sourcecode]
#button {
    font-weight: bold;
    border: 2px solid #fff;
}
[/sourcecode]

(And it wraps the code in <pre><code> tags, takes care of escaping special characters, etc.)

Then say, after a while I decide to use Markdown (and no longer want to use the [sourcecode] shortcode or have its function in my functions.php) or switch to a new blogging platform.

Given the case, I'd like to have all instances of [sourcecode] .... [/sourcecode] in all posts replaced with their respective output. For example, if one of the posts has this:

[sourcecode]
#button {
    font-weight: bold;
    border: 2px solid #fff;
}
[/sourcecode]

It'd be replaced with and saved to database as:

<pre><code>#button {
    font-weight: bold;
    border: 2px solid #fff;
}
</code></pre>

Similarly, this should happen in all posts that have the [sourcecode] shortcode.

Does wordpress have any such regenerate function built-in, or is there a plugin that does what I am after?

1

First of all create a function that use get_shortcode_regex to get the post_content of a post with the shortcode replaced.

Note that any other shoertcode will be untouched

function get_replaced_sourcecode_sc( $post ) {
  if ( empty($post) ) global $post;
  if ( empty($post) || ! isset($post->post_content) ) return false;
  $content = $post->post_content;
  if (
    preg_match_all( '/'. get_shortcode_regex() .'/s', $post->post_content, $matches )
    && array_key_exists( 2, $matches ) && in_array( 'sourcecode', $matches[2] )
  ) {
    foreach ( $matches[2] as $i => $sc ) {
      if ( $sc == 'sourcecode' )
        $now = $matches[0][$i];
        $replace = do_shortcode($now);
        $content = str_replace( $now, $replace, $content );
    }
  }
  return $content;
}

Now in your functions.php you can also add following code:

function replaced_sourcecode_sc_all() {

   $already = get_transient('replaced_sourcecode') ? : array();

   $all = get_posts('nopaging=1post_type=post');

    if ( ! empty($all) ) {

      if ( count($all) == count($already) ) {
         error_log('replaced_sourcecode_sc_all already done its work');
         return;
      }

      $done = array();

      foreach ( $all as $one ) {

        if ( in_array($one->ID, $already) ) continue;

        $content = get_replaced_sourcecode_sc( $post );

        $post = array('ID' => $one->ID, 'post_content' => $content);

        $do = wp_update_post( $post );
        if ( $do ) $done[] = $do;

      }

      set_transient('replaced_sourcecode', $done);

    }
}

add_action('shutdown', 'replaced_sourcecode_sc_all');

Now, enable WP logging, and then visit your site 2 or 3 times. Check the error log and if you find the string "replaced_sourcecode_sc_all already done its works" you can remove the function (or simply comment out the 'add_action' line).

  • So, the first code block goes in my theme's functions.php. Am I supposed to place the second one in a file.php and run it in the browser? Is that what you meant? – its_me Sep 25 '13 at 19:28

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.