Creating a GitHub-like editing experience in Backdrop

Created
Mon, 26/08/2019 - 04:26
Updated
Mon, 26/08/2019 - 04:26

I'm a big fan of the editing experience in GitHub. Through using GitHub over the last few years for my contributions to various open-source projects (mainly Backdrop CMS), I've learnt to write posts in Markdown and love the way GitHub makes it easy to add syntax-highlighted code snippets, insert images, etc. I wanted to replicate some of that functionality in Backdrop, so here's what I did...

Markdown

Using this website as a guinea pig (this post was written using the functionality I describe here), I first needed to allow Markdown in my Body field. Markdown itself is very old (last updated in 2004), but many different versions have popped up since then. I searched around and found that not only did Parsedown look like a good option, but there was already a Backdrop module for it. So I installed that and setup a new Text Format (called 'Markdown') that uses the Parsedown filter (and also Invisimail and Pathologic). Now I can write posts using just Markdown, or I can still choose the full HTML editor experience as always.

The Markdown text format

Another feature that I like in GitHub (and indeed many other sites) is the hidden permalinks next to each heading. When you hover over a heading an icon appears next to it which links directly to that heading. This lets you reference that section of the page very easily and has come in handy for me quite a few times. Yes you can create permalinks in your posts manually, but why do that when you can have it done automatically for you? I therefore wrote a filter module for Backdrop (since none already existed for Backdrop or Drupal) that automatically adds permalinks to the headings in your content. I then installed it on my site and added it to my Markdown text format. You can see it in action on this very page. Just hover over one of the headings and notice the '¶' link that appears next to it.

Syntax Highlighting

You can very nicely and easily add code snippets in Markdown by surrounding the code with three backticks (e.g. ```). But Github goes a step further and colour-codes the code as it were, making it more readable. This is called syntax highlighting. I discovered that Parsedown doesn't do this, so I needed something extra. After some searching, I found highlight.js which includes syntax highlighting for a bunch of different languages by default. With no Backdrop module for it, I decided to write one. After installing it, I simply chose a theme (I'm using 'Atom one light') and then it does its thing automatically.

For example, here's some of the code from the highlight.js module I wrote, coloured here using the very same module (how meta):

/**
 * Implements hook_init().
 */
function highlightjs_init() {
  $path = backdrop_get_path('module', 'highlightjs');
  $style = config_get('highlightjs.settings', 'style');

  // Add the CSS and JS on every page.
  backdrop_add_css("$path/highlight.js/styles/$style", array(
    'group' => CSS_SYSTEM,
    'every_page' => TRUE,
  ));
  backdrop_add_js("$path/highlight.js/highlight.min.js", array(
    'group' => JS_LIBRARY,
    'every_page' => TRUE,
  ));
  backdrop_add_js("$path/js/highlightjs.js", array(
    'group' => JS_DEFAULT,
    'every_page' => TRUE,
  ));
}

Inserting Images

The last step was to work out how to upload images to my posts, and then insert them into the Body field. GitHub provides a fancy drag-and-drop option for this, but I opted for something a bit simpler (and more Backdrop-y). I've previously inserted images into my content using Backdrop's CKEditor, but since I don't have an editor with Markdown I needed an alternative. I soon came across the Insert module for Backdrop and realised that was all I needed. I just added a new Image field to my content type (called 'Image insert'), enabled Insert module's functionality for it, and then prevented images uploaded to this field from appearing in my content by default. Now, when I upload an image to this field, an 'Insert' button appears which will add the necessary code into the Body field to display the image. The only problem was that it inserts HTML code by default. That was quickly fixed by overriding Insert's handy template files to output Markdown code instead.

Insert module

There are a few other things I could do to make the editing experience in Backdrop more closely resemble that of GitHub, such as setting up a basic editor that produces Markdown code via buttons or having an AJAX-y Preview feature, but I decided that I don't mind writing Markdown by hand and Backdrop's Preview button, while slower and a bit more tedious, suffices for my needs.