Reputation: 5664
I'm building a simple "notes" site using Sinatra and Heroku. I write my notes up using Markdown and use the rdiscount gem to convert them to HTML in Sinatra. So a request for /foo would serve up the template /views/foo.md, converted to HTML
What I'd also like to be able to do is serve up the Markdown source as a plain text file. So /foo/source (or something similar) would server up /views/foo.md as plain text.
I've tried using ERB but it just ends up wanting to serve /views/foo.erb.
Here is my current app:
require 'sinatra'
require 'rdiscount'
set :markdown, :layout_engine => :erb
get '/' do
markdown :index
end
get '/:topic' do
markdown params[:topic].to_sym
end
Upvotes: 2
Views: 3050
Reputation: 8252
Short answer: use File.read
to suck in the file's contents, then do what you want with it:
get '/topic/:topic'
markdown File.read(params[:topic] + ".md")
end
Long answer: Sinatra can get kind of goofy with dots and colons and file types, so you may have to wrest control of the parameter. The following (working!) Sinatra app may help demonstrate.
require 'rubygems'
require 'sinatra'
get '/' do
markdown <<-MARKDOWN
# Markdown in Sinatra
* [markdown](/notes)
* [plain text](/notes.txt)
* [pre html](/notes.html)
MARKDOWN
end
def source
parts = params[:base].split('.')
name = parts.first
ext = parts.last
filename = name + ".md"
source = File.read(filename)
puts "filename=" + filename.inspect
puts "source=" + source.inspect
source
end
get '/:base.txt' do
source
end
get '/:base.html' do
"<pre>#{source}</pre>"
end
get '/:base' do
markdown source
end
Upvotes: 4
Reputation: 5664
With a little more searching I managed to get it working using send_file:
get '/:topic/source' do
send_file File.dirname(__FILE__) + "/views/#{params[:topic]}.md", :type => :text
end
But I'd like to believe there's a more elegant solution out there, so leaving the question open for now.
Upvotes: 0
Reputation: 52688
You can try using the str
template:
get '/:topic/source' do
str params[:topic].to_sym
end
The only thing to take into account is that it'll try to interpolate the values like it would do with a string - in other words, it'll try to replace #{foo}
with foo.to_s
. This might or might not be desirable.
Disclaimer: I'm not sure it'll work, I had to deduce this functionality by looking at the source code of Tilt, and I haven't tested it.
Edit: I'm afraid that doesn't work. It's possible to define the str method like this:
helpers do
def str(*args) render(:str, *args) end
end
The Tilt engine tries to find a view called 'foo.str' instead of using 'foo.md'. I also tried registering 'md' as a valid extension of StringTemplate, but it didn't work (I either got the markdown rendered as a string, or I had the same error as before.
Sorry.
Upvotes: -1