I have struggled with most solutions to convert and embed Jupyter notebooks into WordPress blog posts since I use Plotly as a graphic lib, as well as many LaTeX equations and images. Finally, I had to code my way through. Here is what I did :

1. Write the jupyter notebook

Nothing that you don’t know here. If you embed pictures in the notebook though, it would be good to upload them on your WordPress media library, then use the external URL to include them (from your server) in the Markdown cells of Jupyter. Otherwise, you have to put them in the same directory as the notebook and link them with their relative path, it’s less convenent.

2. Convert the Jupyter notebook to HTML

We convert with a basic template :

3. Allow HTML uploads in WordPress

Many security plugins disable this feature so you have to track the culprit if WordPress says “This filetype is forbidden for security reasons” and add this line in your theme

functions.php or wp-config.php:

Now you can import HTML pages just as any other media type. Be careful, this is a security issue. You need to harden the security of your WordPress install to prevent hackers to login, because they can now embed any kind of deceptive or fraudulent content in your pages.

4. Create a shortcode to include the page

This sounds worse than it is : we will just add a small shortcode to allow PHP to include the HTML file directly, without iframes or external renderer. Create a plugin, or add this in your functions.php:

From now on, when in a WordPress post editor, to include the HTML notebook file directly from your WordPress uploads directory (//:your-website.com/wp-content/uploads/), you can use the shortcode [include id="2018/05/notebook.html"] or alternatively [include id="notebook.html"] if you didn’t activate the date structure.

Notice that we enqueue the maths scripts here (see the next section) manually, the explanation is on the next section.

5. Load Plotly and MathJax

Exported with the basic template, Plotly javascript libraries are not embedded and neither are these from Mathjax. Some plugins do the work for MathJax but, as we have to code for Plotly, let’s do both. Again, in your functions.php or in a plugin, write :

The first two lines register the scripts and enables footer loading to improve the page loading speed. The function  load_maths  parses the post content and enqueue the scripts only if the LaTeX markups are detected on the page, avoiding unnecessary scripts on other posts (keep the web minimalist). We also need to enqueue them manually on the include shortcode (see section 5.) because the WordPress content filter is not able to parse includes, so the on-demand enqueuing only works on posts containing maths in the post entry.

The rest is a bit of configuration of MathJax to match the built-in configuration of Jupyter and the default WordPress LaTeX plugin shortcode for retro-compatibility. We add it on every page header, which is not necessary but does not really affect performance so we don’t need to add a content filter that will make the server work more for no user benefit. Notice that the LaTeX display math mode using \[  and \] won’t be available since it conflicts for some reasons with the brackets enclosing the Jupyter cell numbers, so you will have to use $$ instead.

6. A little bit of styling

Now, everything works except there is no styling. So, I just copy/pasted the CSS from Jupyter :

Et voilà ! See the result on my first post… Well, this is sort of depressing… to end up with such a short post whereas I spent 4 hours making everything work.