Sinatra is a DSL for quickly creating web applications in Ruby with minimal effort:
# myapp.rb
require 'sinatra'
get '/' do
'Hello world!'
end
Install the gems needed:
gem install sinatra rackup puma
And run with:
ruby myapp.rb
View at: http://localhost:4567
The code you changed will not take effect until you restart the server. Please restart the server every time you change or use a code reloader like rerun or rack-unreloader.
yield and nested layoutsIn Sinatra, a route is an HTTP method paired with a URL-matching pattern. Each route is associated with a block:
get '/' do
.. show something ..
end
post '/' do
.. create something ..
end
put '/' do
.. replace something ..
end
patch '/' do
.. modify something ..
end
delete '/' do
.. annihilate something ..
end
options '/' do
.. appease something ..
end
link '/' do
.. affiliate something ..
end
unlink '/' do
.. separate something ..
end
Routes are matched in the order they are defined. The first route that matches the request is invoked.
Routes with trailing slashes are different from the ones without:
get '/foo' do
# Does not match "GET /foo/"
end
Route patterns may include named parameters, accessible via the
params hash:
get '/hello/:name' do
# matches "GET /hello/foo" and "GET /hello/bar"
# params['name'] is 'foo' or 'bar'
"Hello #{params['name']}!"
end
You can also access named parameters via block parameters:
get '/hello/:name' do |n|
# matches "GET /hello/foo" and "GET /hello/bar"
# params['name'] is 'foo' or 'bar'
# n stores params['name']
"Hello #{n}!"
end
Route patterns may also include splat (or wildcard) parameters, accessible
via the params['splat'] array:
get '/say/*/to/*' do
# matches /say/hello/to/world
params['splat'] # => ["hello", "world"]
end
get '/download/*.*' do
# matches /download/path/to/file.xml
params['splat'] # => ["path/to/file", "xml"]
end
Or with block parameters:
get '/download/*.*' do |path, ext|
[path, ext] # => ["path/to/file", "xml"]
end
Route matching with Regular Expressions:
get /\/hello\/([\w]+)/ do
"Hello, #{params['captures'].first}!"
end
Or with a block parameter:
get %r{/hello/([\w]+)} do |c|
# Matches "GET /meta/hello/world", "GET /hello/world/1234" etc.
"Hello, #{c}!"
end
Route patterns may have optional parameters:
get '/posts/:format?' do
# matches "GET /posts/" and any extension "GET /posts/json", "GET /posts/xml" etc
end
Routes may also utilize query parameters:
get '/posts' do
# matches "GET /posts?title=foo&author=bar"
title = params['title']
author = params['author']
# uses title and author variables; query is optional to the /posts route
end
By the way, unless you disable the path traversal attack protection (see below), the request path might be modified before matching against your routes.
You may customize the Mustermann
options used for a given route by passing in a :mustermann_opts hash:
get '\A/posts\z', :mustermann_opts => { :type => :regexp, :check_anchors => false } do
# matches /posts exactly, with explicit anchoring
"If you match an anchored pattern clap your hands!"
end
It looks like a condition, but it isn't one! These options will
be merged into the global :mustermann_opts hash described
below.
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
Other available conditions are host_name and provides:
get '/', :host_name => /^admin\./ do
"Admin Area, Access denied!"
end
get '/', :provides => 'html' do
haml :index
end
get '/', :provides => ['rss', 'atom', 'xml'] do
builder :feed
end
provides searches the request's Accept header.
You can easily define your own conditions:
set(:probability) { |value| condition { rand <= value } }
get '/win_a_car', :probability => 0.1 do
"You won!"
end
get '/win_a_car' do
"Sorry, you lost."
end
For a condition that takes multiple values use a splat:
set(:auth) do |*roles| # <- notice the splat here
condition do
unless logged_in? && roles.any? {|role| current_user.in_role? role }
redirect "/login/", 303
end
end
end
get "/my/account/", :auth => [:user, :admin] do
"Your Account Details"
end
get "/only/admin/", :auth => :admin do
"Only admins are allowed here!"
end
The return value of a route block determines at least the response body passed on to the HTTP client or at least the next middleware in the Rack stack. Most commonly, this is a string, as in the above examples. But other values are also accepted.
You can return an object that would either be a valid Rack response, Rack body object or HTTP status code:
[status (Integer), headers (Hash), response
body (responds to #each)][status (Integer), response body (responds to
#each)]#each and passes nothing but strings to
the given blockThat way we can, for instance, easily implement a streaming example:
class Stream
def each
100.times { |i| yield "#{i}\n" }
end
end
get('/') { Stream.new }
You can also use the stream helper method (described below) to reduce
boilerplate and embed the streaming logic in the route.
As shown above, Sinatra ships with built-in support for using String patterns and regular expressions as route matches. However, it does not stop there. You can easily define your own matchers:
class AllButPattern
def initialize(except)
@except = except
end
def to_pattern(options)
return self
end
def params(route)
return {} unless @except === route
end
end
def all_but(pattern)
AllButPattern.new(pattern)
end
get all_but("/index") do
# ...
end
Note that the above example might be over-engineered, as it can also be expressed as:
get /.*/ do
pass if request.path_info == "/index"
# ...
end
Static files are served from the ./public directory. You can specify
a different location by setting
| 日期 | 榜单 | 排名 | 周期新增 | 总 STAR |
|---|