Since I've been been working in IPython Notebook a lot lately, I wanted to find a way to post Notebooks directly into a WordPress blog. The results I found by googling were only partially satisifactory:

  1. http://www.josephhardinee.com/blog/?p=46

  2. http://stackoverflow.com/questions/20849988/posting-ipython-notebook-in-wordpress. This and #1 are essentially the same. They work, but since the html they start with is produced using the basic template of nbconvert, they leave out syntax highlighting and other important features.

  3. http://onsnetwork.org/eimd/2014/08/08/how-to-enter-ipython-notebooks-to-wordpress/. The code posted doesn't seem to work as is, but after a little fiddling I got the following recipe to work:

     <iframe src="http://nbviewer.ipython.org/my_notebook_location" 
      width="100%" height="500" scrolling="yes"></iframe>
    

    However, I don't like the way scrolling works and I'm a little uncomfortable routing my blog through ipython.org.

After some fiddling and googling around about various CSS and javascript issues I found a way to address both of my issues with #2 and get that working in a fairly satisfactory fashion for Chrome and I believe IE. Unfortunatley, this doesn't set the height correcly until a reload when using Safari. Still it's a start, so here's a first simple recipe, that mostly works:

  1. Install the Raw HTML plugin to wordpress. You only need to do this once.
  2. Run ipython nbconvert YOUR_NOTEBOOK.ipynb to get an html file.
  3. Upload this html file to your wordpress site. I think it needs to be on the same domain to avoid cross-site scripting issues with the javascript, but I haven't tested it
  4. Post the following chunk of code into your WordPress text window, replacing URL_OF_NOTEBOOK with the URL of the html file you uploaded earlier:
[raw]
<script type="text/javascript" language="javascript">
// <![CDATA[
function resizeIframe(obj) {  
    obj.style.height = obj.contentWindow.document.body.scrollHeight + 'px';   
    obj.contentDocument.body.style.overflowX = "hidden";
}
// ]]>
</script>
<iframe style="width: 100%; padding: 0; border: none;" 
        src="URL_OF_NOTEBOOK" 
        onload="javascript:resizeIframe(this);"/>
[/raw]

The [raw] tags keep WordPress from meddling with the code, while javascript fixes (i.e. turns off) the horizontal scrolling and sets the height correctly so that the whole notebook fits inline. Note that the Pandoc back end for nbconvert had some problems correctly processing the above code block, so I ended up downloading Node.js, which seemed to work much better.

After a bunch of searching around I came across a [page] (http://www.bitsofbits.com/wp-content/uploads/2015/01/custom.css) that described how to fix the issue with Safari using JQuery. After some fiddling I magaged to come a standalone fragment of HTML that appears to work correctly on Safari, Chrome and IE (recent versions at least). It's a little more cumersome than the preceding fragment, and does a little extra work on Chrome and IE, but it's a good start. Here's the updated fragment:

[raw]

<script type="text/javascript">
function resizeIframe(ifrm) {       
    ifrm.style.height = ifrm.contentWindow.document.body.scrollHeight + 'px';
    // Setting the width here, or setting overflowX to "hidden" as above both 
    // work for this page. It may be that one turns out to be better.
    ifrm.style.width = ifrm.contentWindow.document.body.scrollWidth + 'px';
}
</script>

<script type="text/javascript">
function onLoad() {    
    var ifrm = document.getElementById('ipython_notebook_frame');   
    setTimeout(resizeIframe, 0, ifrm);
}
</script>

<iframe id="ipython_notebook_frame" 
        style="height: 500px; width: 100%; padding: 0; border: none;" 
        src="URL_OF_NOTEBOOK">
 </iframe>

<script type="text/javascript">
// By deleting and reinstating the iframe src, and by using setTimeout
// rather than resizing directly we convince Safari to render the
// page. See http://www.bitsofbits.com/wp-content/uploads/2015/01/custom.css
var iframe = document.getElementById('ipython_notebook_frame');
iframe.onload = onLoad;
var iSrc = iframe.src;
iframe.src = '';
iframe.src = iSrc;
</script>

[/raw]

That's it, a possibly complete solution for displaying IPython Notebooks in WordPress. Please let me know if it's useful to you. Also please let me know if you have any suggestions for improvements, I suspect I'm doing this the hard way.

Since this is an IPython notebook, I'll throw in the obligatory plot as a demonstration:

In [1]:
%matplotlib inline
from matplotlib import pyplot as plt
import numpy as np

x = np.linspace(0, 10, 1000)

plt.plot(x, np.sin(x))
plt.plot(x, np.cos(x))
Out[1]:
[<matplotlib.lines.Line2D at 0x105753850>]