haml-server |
|
---|---|
|
|
haml-server is a dead-simple Sinatra app for serving up a directory of
files. There are a few other projects much more ambitious than this (such as
serve), but haml-server’s goal is simple: serve haml files. Why? Because
writing |
|
Installation |
|
This is the easy part! Run this from your default ruby (or default RVM ruby)
so you have access to
You can also grab the code from github. |
|
Usage |
|
Think of
Visiting |
|
Layouts |
|
You can also create a file called
|
|
SASS |
|
If you want to use SASS templates, you can either define them inline using HAML’s filters, like so:
Or you can write them to a standalone file, and then link to the same file
but with “.css” instead of “.sass”. So if you had
|
|
Helpers |
|
You can create a file called
And then in your views, you can access the helpers:
The helpers are reloaded before each request, so you can add and remove them without restarting the server. |
|
Running on Heroku (cedar stack) |
|
With Heroku’s cedar stack, it’s now super easy to deploy your |
|
Structure |
|
Since we’ll be adding some additional files to get things wired up, I
recommend you move your views and static files into a separate folder like
When working locally, then, you’ll want to run the site with: Now to get things set up for Heroku, we’ll need to add a few files:
Now the project should look like this:
|
|
Deploy |
|
First we’ll need to get our environment in order by running:
This will install any dependencies, and store those in a file called
Now we should set up the site as a
We’re almost done! Now we’ll create a new application and deploy it:
|
|
The code |
|
|
require "haml" |
|
require "sass" |
Okay. In any other context, this would be pretty evil. Let me explain.
Sinatra is a well-behaving citizen, and calls |
def ARGV.dup
self
end |
Yep. This is a hack, too. Sinatra only automatically runs itself when the file is directly called — but that’s not the case when running through rubygem’s wrapped command. Solution? Just pretend we were executed directly. |
$0 = __FILE__ |
And now we can load sinatra, knowing that the options will be parsed out of
|
require "sinatra" |
I love Pathname. This line works just like you’d expect it to:
|
require "pathname"
template_dir = Pathname(Dir.pwd) + (ARGV.shift || ".")
set :public_folder, template_dir
set :views, template_dir |
If a favicon wasn’t already matched by the public handler, just return a 404. |
get "/favicon.ico" do
404
end |
This will be a container module for user-defined helpers. |
module Helpers
class << self
def reload! |
First we remove all instance methods in the helper module. |
instance_methods.each do |method|
remove_method(method)
end |
And now we load any helper methods into the module from the file
|
module_eval(File.read("helpers.rb")) if File.file?("helpers.rb")
end
end
end |
Include our module into the Sinatra application. |
helpers Helpers |
This is our basic handler for all requests that come through to Sinatra. We’ll extract the necessary path information, and then render either a haml or sass file. |
handler = lambda do |
Reload our helpers for each request. |
Helpers.reload!
path = request.path_info
extension = File.extname(path) |
This is the most straight-forward way to remove the extension from a while while preserving it’s original path information. |
path = path.chomp(extension) |
If the path is empty, it’s a request for the index page. |
path = :index if path == "/" |
We’re rendering templates, so we need to convert to a symbol for Sinatra — otherwise it will think we’re rending a string. |
path = path.to_sym
case extension
when ".css" |
If a request for, say, ‘/stylesheets/screen.css’ wasn’t matched by the public handler, then we try to render a sass template with the same name. |
sass path
else |
Otherwise, we fall back to always rendering haml. |
haml path
end
end |
Now we bind our handler to all of the |
get //, &handler
put //, &handler
post //, &handler
delete //, &handler |
And that’s it! We let Sinatra handle the rest: it will parse out any provided
options (see |
|