Lightweight Markdown in your Rails models

We wrote 66 lines of code so you only have to type two

One of the first things we thought when developing the new website was that we wanted a blog. And we wanted it powered by Markdown! Markdown is a powerful yet lightweight markup language aimed at producing clean HTML output from a readable, uncluttered syntax. It is probably the most comfortable templating language I've had to struggle with.

I already knew there were some gems to integrate Markdown into Rails, but every piece of code I found was simply too much for our purpose. So we decided to give it a shot and wrote a gem in roughly 66 lines of code —Markdownizer was born.

Markdownizer uses CodeRay for code syntax highlighting and Ryan Tomayko's RDiscount to parse Markdown.

Integrating Markdownizer into your Rails application

Installing Markdownizer is pretty straightforward. If you are using Bundler to manage your application's dependencies (and if you are not you definitely should), you just have to include this in your Gemfile:

# Gemfile
gem 'markdownizer'  

If you want to use the code highlighting feature, you have to run this generator:

$ rails generate markdownizer:install

This will place a markdownizer.css file in your public/stylesheets folder. You will have to require it manually in your layouts, or through jammit, or whatever you are using to manage your assets :)

Unobtrusive in the models, unobtrusive in the views

Let's say you have a Post model that needs some Markdown attribute called body:

class Post < ActiveRecord::Base  
  markdownize! :body
  # In this case we want to treat :body as markdown.
  # You can pass an options hash to the code renderer, such as:
  #
  #   markdownize! :body, :line_numbers => :table
  #
end  

Markdownizer needs you to have an additional field called rendered_body. To fulfill this requirement, just create a database migration adding this field. Most times you will want this field to have the type text, I'm guessing. If the attribute in question was description instead of body, you would need a rendered_description field. You know what I mean.

Now you can save your posts like this:

# Example of post creation
Post.create body: """  
  # My H1 title
  Markdown is awesome!
  ## Some H2 title...

  {% code ruby %}

  # All this code will be highlighted properly! :)
  def my_method(*my_args)
    something do
      . . .
    end
  end

  {% endcode %}
"""  

The Post model automatically has a before filter that will re-parse the markdownized field upon update.

As you see, since we needed some customization, Markdownizer adds support for captions and line emphasizing. Please refer to the generated documentation to know how to use all the available options.

That's it!

In case you are wondering, this very post has been written in markdown using
Markdownizer. No kidding! :)