Toggle sidebar

Creating a GitHub-like editing experience in Backdrop

I'm a big fan of the editing experience in GitHub. Through using GitHub over the last few years for me 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 me 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 choc-a-bloc 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 ya hover over a heading an icon appears next to it which links directly to that heading. This lets ya reference that section of the page very easily and has come in handy for me quite a few times. Yeh ya can create permalinks in ya posts manually, but why do that when ya can have it done automatically for ya? I therefore wrote a filter module for Backdrop (since none already existed for Backdrop or Drupal) that automatically adds permalinks to the headings in ya content. I then installed it on me site and added it to me Markdown text format. Ya 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

Ya 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 nah 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 me 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 me 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 me content type (called 'Image insert'), enabled Insert module's functionality for it, and then prevented images uploaded to this field from appearing in me 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 me needs.