Markdown with auto-title in Rails

Written . Tagged Markdown, Ruby, Ruby on Rails.

I really like the idea of using a writer’s format like Markdown for your site’s terms of use, privacy policy etc. I just implemented that on our site, and it’s so very sweet.

Prerequisites

I should mention I’m on Rails edge, currently revision 8168. Might work in earlier versions, but I didn’t try.

Install Markdown on Rails and the bluecloth gem.

Configuration

I created a config/initializers/template_handlers.rb file (that will also contain some Haml configuration) with this inside:

1
2
3
4
# Markdown on Rails

ActionView::Base.register_template_handler('markdown', MarkdownOnRails)
MarkdownOnRails::map_headings_down_by 1  # So '# Terms of Use' becomes a <h2> etc

If you installed Markdown on Rails as a gem (I have it pistonized), I believe you need to require it first.

Routes and controller

Create whatever routes you want – perhaps

1
map.info 'info/:action', :controller => 'info'

and create an InfoController. My controller reads like so:

1
2
3
4
5
6
7
8
9
10
11
class InfoController < ApplicationController
  before_filter :set_title

protected

  def set_title
    file = @template.full_template_path(default_template_name, @template.pick_template_extension(default_template_name))
    self.title = $1 if File.read(file).match(/\A\s*#\s*(.+)\s*$/)
  end

end

The set_title method simply reads the view file, finds an initial header like

1
# Privacy Policy

and sets that as the page title. It uses a title= helper that I’ve defined in ApplicationController. That method basically sets an instance variable that I display in my application layout. The net result is that the page <title> will be set automagically from the Markdown.

Writing set_title took some digging around inside Rails. There might be a nicer way to do this – let me know in the comments.

Markdown on Rails actually allows you to use erb in your templates, so if one doesn’t mind mixing things up and repeating oneself, one could get rid of set_title and do e.g.

1
2
3
<% self.title = "Privacy Policy" -%>
# Privacy Policy

instead.

Views

With all this set up, you can just create an app/views/info/privacy.html.markdown like so:

1
2
3
# Privacy Policy

Jeff Goldblum is watching *you* poop!

and similarly for terms of use etc.

The page title will be set and the Markdown is rendered all pretty inside the controller/application layout.