Skip to content

How to Build a Grav Plugin: Part 1

Identifying a need & assessing scope

  • code
  • tutorial
  • series

I use syntax highlighting in my editor environment. Most modern editors enable syntax highlighting and come with a couple of themes by default; most online code-sharing platforms (like GitHub, GitLab, or Gitea) provide this feature out of the box.

By way of an example, syntax highlighting turns this:

JavaScript code snippet without syntax highlighting
Before. This is fine, and it’s what I’ve been using up to now.

… into something like this:

JavaScript code snippet with syntax highlighting
After. Note that keys are light blue, numeric values are pink, and string values are green.

Grav, my current CMS, already has two plugins to do this on the client side:

  1. Prism Highlighter, which uses Prism.js; and
  2. Highlight, which uses (surprise!) highlight.js.

I’m not at all against JavaScript, but I prefer to reduce client-side JavaScript where possible. For what it’s worth, GitHub does this on the server side (formerly using the Python library pygments), as do GitLab (using the rouge Ruby gem) and Gitea (using Go’s chroma package). Nothing currently does this on the server side for Grav; this is by definition an opportunity, albeit a small one.

Features I’d like

Boom. Super high-level todo list done. Time for a little more refinement.

Choosing a library

I suppose I could try to write a syntax highlighter from scratch, but that would be a foolish waste of time. (Unless the goal were to learn how to do exactly that — parsing, keywords, etc. That is not the goal.) Plenty of server-side syntax highlighting libraries exist already. I’ll use one of those.

I could use pygments, rouge, or chroma, using exec to integrate the output of those programs in with PHP’s templating. The PHPygments library takes this approach. Since the intent is to release this on the Grav plugin repositbory, I’d prefer to not require a user to have to necessarily hop into a terminal session, check a Python version, etc. Doing so might even total preclude people from using the plugin in shared hosting environments.

For pure PHP libraries, I found two options:

GeSHi looks pretty robust, and highly customizable. It’s not immediately clear how actively developed it is, with several items on its issue tracker still open and last updated nearly 10 years ago. highlight.php, on the other hand, has a small but pretty healthy community at GitHub, and last had an update this summer. It’s available under the quite permissive BSD 3-Clause License, so no problems there.

Winner: highlight.php

Picking a theme from the admin panel

This will cover on Grav’s Blueprints. I’ll start with hardcoding a couple of themes, then take the opportunity to learn about using the data-*@: notation to dynamically populate the theme options provided by the highlight.php library.

Shortcode support

Shortcodes are shorthand — a kind of parameterized text expander that runs when templates are compiled and evaluated. I think WordPress popularized them, based on BBCode markup syntax. Plenty of other CMSs support them now, both in PHP-land (WordPress, Craft, and Perch among others) and in static site generators (Hugo, Eleventy, and Nikola among others).

The Grav core dev team already maintains the shortcode core plugin, so the heavy lifting of Grav integration is done. I’ll extend that work. (Literally, using a subclass.)

Wrapping up the planning phase

Okay, given that:

… I feel confident to proceed with the plugin project. As for planning the how to break up these posts, I’m thinking:

  1. this post
  2. planning out how the shortcode syntax will work
  3. setting up the development environment
  4. writing the plugin: shortcode/syntax highlighting bits
  5. writing the plugin: blueprint/admin panel bits
  6. writing the documentation, etc.
  7. finishing up: going through the plugin release process