public
Fork of bmizerany/sinatra
Description: Classy web-development dressed in a DSL
Homepage: http://sinatrarb.com
Clone URL: git://github.com/JackDanger/sinatra.git
Search Repo:
bmizerany (author)
Thu Apr 10 15:38:39 -0700 2008
commit  39cee5c8da2caf27359e8bc8cb8cd5fef3d426d1
tree    a4ff88fa2fbe10e21410312e20201b6d06d38d22
parent  ca9ac7b5aeb3d5adc1a4c7fb86e21b0dc688e55b
name age message
folder .gitignore Wed Feb 20 20:14:53 -0800 2008 more ignores [Blake Mizerany]
folder CHANGELOG Fri Apr 11 16:29:36 -0700 2008 Sinatra 0.2.0 released [Blake Mizerany]
folder LICENSE Sun Apr 13 23:54:08 -0700 2008 added MIT for release [bmizerany]
folder Manifest Fri Apr 11 16:29:36 -0700 2008 Sinatra 0.2.0 released [Blake Mizerany]
folder README.rdoc Tue Apr 08 13:51:28 -0700 2008 Added Sass information to documentation. [nmeans]
folder Rakefile Fri Apr 11 16:29:36 -0700 2008 Sinatra 0.2.0 released [Blake Mizerany]
folder images/ Thu Nov 29 18:35:06 -0800 2007 * Default error messages [Blake Mizerany]
folder index.html Mon Apr 07 19:03:48 -0700 2008 new rubyforge page [Blake Mizerany]
folder lib/ Fri Apr 11 14:09:23 -0700 2008 err. [Blake Mizerany]
folder test/ Fri Apr 11 14:09:23 -0700 2008 err. [Blake Mizerany]
README.rdoc

Sinatra

Sinatra a DSL for quickly creating web-applications in Ruby with minimal effort.

Sample app:

  # myapp.rb

  require 'rubygems'
  require 'sinatra'

  get '/' do
    'Hello world!'
  end

Ruby this as ruby myapp.rb and view at http://localhost:4567

RESTful

  get '/' do
    .. show things ..
  end

  post '/' do
    .. create something ..
  end

  put '/' do
    .. update something ..
  end

  delete '/' do
    .. annihilate something ..
  end

  head '/' do

  end

NOTE: put and delete are triggered when a _method param is set to PUT or DELETE and the HTTP_REQUEST_METHOD is a POST

Routes

NOTE: Routes are looked up in order of declaration

Simple

  get '/hi' do
    ...
  end

With params

  get '/:name' do
    # matches /sinatra and the like and sets params[:name]
  end

Splat’n

  get '/message/*' do
    # matches /message/1/2/3/4/5
  end

Get an agent!

  get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
    "You're using Songbird version #{params[:agent][0]}"
  end

  get '/foo' do
    # matches non-songbird browsers
  end

Static files

Put all of your static content in the ./public directory

  root
    \ public

If a file exists that maps to the REQUEST_PATH then it is served and the request end; Sinatra will look for and event that matches the path otherwise

Views (if you need MVC)

All views are looked up in:

  root
    | - views/

Templates

Haml

  get '/' do
    haml :index
  end

This will render ./views/index.haml

Sass

  get '/stylesheet.css' do
    header 'Content-Type' => 'text/css; charset=utf-8'
    sass :stylesheet
  end

This will render ./views/stylesheet.sass

Inline

  get '/' do
    haml '%div.title Hello World'
  end

This will render the inlined template string

Accessing Variables

Templates are rendered in the context the current Sinatra::EventContext. This means you get all instance/class variables and methods it has access to.

  get '/:id' do
    @foo = Foo.find(params[:id])
    haml '%h1== @foo.name'
  end

Send local objects like:

  get '/:id' do
    localvar = Foo.find(params[:id])
    haml '%h1== localvar.name', :locals => { :localvar => localvar }
  end

This is more ideal for rendering templates as partials from within templates

In file templates

This one is cool:

  get '/' do
    haml :index
  end

  use_in_file_templates!

  __END__

  ## layout
  X
  = yield
  X

  ## index
  %div.title Hello world!!!!!

Try it!

You can do this too but it’s not as cool

  template :layout do
    "X\n=yield\nX"
  end

  template :index do
    '%div.title Hello World!'
  end

  get '/' do
    haml :index
  end

Erb

This works like Haml except you use erb instead of haml

Sass

This works like Haml except you use sass instead of haml. It’s also a good idea to add header ‘Content-Type’ => ‘text/css; charset=utf-8’ before your call to sass so Sinatra returns the proper content type header with the file.

Builder

See Sinatra::Builder

Helpers

It is ill-advised to create helpers on (main). Use the handy helpers to install helper methods on Sinatra::EventContext for use inside events and templates.

Example:

  helpers do

    def bar(name)
      "#{name}bar"
    end

  end

  get '/:name' do
    bar(params[:name])
  end

Before filters

These are run in Sinatra::EventContext

  before do
    .. this code will run before each event ..
  end

Halt!

To immediately stop a request during a before filter or event use:

  throw :halt

Variations

Set the body to the result of a helper method

  throw :halt, :helper_method

Set the body to the result of a helper method after sending it parameters from the local scope

  throw :halt, [:helper_method, foo, bar]

Set the body to a simple string

  throw :halt, 'this will be the body'

Set status then the body

  throw :halt, [401, 'go away!']

Set the status then call a helper method with params from local scope

  throw :halt, [401, [:helper_method, foo, bar]]

Run a proc inside the Sinatra::EventContext instance and set the body to the result

  throw :halt, lambda { puts 'In a proc!'; 'I just wrote to $stdout!' }

Create you own to_result

  class MyResultObject
    def to_result(event_context, *args)
      event_context.body = 'This will be the body!
    end
  end

  get '/' do
    throw :halt, MyResultObject.new
  end

Get the gist? If you want more fun with this then checkout to_result on Array, Symbol, Fixnum, NilClass.

Configuration & Re-loading

Sinatra supports multiple environments and re-loading. Re-loading happens on every request when in :development. Wrap your configurations in configure (i.e. Database connections, Constants, etc.) to protect them from re-loading and to only work in certain environments.

All environments:

  configure do

  end

Production

  configure :production do

  end

Two at a time:

  configure :production, :test do

  end

This is also really nifty for error handling.

Error handling

Not Found

Remember: These are run inside the Sinatra::EventContext which means you get all the goodies is has to offer (i.e. haml, erb, :halt, etc.)

Whenever NotFound is raised this will be called

  not_found do
    'This is nowhere to be found'
  end

Error

By default error will catch Sinatra::ServerError

Sinatra will pass you the error via the ‘sinatra.error’ in request.env

  error do
    'Sorry there was a nasty error - ' + request.env['sinatra.error'].name
  end

Custom error mapping:

  error MyCustomError do
    'So what happened was...' + request.env['sinatra.env'].message
  end

then if this happens:

  get '/' do
    raise MyCustomError, 'something bad'
  end

you gets this:

  So what happened was... something bad

one guess what this does ;)

  not_found do
    'I have no clue what you're looking for'
  end

Try it!

Because Sinatra give you a default not_found and error do :production that are secure. If you want to customize only for :production but want to keep the friendly helper screens for :development then do this:

  configure :production do

    not_found do
      "We're so sorry, but we don't what this is"
    end

    error do
      "Something really nasty happened.  We're on it!"
    end

  end

Mime types

When using send_file or static files you may have mime types Sinatra doesn’t understand. Use mime in those cases.

  mime :foo, 'text/foo'

Testing

Test/Unit

  require 'my_sinatra_app'
  require 'sinatra/test/unit'

  class MyAppTest < Test::Unit::TestCase

    def test_my_default
      get_it '/'
      assert_equal 'My Default Page!', @response.body
    end

    def test_with_agent
      get_it '/', :agent => 'Songbird'
      assert_equal 'You're in Songbird!', @response.body
    end

    ...

  end

Test/Spec

  require 'my_sinatra_app'
  require 'sinatra/test/spec'

  context 'My app'

    should "show a default page" do
      get_it '/'
      should.be.ok
      body.should.equal 'My Default Page!'
    end
    ...

  end

Test helpers

See Sinatra::Test::Methods

Irb

This will be back in soon

Command line

Run your sinatra file like:

  ruby myapp.rb [options]

Options are:

  -h # help
  -p # set the port (default is 4567)
  -e # set the environment (default is development)
  -x # turn on the mutext lock (default is off)

Contribute

  cd where/you/keep/your/projects
  git clone git://github.com/bmizerany/sinatra.git
  cd your_project
  ln -s ../sinatra/

at the top of your sinatra.rb file

  $:.unshift File.dirname(__FILE__) + '/sinatra/lib'
  require 'sinatra'

  get '/about' do
    "I'm running on Version " + Sinatra::Version.combined
  end