Introducing: ‘Kirby Highlight’

Hey there,
just recently I hacked together a plugin that highlights code snippets server-side.

But … why?

Server-side - that means no external dependencies (especially those written in javascript like prism.js and highlight.js). I love them both, but they’re not for everyone. People disabling javascript execution (and for good reasons) should still be able to enjoy some decently highlighted code IMHO.

Why not? When I found out about Geert Bergman’s highlight.php library (a PHP port of highlight.js), I decided to go for it:

  • Highlighting code for everyone - no javascript needed
  • Extensive: currently 141 supported languages
  • Customisable: 65 different styles included (more coming soon)

Getting started

Use one of the following methods to install & use kirby-highlight:

Git submodule

If you know your way around Git, you can download this plugin as a submodule:

git submodule add site/plugins/kirby-highlight

Clone or download

  1. Clone or download this repository.
  2. Unzip / Move the folder to site/plugins.

Activate the plugin

Activate the plugin with the following line in your config.php:

c::set('plugin.kirby-highlight', true);

Now proper classes are added to your code snippets, making them ‘themeable’. If you want to activate kirby-highlight only on specific domains, read about multi-environment setups.


Change kirby-highlight options to suit your needs:

Option Type Default Description
plugin.kirby-highlight.languages Array ['html', 'php'] Defines languages to be auto-detected (currently 141 languages are supported).


To apply one of the many available stylesheets, just include it in your <head> element using the css() helper:

<?php echo css('assets/plugins/kirby-highlight/css/zenburn.css') ?>

Note: Most of the included themes depend some way or another on the class .hljs to be added to the code’s container!

In order to make sure the theme gets applied as planned, any of these methods will work:

  • Simply use kirby-pep to put it there: c::set('plugin.kirby-pep.code_class', 'language-%s hljs');
  • Replace .hljs with [class^="language-"] in the included stylesheet
  • Copy it to your assets/css directory and modify it
  • Include the styles in your own workflow


Adding an unsupported language breaks kirbytext() parsing of the code snippet in question. Always be sure to only include valid languages.

You can find the plugin on Github. It’s not much, but it’s something. I’d love to get some feedback on this, and since this is my second (public) plugin, try to be nice :slightly_smiling_face:


Releasing v0.3.0-beta

Regarding language definitions & styles, this is up to highlight.js v9.12.0:

New features:

  • Added all 79 styles also included in highlight.js.
  • Added optional character escaping.

How to use:

Just define it in your config.php:

Option Type Default Description
plugin.kirby-highlight.escaping Boolean false Enables character escaping (converting < to &lt;, > to &gt;, …), see the docs over at PHP’s htmlspecialchars().

Feedback welcome!

This is still considered beta, but should nonetheless work as intended - since nobody complained, I guess that’s a good start!

However, feel free to test this release and if something’s bothering you, just open an issue.

Awesome! i’m testing this out on a documentation site i’m building at the moment. I will report back any issues.


Hmmm ok so I have some issues. I have install the plugin, and Kirby Pep, but its not quite working. I have the following options in my config:

c::set('plugin.kirby-highlight', true);
c::set('plugin.kirby-highlight.languages', ['html', 'scss', 'css']);
c::set('plugin.kirby-pep', true);
c::set('plugin.kirby-pep.code_class', 'language-%s hljs');

I have the styles included (as part of a SASS build, rather then standalone sheet)

My code blocks are getting partially styled. Im not seeing the .hljs class or a language class being applied to the code container, and the formatting is being stripped so its on one line:

<pre><code><span class="hljs-variable">$times</span>: Times, <span class="hljs-string">"Times New Roman"</span>, serif; <span class="hljs-variable">$arial</span>: Arial, sans-serif; <span class="hljs-variable">$georgia</span>: Georgia, serif; <span class="hljs-variable">$garamond</span>: <span class="hljs-string">"Apple Garamond"</span>, <span class="hljs-string">"ITC Garamond Narrow"</span>, <span class="hljs-string">"Garamond"</span>, serif; <span class="hljs-variable">$helvetica</span>: <span class="hljs-string">"Helvetica Neue"</span>, Helvetica, sans-serif; <span class="hljs-variable">$verdana</span>: <span class="hljs-string">"Verdana Ref"</span>, Verdana, sans-serif; <span class="hljs-variable">$trebuchet</span>: <span class="hljs-string">"Trebuchet MS"</span>, sans-serif; <span class="hljs-variable">$gillsans</span>: <span class="hljs-string">"Gill Sans MT"</span>, <span class="hljs-string">"Gill Sans"</span>, Tahoma, Geneva, sans-serif;</code>

Any idea whats wrong?

Three questions:

  • Are you using a generic textarea field?
  • Does your <code> element really not have any class (or was that just laziness :slight_smile: )
  • Are you invoking the code snippet using the usual fenced code syntax?


// some code


// Edit:
4th question: Which plugin versions are you using?

I am using Enhanced textarea field, but i get the same result with the standard Kirby field.

No laziness here, it really didn’t have the classes.

Ah ha! the missing thing, didnt realise i had to declare the language on the fence. I just did ```

So now i’m getting the classes that were missing, and a bit more styling, but the formatting is still stripped. Both highlight and pep are the most recent versions, downloaded today. Kirby 2.5.4, PHP 7x running on Homestead vagrant box.


Ok, think i’ve figured something out, perhaps a bug. It doesn’t like the sass code block starting with a variable.

this works, and keeps its formatting and indents, but only gets classes on the code tag…

components: (
	baseform: true,
	inputs: true,
	addons: true,
	select: true,
	validation: true

This gets stripped onto one line, but does get all the classes generated:

$form-skin-default: (
  // Components
  components: (
    baseform: true,
    inputs: true,
    addons: true,
    select: true,
    validation: true

Edit: Hmm… its worse then that, this doesnt work either…

body {
  padding: 0;
  margin: 0;
  min-height: 100%;
  display: flex;
  flex-direction: column;

I tried some HTML too and the same thing happens.

I’ll try to reproduce this, wait a sec …

Ah ha! I have found the culprit. Didnt realise i had @jenstornell HTML minifier active. It was that that was stripping the formatting. I feel silly.

Glad you worked it out!

True, highlight.js doesn’t seem to care that much for SASS/SCSS, but it gets rendered nonetheless :wink:

Thanks for looking into it. Unfortunately the @jenstornell html minifier plugin does not have a way to exclude certain tags, only whole pages. Thats no good to me because nearly every page has a code example on it… :frowning:

Releasing v0.4.0

With this release, the underlying PHP port is finally at eye level with highlight.js v9.12.0.

  • All 176 languages
  • All 79 styles
  • Improved language definition update process

Check it out on Github.
Thanks for the great feedback so far and have a good night, everybody!

code elements should not be minified. Do you use a code element?

Yes, its a Markdown code fence, so its actually a <code> tag nested inside a <pre> tag. The highlight plugin renders <span> tags inside this. It is not being ignored by your plugin. :frowning:

I think the problem is that your plugin is ignoring code, pre, and textarea tags, but its not ignoring tags inside those tags.

I have added an issue:

Because I’ve built the parser myself this time, it’s easier to fix the problem. It seems like all parsers have their own problems, now including mine.

Thanks @jenstornell , its a great plugin, and my use case is probably not a common one but i look forward to a resolution :slight_smile:

1 Like

A bit late probably but I updated my today and now I tested this code:

It keep the spaces untouched so I think it works like it should now:

    We have
        code here</span>

@jenstornell Gosh, completely forgot about that one. All good things come to those who wait. :slight_smile:

Ill test it out later on my blog, and I have various code snippets in several different languages so ill let you know if i hit any bumps.

Releasing v0.6.0

  • Updating highlight-php to v9.15.6.0 (more languages & styles)
  • Adding hljs class to pre container by default (configurable)
  • Removing kirby-pep from

Get your copy here and enjoy server-side syntax highlighting!