Migrating from PHP Markdown to Jetpack Markdown

I’ve had this blog since 2004, less than a year after the first release of WordPress. Since then, I’ve migrated the blog to each new WordPress release.

Unfortunately, with each migration comes additional technical debt. For example, beginning with WordPress 2.2, the default character set for databases was changed from latin1 to utf8. Performing this conversion is a tedious, manual process, and through the years I’ve converted columns as-needed to support modern character sets (such as when needing the Unicode ♥ symbol).

Until now, a blocking problem has been that the PHP Markdown plugin has bugs that cause it to incorrectly render certain advanced HTML content, such as those found in shortcodes. Unfortunately, the plugin entered maintenance mode in February of 2013 and is no longer actively developed.


  • PHP Markdown stores its post_content in Markdown form in the wp_posts table. The PHP Markdown plugin, just before displaying a post, translates this Markdown text into HTML.
  • A consequence is that deactivating this plugin means that post content no longer appears as HTML. That’s bad.
  • Jetpack Markdown, the candidate replacement plugin, stores its post_content in HTML, and keeps the Markdown content in a separate post_content_filtered column. The advantage of this approach is that posts render correctly even if the plugin is deactivated. The design trade-off is that the database must store both the HTML and Markdown forms of the content.

There’s an impedance mismatch in that the two plugins translate from Markdown to HTML at different points in the content process.


The migration involves iterating through every WordPress post, and copying the Markdown form of post_content and storing it in post_content_filtered. At this point, post_content and post_content_filtered will both contain the Markdown form of the content.

Next, for each post, re-run the Markdown function (from markdown.php) and replace the post_content column with the HTML version of the content. That is:

$to_html = Markdown($post_content);

Finally, the new Jetpack Markdown plugin stores metadata for each post by adding a _wpcom_is_markdown key to posts that use Markdown. Thus, insert rows into wp_postmeta to reflect this:

INSERT INTO wp_postmeta
(post_id, meta_key, meta_value) VALUES 
(post_id, '_wpcom_us_markdown', '1')


The database is now migrated to a form that can be used by Jetpack Markdown.