Emulating IPython Notebooks in WordPress

I purchased this website many years ago with the intention of starting my own blog. At the time, I was teaching myself Python, and I thought it wouldn’t be that hard to write my own custom website using CGI and MySQL. Please don’t ever do this! Although I learned quite a bit about web servers, HTML, CSS, and SQL databases, it was way too much work, and my blog never took off.

Fast forward to 2015. After receiving yet another auto-payment notification for my unused website, I decide the time has finally come to make use of it. Fortunately, my hosting provider has an auto-install option for a WordPress blog. WordPress is popular. It’s apparently easy to use… Let’s give this a try.

One thing I’d like to write about is Python programming for data analysis with included examples. I’m a heavy user of IPython notebooks for data analysis, so I’d like to be able to incorporate some of the notebook display features into my blog. Unfortunately, a web search for some ideas on uploading notebooks to WordPress was surprisingly unhelpful given WordPress’s popularity.

IPython provides a tool, nbconvert, which can convert notebook files directly to HTML. This is great because you can easily send a webpage of an analysis to a colleague, for example. It is also the basis of the NBViewer website. This might make a good starting point; however, one of my biggest problems with the IPython notebook is that markdown cells are not spell-checked. My spelling skills are atrocious, so my notebooks are always rife with errors. Knowing this, I was reluctant to upload notebooks directly and decided to pursue other options.

Ultimately, I found a bunch of plugins and hacks that gave me much of the display functionality for emulating the look and feel of the IPython notebook. My adventures are documented below in case others might find this useful.

Code Highlighting

This was the easiest part of the whole process. There are many syntax highlighters available as WordPress plugins. I took a quick look at a couple of “Top ### Code Highlighting” pages for inspiration, but it seemed like all the highlight plugins are fairly similar. I finally chose Crayon, not for any particular reason, except that it was pretty high up on many of the top lists. The default display properties were not optimal for my taste, so I modified several options through the “Settings” link under Crayon on the Plugins admin page. The changes are as follows: 1) Display the Toolbar to “Never”, 2) Enable plain code view and display to “Disable Mouse Events”, 3) and Language Fallback to “Python”.

Now, my “Add Post” editor contains a Crayon button, which opens a source code import window, from which I can also alter any of the numerous global display options. To add some code from a notebook, simply copy-and-paste it into the Crayon source code window. Once inserted, the source code is wrapped in the appropriate pre tags. For example, the following highlighted Python code

Appears as this in the Text editor window after insertion with Crayon:

<pre class="lang:python decode:true " >print('hello')</pre>

Creating a Child Theme

After some experimentation, I realized that I was going to need to modify my site theme with some custom CSS, at the minimum. I read up on this topic on the web, and most people recommend that you create a Child Theme when doing any customization. A child theme is essentially an overlay on top of another base (Parent) theme. There are a couple of advantages here. First, if the underlying theme is updated, you won’t lose your customizations. In addition, the child overlay is a fairly minimal set of files, so you could transfer your changes to a new theme with very little effort. The WordPress documentation on Child Themes is a pretty decent place to find step-by-step information.

As of this writing, this site is using the default “twentyfifteen” theme. In my themes folder, wp-content/themes, I created a new theme folder called twentyfifteen-child that contains two files: style.css and functions.php.

The functions.php file simply contains a function theme_enqueue_styles that loads the main style sheet from the underlying parent theme. My file is shown below:

The style.css file is simply your custom style sheet that must contain a comment header with a tag Template that names the underlying parent theme. I simply copied the parent theme style.css file and added the “Template” line. My file is shown below:

Then I simply changed to the “twentyfifteen-child” theme from the WordPress theme manager.

Pandas DataFrame Tables

Pandas is a powerful data analysis library for Python. Among other things, Pandas provides a tabular data structure called DataFrame, which is very similar to the equivalently named structure in R. In IPython’s notebook and Qt Console interface, Pandas DataFrames are printed as nice HTML tables. For example, below is a chunk of code and the IPython output.

one two 0 b
0 5 1 A D
1 8 9 B A
2 9 3 C E

Emulating this was a little tricky. As a first step, convert your notebook to HTML:

$ ipython nbconvert test_notebook.ipynb

Open the resulting HTML file in a text editor. There is a ton of boilerplate junk here, but you can easily find the table by searching for “<table”. Copy all of the text up to and including the closing </table> tag, and paste this into the Text Post editor. This won’t work in the Visual editor, which does some conversions behind the scenes. Make sure the table class is set to “dataframe”. Wrap the table in a div with the class name “dftable”. Here is the raw HTML for the above table:

Next, I modified the CSS file of my Child Theme (style.css) to alter the default appearance of this class of table and the surrounding div.

Perhaps not the most elegant solution, but it does the trick.

Matplotlib Figures

IPython can display Matplotlib figures inline with the rest of the code and output. On export to HTML, the image is embedded into the raw HTML in base64 encoded text. Again, this is great when sharing the HTML files with collaborators, because everything is contained in one file. However, WordPress doesn’t handle this elegantly. In this case, using Matplotlib’s savefig command will create a hard copy version of the figure in addition to inlining it in the notebook. For example, the following set of commands will produce a very simple plot in a notebook along with a PNG of the same figure called “testing.png”:


To emulate an IPython notebook with the inline set, I’ll probably just drop the savefig calls when transferring the code into my post. Then I can simply use the “Add Media” button in my post editor to upload and include the figure. An advantage of this procedure is that the figures are given their own URL, which people can reference in the future.


Again, there are a bunch of MathJax plugins available for WordPress. I chose “Simple MathJax” because it sounded… simple. And it seemed to best emulate the way MathJax behaves in IPython notebook markdown cells. Once installed and enabled, I can can add inline MathJax by using a single \$ sign. For example, \$\frac{1}{2}\$ will be rendered as $\frac{1}{2}$. Block equations can be included with the double dollar sign \$\$, such that \$\$\alpha^{2}\$\$ is rendered as $$\alpha^{2}$$

EDIT: This following paragraph is no longer necessary. I filed a PR with these changes to this plugin. It has been merged into master. I’ll leave this here for reference, though.

One issue is that the escaping the dollar sign is not supported by default. In order to set this, go to the Plugins page and select “Edit” under Simple MathJax. This opens a text editor for modifying this plugin. Search for the following line:

Add processEscapes: true to the end of this line as such:

Now your should be able to add dollar signs to your post by preceding them with \, such as \$.

Final Thoughts

That covers most things that I want to do for the time being. However, I’ll probably come back to this topic again once I get frustrated with some other odd behavior of my site. I hope others find this useful. Leave me a comment if you want me to add/clarify anything.


I wrote a second post that shows how to add “Input:”/”Output:” text before all code boxes.