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?