There’s got to be a prettier way of implementing this.
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.
scope 'api', :module => 'api' do
match '/:version' => redirect('/api/%{version}/docs')
match '/:version/docs/(/:page)' => "docs#show"
end
Create a controllers/api/docs_controller.rb.
class Api::DocsController < ApplicationController
# GET /api/docs/:version/:page
def show
@version = params[:version]
@page = (params[:page] || "index").downcase.gsub(/[^a-z0-9]/, '') # strip any non-alpha-numeric characters
filename = File.join(Rails.root, 'public/api/' + @version + "/docs/" + @page + '.md')
begin
file = File.open(filename, "rb")
@markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, :autolink => true, :space_after_headers => true)
render :text => @markdown.render(file.read), :layout => true
rescue Errno::ENOENT
render :file => "public/404.html", :status => 404
end
end
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?