Sharing Code with Gist in ExpressionEngine

Tutorial on how to use Gists from GitHub to share code in ExpressionEngine2 content.

This is not the article that I originally set out to write. Last week I started an article about the benefits of a Ruby gem that I had started using. The research for the article was going great. I had working code examples and was ready to start writing. Then I hit a road block: How were my code examples going to be displayed?

Time for a minor detour:

We have been using GitHub to share code lately. This seemed like a good place to start. I quickly remembered that Gists were made for the specific purpose of sharing code snippets. Gists also have a feature to embed, via JavaScript, the snippet elsewhere on the web. I thought my journey was over, that this was going to be my solution. But once I looked at the code that the embed was generating, I was less than impressed. The embeds used "document.write" which is  generally frowned upon. Also, using the embed JavaScript in our ExpressionEngine field causes the admin tool to not work correctly––this prevented my article from being edited. This combined with the fact that people without JavaScipt would not be able to see my awesome code examples, I set out to find a better way.

The three problems:

  1. Retrieve a Gist and display it using server-side code. (ExpressionEngine integration required.)
  2. Be able to call ExpressionEngine tags from content blocks.
  3. Code examples need to have line numbers.

Fetch Gist

In order to fetch my Gists I decided to build an ExpressionEngine tag that would make the call on the server, strip out the JavaScript and then write out the HTML and CSS include. The CSS include was important to me because code highlighting was an important benifit of using Gist. This turned out to be fairly easy. All I had to do was call the same URL that is used in the embed and strip out the JavaScript and remove the new lines characters and slashes. I built the plugin to require that the user provide the Gist ID, but I left the filename as optional. This allows the end user to pull in multiple files by just the ID, and also allows me to identify a specific file.

You can check out my plug-in on GitHub.

Please note that this plug-in has only been tested using ExpressionEngine 2.

ExpressionEngine Tags in Content Blocks

So now I had a shiny new plug-in to pull in my code examples. I tested it out by directly putting in a templates on a development server. When I moved my new tag into the content of an article (by the way, we use WYGWAM) I realized that my new tag was not being executed. I set out to see if I could make this work. Like usual I dove in head first, so I popped open the source code for our rich text area field type and started hacking. I quickly realized that this was not the way to go. Then I jumped into Google and found that the ExpressionEngine core team had thought of this problem and provided a plug-in/tag to handle this situation.

You can find it here.

Now there are several security reasons that you should be careful when using this tag. This allows anyone who has permission to edit content to use any ExpressionEngine tags they want. It does not require much imagination to think of the abuse cases that could open up. I considered these risks and quickly decided that since this was our internal blog, that I could live with the risks.

So now I had my new tag and a way to use it in my article. Things were going great. I decided to show some other Sparkboxers. The first comment was not how cool it was, or how it worked, they just asked why there were no line numbers. This began the third leg of my journey. 

 

Line Numbers

So now that I had my code examples from Gist to my article in ExpresionEngine all I needed was to get line numbers in the code. I began by working through what it would take to add that functionality to my plug-in. I decided that doing this in PHP was not going to be fun, but while talking to Rob we decided that this could easily be done in JavaScript. Just make sure that below method get called after document.ready(). The below requires jQuery.

addLineNumbersToGists() {
$('.gist').each( function() {
$(this).find('.line').each(function(i, e) {
$(this).prepend(
$('<div/>').css({
'float' : 'left',
'width': '30px',
'font-weight' : 'bold',
'color': '#808080'
}).text(++i)
);
});
});
}
view raw script.js hosted with ❤ by GitHub

The End

So there you have it. You should be able to use the above to share code examples from Gist on your ExpressionEngine site. If you were hoping to find my Ruby article, don't worry, it should be done soon and it will have lots of code examples.