README.rdoc in rtomayko-sinatra-0.9.0 vs README.rdoc in rtomayko-sinatra-0.9.0.2
- old
+ new
@@ -1,12 +1,10 @@
= Sinatra
Sinatra is a DSL for quickly creating web-applications in Ruby with minimal
-effort.
+effort:
-== Sample App
-
# myapp.rb
require 'rubygems'
require 'sinatra'
get '/' do
'Hello world!'
@@ -30,14 +28,10 @@
delete '/' do
.. annihilate something ..
end
- head '/' do
-
- end
-
== Routes
Routes are matched based on the order of declaration. The first route that
matches the request is invoked.
@@ -45,18 +39,21 @@
get '/hi' do
...
end
-Named parameters:
+Route patterns may include named parameters, accessible via the
+<tt>params</tt> hash:
get '/:name' do
# matches "GET /foo" and "GET /bar"
# params[:name] is 'foo' or 'bar'
+ "Hello #{params[:name]}!"
end
-Splat parameters:
+Route patterns may also include splat (or wildcard) parameters, accessible
+via the <tt>params[:splat]</tt> array.
get '/say/*/to/*' do
# matches /say/hello/to/world
params[:splat] # => ["hello", "world"]
end
@@ -64,62 +61,73 @@
get '/download/*.*' do
# matches /download/path/to/file.xml
params[:splat] # => ["path/to/file", "xml"]
end
-User agent matching:
+Route matching with Regular Expressions:
+ get %r{/hello/([\w]+)} do
+ "Hello, #{params[:captures].first}!"
+ end
+
+Routes may include a variety of matching conditions, such as the user 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
+Static files are served from the <tt>./public</tt> directory. You can specify
+a different location by setting the <tt>:public</tt> option:
- root
- \ public
-
-To use a different static directory:
-
set :public, File.dirname(__FILE__) + '/static'
-== Views
+== Views / Templates
-Views are searched for in a ./views directory in the same location as
-your main application.
+Templates are assumed to be located directly under a <tt>./views</tt>
+directory. To use a different views directory:
-To use a different views directory:
-
set :views, File.dirname(__FILE__) + '/templates'
=== Haml Templates
+The haml gem/library is required to render HAML templates:
+
get '/' do
haml :index
end
Renders <tt>./views/index.haml</tt>.
-=== Erb
+=== Erb Templates
get '/' do
erb :index
end
Renders <tt>./views/index.erb</tt>
-=== Builder
+=== Builder Templates
-See Sinatra::Builder
+The builder gem/library is required to render builder templates:
-=== Sass
+ get '/' do
+ content_type 'application/xml', :charset => 'utf-8'
+ builder :index
+ end
+Renders <tt>./views/index.builder</tt>.
+
+=== Sass Templates
+
+The sass gem/library is required to render Sass templates:
+
get '/stylesheet.css' do
content_type 'text/css', :charset => 'utf-8'
sass :stylesheet
end
@@ -133,13 +141,12 @@
Renders the inlined template string.
=== Accessing Variables
-Templates are evaluated within the Sinatra::EventContext instance
-used to evaluate event blocks. Instance variables set in event
-blocks can be accessed direcly in views:
+Templates are evaluated within the same context as the route blocks. Instance
+variables set in route blocks are available in templates:
get '/:id' do
@foo = Foo.find(params[:id])
haml '%h1= @foo.name'
end
@@ -156,44 +163,57 @@
=== In-file Templates
Templates may be defined at the end of the source file:
+ require 'rubygems'
+ require 'sinatra'
+
get '/' do
haml :index
end
- use_in_file_templates!
-
__END__
@@ layout
- X
- = yield
- X
+ %html
+ = yield
@@ index
%div.title Hello world!!!!!
+NOTE: Sinatra will automaticly load any in-file-templates in the
+source file that first required sinatra. If you have in-file-templates
+in another source file you will need to explicitly call
++use_in_file_templates! on main in that file.
+
It's also possible to define named templates using the top-level template
method:
template :layout do
- "X\n=yield\nX"
+ "%html\n =yield\n"
end
template :index do
'%div.title Hello World!'
end
get '/' do
haml :index
end
+If a template named "layout" exists, it will be used each time a template
+is rendered. You can disable layouts by passing <tt>:layout => false</tt>.
+
+ get '/' do
+ haml :index, :layout => !request.xhr?
+ end
+
== Helpers
-The top-level <tt>helpers</tt> method
+Use the top-level <tt>helpers</tt> method to define helper methods for use in
+route blocks and templates:
helpers do
def bar(name)
"#{name}bar"
end
@@ -203,11 +223,13 @@
bar(params[:name])
end
== Filters
-Before filters are evaluated in request context before routing is performed:
+Before filters are evaluated before each request within the context of the
+request and can modify the request and response. Instance variables set in
+filters are accessible by routes and templates.
before do
@note = 'Hi!'
request.path_info = '/foo/bar/baz'
end
@@ -215,83 +237,92 @@
get '/foo/*' do
@note #=> 'Hi!'
params[:splat] #=> 'bar/baz'
end
-Before filters can modify the request and response; instance variables are
-available to routes.
+== Halting
-== Halt!
+To immediately stop a request during a before filter or route use:
-To immediately stop a request during a before filter or event use:
+ halt
- throw :halt
+You can also specify a body when halting ...
-Set the body to a simple string
+ halt 'this will be the body'
- throw :halt, 'this will be the body'
+Set the status and body ...
-Set status then the body
+ halt 401, 'go away!'
- throw :halt, [401, 'go away!']
+== Passing
-Run a proc inside the Sinatra::EventContext instance and set the body to the
-result
+A route can punt processing to the next matching route using the <tt>pass</tt>
+statement:
- throw :halt, lambda { puts 'In a proc!'; 'I just wrote to $stdout!' }
+ get '/guess/:who' do
+ pass unless params[:who] == 'Frank'
+ "You got me!"
+ end
+ get '/guess/*' do
+ "You missed!"
+ end
+
+The route block is immediately exited and control continues with the next
+matching route. If no matching route is found, a 404 is returned.
+
== Configuration and Reloading
Sinatra supports multiple environments and reloading. Reloading happens
-before every request when running under the :development environment. Wrap
-your configurations in <tt>configure</tt> (i.e. Database connections, Constants,
-etc.) to protect them from reloading or to target specific environments.
+before each request when running under the <tt>:development</tt>
+environment. Wrap your configurations (e.g., database connections, constants,
+etc.) in <tt>configure</tt> blocks to protect them from reloading or to
+target specific environments.
-All environments:
+Run once, at startup, in any environment:
configure do
...
end
-Production:
+Run only when the environment (RACK_ENV environment variable) is set to
+<tt>:production</tt>.
configure :production do
...
end
-Two at a time:
+Run when the environment (RACK_ENV environment variable) is set to
+either <tt>:production</tt> or <tt>:test</tt>.
configure :production, :test do
...
end
-This is also really nifty for error handling.
-
== Error handling
-Error handlers run inside the current Sinatra::EventContext instance, which
-means you get all the goodies it has to offer (i.e. haml, erb, throw :halt,
-etc.)
+Error handlers run within the same context as routes and before filters, which
+means you get all the goodies it has to offer, like <tt>haml</tt>, <tt>erb</tt>,
+<tt>halt</tt>, etc.
=== Not Found
-When Sinatra::NotFound is raised, the not_found handler is invoked:
+When a <tt>Sinatra::NotFound</tt> exception is raised, or the response's status
+code is 404, the <tt>not_found</tt> handler is invoked:
not_found do
'This is nowhere to be found'
end
=== Error
-By default, the +error+ handler is invoked on Sinatra::ServerError or when
-an unknown error occurs.
+The +error+ handler is invoked any time an exception is raised from a route
+block or before filter. The exception object can be obtained from the
+'sinatra.error' Rack variable:
-The exception can be obtained from the 'sinatra.error' variable in
-request.env.
-
error do
- 'Sorry there was a nasty error - ' + request.env['sinatra.error'].name
+ 'Sorry there was a nasty error - ' + env['sinatra.error'].name
end
Custom errors:
error MyCustomError do
@@ -307,16 +338,16 @@
You get this:
So what happened was... something bad
Sinatra installs special not_found and error handlers when running under
-the development.
+the development environment.
== Mime types
-When using send_file or static files you may have mime types Sinatra doesn't
-understand. Use +mime+ in those cases.
+When using <tt>send_file</tt> or static files you may have mime types Sinatra
+doesn't understand. Use +mime+ to register them by file extension:
mime :foo, 'text/foo'
== Rack Middleware
@@ -353,85 +384,102 @@
many of of these components automatically based on configuration so you
typically don't have to +use+ them explicitly.
== Testing
-=== Test/Unit
+The Sinatra::Test module includes a variety of helper methods for testing
+your Sinatra app. Sinatra includes support for Test::Unit, test-spec, RSpec,
+and Bacon through separate source files.
- require 'rubygems'
+=== Test::Unit
+
require 'sinatra'
require 'sinatra/test/unit'
require 'my_sinatra_app'
class MyAppTest < Test::Unit::TestCase
-
def test_my_default
- get_it '/'
+ get '/'
assert_equal 'My Default Page!', @response.body
end
def test_with_agent
- get_it '/', :agent => 'Songbird'
+ get '/', :agent => 'Songbird'
assert_equal 'You're in Songbird!', @response.body
end
...
-
end
-=== Test/Spec
+=== Test::Spec
- require 'rubygems'
+Install the test-spec gem and require <tt>'sinatra/test/spec'</tt> before
+your app:
+
require 'sinatra'
require 'sinatra/test/spec'
require 'my_sinatra_app'
describe 'My app' do
-
it "should show a default page" do
- get_it '/'
+ get '/'
should.be.ok
body.should.equal 'My Default Page!'
end
...
-
end
=== RSpec
- require 'rubygems'
- require 'spec'
+Install the rspec gem and require <tt>'sinatra/test/rspec'</tt> before
+your app:
+
require 'sinatra'
require 'sinatra/test/rspec'
require 'my_sinatra_app'
describe 'My app' do
it 'should show a default page' do
- get_it '/'
+ get '/'
@response.should be_ok
@response.body.should == 'My Default Page!'
end
...
end
-See Sinatra::Test::Methods for more information on +get_it+, +post_it+,
-+put_it+, and friends.
+=== Bacon
+ require 'sinatra'
+ require 'sinatra/test/bacon'
+ require 'my_sinatra_app'
+
+ describe 'My app' do
+ it 'should be ok' do
+ get '/'
+ should.be.ok
+ body.should == 'Im OK'
+ end
+ end
+
+See Sinatra::Test for more information on +get+, +post+, +put+, and
+friends.
+
== Command line
Sinatra applications can be run directly:
- ruby myapp.rb [-h] [-x] [-p PORT] [-e ENVIRONMENT]
+ ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-s HANDLER]
Options are:
-h # help
-p # set the port (default is 4567)
-e # set the environment (default is development)
+ -s # specify rack server/handler (default is thin)
-x # turn on the mutex lock (default is off)
== Contributing
=== Tools
@@ -439,18 +487,18 @@
Besides Ruby itself, you only need a text editor, preferably one that supports
Ruby syntax hilighting. VIM and Emacs are a fine choice on any platform, but
feel free to use whatever you're familiar with.
Sinatra uses the Git source code management system. If you're unfamiliar with
-Git, you can find more information and tutorials on http://git.or.cz/ as well
-as http://git-scm.com/. Scott Chacon created a great series of introductory
-screencasts about Git, which you can find here: http://www.gitcasts.com/
+Git, you can find more information and tutorials on http://git.or.cz as well
+as http://git-scm.com. Scott Chacon created a great series of introductory
+screencasts about Git, which you can find here: http://www.gitcasts.com
=== First Time: Cloning The Sinatra Repo
cd where/you/keep/your/projects
- git clone git://github.com/bmizerany/sinatra.git
+ git clone git://github.com/sinatra/sinatra.git
cd sinatra
cd path/to/your_project
ln -s ../sinatra/
=== Updating Your Existing Sinatra Clone
@@ -460,30 +508,29 @@
=== Using Edge Sinatra in Your App
at the top of your sinatra_app.rb file:
- $:.unshift File.dirname(__FILE__) + '/sinatra/lib'
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/sinatra/lib'
require 'sinatra'
get '/about' do
"I'm running on Version " + Sinatra::VERSION
end
=== Contributing a Patch
There are several ways to do this. Probably the easiest (and preferred) way is
-to fork Sinatra on GitHub (http://github.com/bmizerany/sinatra), push your
-changes to your Sinatra repo, and then send Blake Mizerany (bmizerany on
-GitHub) a pull request.
+to fork Sinatra on GitHub (http://github.com/sinatra/sinatra), push your
+changes to your Sinatra repo and file a ticket in lighthouse (sinatra.lighthouseapp.com) where we can discuss it.
You can also create a patch file and attach it to a feature request or bug fix
on the issue tracker (see below) or send it to the mailing list (see Community
section).
=== Issue Tracking and Feature Requests
-http://sinatra.lighthouseapp.com/
+http://sinatra.lighthouseapp.com
== Community
=== Mailing List