The social share image for the jmwhitworth/PrismPress Github repository

A custom Gutenberg block powered by Prism.js

As this website is primarily a web development blog and portfolio, I need to be able to display blocks of code to share with readers.

While dozens of plugins are available on the WordPress plugin repo, none of them fit my exact requirements.

I decided to build one myself so that I could utilise Prism.js, a lightweight syntax highlighter, within the Gutenberg editor.

Goals & Features

  • Create a custom Gutenberg block for adding syntax-highlighted code.
  • Use Prism.js for the syntax highlighting functionality.
  • Develop around having no bloat beyond my own personal requirements:
    • No admin pages as it will have only a single configuration
    • Only include a single Prism.js theme
    • Only include support for languages I use
    • Include minimal Prism.js plugins for quality-of-life features
  • Manage deployment via PHP’s Composer package manager.

Tech Stack

  • PHP ^8.0 (Should work for PHP 7.4 as there’s very minimal PHP in use, but untested)
  • Node ^21
  • Prism.js

Demonstration

# Python code
print("I'm using PrismPress!")
// PHP code without line numbers
echo "I'm using PrismPress!";
// Javascript Code
console.log("I'm using PrismPress!");
Plain text without line numbers

PrismPress supports many languages and can use any combination of them as required both with or without line numbers. Here’s the full list of supported languages as of version 1.2.1:

  • Markup (HTML + XML + SVG + MathML + SSML + Atom + RSS)
  • CSS
  • C-like
  • Javascript
  • Bash + Shell
  • Docker
  • JSON
  • Markup templating
  • PHP
  • Python
  • YAML

Additionally, the following plugins are included as of version 1.2.1 and are visible when hovering your mouse over (or tapping on mobile devices) one of the blocks:

  • Line numbers
  • Show language
  • Toolbar
  • Copy to clipboard

How to use PrismPress

Using PrismPress is easy. First, install the plugin by either downloading the latest release from GitHub and uploading the plugin to your website, or install it via PHP’s Composer package manager: Detailed instructions for both approaches are included in the readme file.

Once installed, it’s as easy as adding a new block in the Gutenberg editor and selecting ‘Prism Code’:

A screenshot showing the ‘Prism Code’ (PrismPress) block in Gutenberg.

With your new block, you can then select the language you’re using, choose to enable or disable line numbers, and paste your code into the text area:

A screenshot showing content being added in a ‘Prism Code’ (PrismPress) block.

This results in the following:

if __name__ == "__main__":
    print("Code on the right!")

Challenges in this project

Gutenberg blocks are built using React. React powers the editor and allows for elements to be drag-and-dropped and modified live on the page itself. Personally, I’d dabbled with React before getting into Gutenberg development, but since taking on Gutenberg development, I’ve learned a great deal about how React works.

An interesting challenge behind this plugin is allowing Prism.js to function correctly within Gutenberg. If you’re a user of Gutenberg, you might have noticed that the content for the block is added within the sidebar panel instead of directly on the block itself. This isn’t typical for Gutenberg blocks. As Prism.js rewrites the page markup to style and decorate the content inline with what language it’s set to display, this makes editing it on the block directly impractical. In my testing, each time I would type a character and React would re-render the block, it would reset my typing cursor to the beginning of the line. This is simply because, as far as my browser is aware, the element I was typing in was destroyed and recreated. To get around this frustrating limitation, I removed the ability to type in the block and relocated that to the sidebar. While the editing space is limited, the intention is for code to be copied and pasted into the block and not really to be written in the block directly.

Plans for future development

It’s possible that in the future I might change my approach to afford some extensibility for anyone else wanting to adopt the plugin if they needed extra languages or plugins. Currently, that’s not on my written list, but it’s something I’m keeping in mind.

As of version 1.2.1, my currently listed todos are:

  • Add updating within WordPress.
  • Add a better text area for coding, such as a modal.

Allowing updating within WordPress will allow anyone else who adopts this plugin to update the software without the need to manually install new releases. This isn’t an issue for me as I use Composer to manage my WordPress websites, but this isn’t so common for most WordPress deployments.

Adding a better text area for coding is a quality-of-life change that I think will be nice from a usability point of view. While, as I mentioned earlier, the intention isn’t for someone to write code within a PrismPress block, for small functions it might be easier. It’s currently easy to do so as well, but with a slightly larger area for previewing what you’re typing, it might just feel a little nicer to work with.

Summary

PrismPress is a custom block I’ve built to facilitate showing syntax-highlighted code on my WordPress website through the Gutenberg editor with minimal bloat.

I’m delighted with how the plugin works, and have had no troubles in using the block or seeing it in action. While it’s tailored specifically for my needs, I’ve made it distributable for anyone to utilise on the off-chance it can fulfil their needs too.

As a great exercise in React development and a project that will truly serve a purpose for years to come, I’m delighted with the work I’ve done here.