Rendering Markdown Documents in Rails

Back | grape, rails, ruby | 11/7/2011 |

There’s got to be a prettier way of implementing this.

imageimage

We use the following code to render API documentation, which is written in Markdown.

Add a route that will capture the document filename in config/routes.rb. Bonus features: a namespaced controller and a redirect to /api/v1/docs for /api/v1.

  1. scope 'api', :module => 'api' do
  2.   match '/:version' => redirect('/api/%{version}/docs')
  3.   match '/:version/docs/(/:page)' => "docs#show"
  4. end

Create a controllers/api/docs_controller.rb.

  1. class Api::DocsController < ApplicationController
  2.   
  3.   # GET /api/docs/:version/:page
  4.   def show
  5.     @version = params[:version]
  6.     @page = (params[:page] || "index").downcase.gsub(/[^a-z0-9]/, '') # strip any non-alpha-numeric characters
  7.     filename = File.join(Rails.root, 'public/api/' + @version + "/docs/" + @page + '.md')
  8.     begin
  9.       file = File.open(filename, "rb")
  10.       @markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, :autolink => true, :space_after_headers => true)
  11.       render :text => @markdown.render(file.read), :layout => true
  12.     rescue Errno::ENOENT
  13.       render :file => "public/404.html", :status => 404
  14.     end
  15.   end
  16.   
  17. end

You can now create public/api/v1/docs/something.md and it will render under api/v1/docs/something.

What I’d like to do is take the Markdown renderer out of this controller, define it as a generic handler, and swap the template being rendered to the filename instead. How do I do that?