Easy Code Highlighting in Ghost with Prism
Background
I had a tough time searching around for the ideal solution on this. PrismJS provides an easy, extensible way to take care of code and syntax highlighting on websites. It's a really popular library that a ton of bloggers use for tutorials.
There are a couple of ways of skinning this cat, and some folks have already provided great tutorials here and here. However, I wanted something a bit more dynamic. I didn't want to load an additional 20-30Kb + of data on every page when I'm not posting code snippets on those pages. Also, I wanted the ability to dynamically load the languages I want to only if necessary.
So I mixed some solutions of my own together with some simple javascript.
Overview
- Download PrismJS and add the language components to your assets folder
- Edit your
post.hbs
file to dynamically load the prism libraries - Re-upload and activate your theme
- Profit and use PrismJS style
<pre>
and<code>
tag styling in your blog!
Guide
Step 1
Go to the PrismJS Download Page. For this since we can dynamically load whatever languages you need, you should only select the core modules and also the default languages if they make sense for you. The only necessity here is to make sure you include the autoloader module.
For this you will also need to download the language components file here (the link says download all grammars). Notice how we are at 16.04 KB!!!
For this you will also need to download your current theme. Go to your blog admin site or app and download / extract it.
Once you have your theme handy and have downloaded prism.js
, prism.css
, and components
(grammars) we want to move the prism files into your themes folder. Make a new directory called prism
inside your assets
theme folder. Copy the prism.js
and prism.css
into your newly created prism
folder. Lastly extract the components and copy them into a components
folder (full path should be /assets/prism/components/*
).
Great Step 1 is now complete!
Step 2
For this step we want to open our post.hbs
file within the root theme folder. You can use your favorite editor (I like VSCode or Atom). You want to copy and paste the following code into the end of this file before the {{/contentFor}}
line.
<script>
// Detect if we have code tags on the page.
var codeElement = document.querySelector("pre > code");
if (typeof(codeElement) != 'undefined' && codeElement != null)
{
// Create CSS Element
var prismCSS = document.createElement('link');
prismCSS.rel = "stylesheet";
prismCSS.type = "text/css";
prismCSS.href = "/assets/prism/prism.css?v=1"
// Create PrismJS Element
var prismScript = document.createElement('script');
prismScript.type='text/javascript';
prismScript.src="/assets/prism/prism.js?v=1";
// Set Components Folder because of asynch script loading
prismScript.onload = function() {
Prism.plugins.autoloader.languages_path = '/assets/prism/components/';
};
// Load script and css in the DOM
document.head.appendChild(prismCSS);
document.head.appendChild(prismScript);
}
</script>
What we are essentially doing is:
- Checking if our post has PrismJS supported elements (code tags inside of pre tags).
- If the tags exist we are dynamically creating a css file link as well as a script tag and loading them into the HTML head section.
Save this file.
Step 3
Compress, re-upload, and activate this new theme.
Step 4
In your blog you can now do something like this to take advantage of the new functionality. You can also use the standard markdown syntax with the triple backtick (eg: ```python```).
This is equivalent to:
And that will yield this on your page:
import requests
class Ghost:
def __init__(self):
pass
Final Thoughts
Once you know how to do it, getting this to work is pretty easy and painless. Let me know what you think down in the comments! If you have a better way of doing things I'm also open to ideas. A couple of key features I was looking for:
- Dynamically load whatever language I want
- Reduce (de-bloat) unnecessary script loading on my Ghost posts page
- Great syntax highlighting on my blog!
You could actually take this a step further if you were hosting your own blog and statically serve the prism assets through Nginx so you didn't have to worry about managing it inside your theme folder. I might do a tutorial on that next. This, however, should also work for folks that are using the Ghost cloud SaaS service as well.