Browse files

Change code blocks to use triple-backtick form, including noting ruby…

… where appropriate
  • Loading branch information...
1 parent 1caf703 commit cdd114c60721dd75de11f2cf1f69061c8991cc2e @cschneid cschneid committed Nov 3, 2012
View
12 book/Deployment.markdown
@@ -21,16 +21,20 @@ Steps to deploy to Heroku:
`myapp.rb`. Second, run your application. If you're subclassing, use the
subclass's name, otherwise use Sinatra::Application.
- require "myapp"
+```ruby
+require "myapp"
- run Sinatra::Application
+run Sinatra::Application
+```
2. Create the app and push to it
From the root-directory of the application
- $ heroku create <app-name> # This will add heroku as a remote
- $ git push heroku master
+```
+$ heroku create <app-name> # This will add heroku as a remote
+$ git push heroku master
+```
For more details see [this](http://github.com/sinatra/heroku-sinatra-app)
View
12 book/Development.markdown
@@ -17,14 +17,18 @@ available on Windows and JRuby.
Usage is rather simple:
- gem install shotgun # run only once, to install shotgun
- shotgun my_app.rb
+```ruby
+gem install shotgun # run only once, to install shotgun
+shotgun my_app.rb
+```
If you want to run a modular application, create a file named `config.ru` with
similar content:
- require 'my_app'
- run MyApp
+```ruby
+require 'my_app'
+run MyApp
+```
And run it by calling `shotgun` without arguments.
View
154 book/Getting_to_know_Sinatra.markdown
@@ -24,27 +24,29 @@ users will navigate the actions you define for your application.
They also enable to you create [RESTful web services][restful-web-services], in
a very obvious manner. Here's an example of how one-such service might look:
- get '/dogs' do
- # get a listing of all the dogs
- end
-
- get '/dog/:id' do
- # just get one dog, you might find him like this:
- @dog = Dog.find(params[:id])
- # using the params convention, you specified in your route
- end
-
- post '/dog' do
- # create a new dog listing
- end
-
- put '/dog/:id' do
- # HTTP PUT request method to update an existing dog
- end
-
- delete '/dog/:id' do
- # HTTP DELETE request method to remove a dog who's been sold!
- end
+```ruby
+get '/dogs' do
+ # get a listing of all the dogs
+end
+
+get '/dog/:id' do
+ # just get one dog, you might find him like this:
+ @dog = Dog.find(params[:id])
+ # using the params convention, you specified in your route
+end
+
+post '/dog' do
+ # create a new dog listing
+end
+
+put '/dog/:id' do
+ # HTTP PUT request method to update an existing dog
+end
+
+delete '/dog/:id' do
+ # HTTP DELETE request method to remove a dog who's been sold!
+end
+```
As you can see from this contrived example, Sinatra's routing is very easy to get
along with. Don't be fooled, though, Sinatra can do some pretty amazing things
@@ -69,14 +71,16 @@ match to the request.
The `before` method will let you pass a block to be evaluated **before** _each_
and _every_ route gets processed.
- before do
- MyStore.connect unless MyStore.connected?
- end
+```ruby
+before do
+ MyStore.connect unless MyStore.connected?
+end
- get '/' do
- @list = MyStore.find(:all)
- erb :index
- end
+get '/' do
+ @list = MyStore.find(:all)
+ erb :index
+end
+```
In this example, we've set up a `before` filter to connect using a contrived
`MyStore` module.
@@ -86,9 +90,11 @@ In this example, we've set up a `before` filter to connect using a contrived
The `after` method lets you pass a block to be evaluated **after** _each_ and
_every_ route gets processed.
- after do
- MyStore.disconnect
- end
+```ruby
+after do
+ MyStore.disconnect
+end
+```
As you can see from this example, we're asking the `MyStore` module to
disconnect after the request has been processed.
@@ -99,9 +105,11 @@ Filters optionally take a pattern to be matched against the requested URI
during processing. Here's a quick example you could use to run a contrived
`authenticate!` method before accessing any "admin" type requests.
- before '/admin/*' do
- authenticate!
- end
+```ruby
+before '/admin/*' do
+ authenticate!
+end
+```
[filters]: http://www.sinatrarb.com/intro#Filters
@@ -113,25 +121,31 @@ routines. For instance there are handlers for [halting][halting] and
There are also handlers for redirection:
- get '/' do
- redirect '/someplace/else'
- end
-
+```ruby
+ get '/' do
+ redirect '/someplace/else'
+end
+```
+
This will return a 302 HTTP Response to `/someplace/else`.
You can even use the Sinatra handler for sessions, just add this to your
application or to a configure block:
- enable :sessions
+```ruby
+enable :sessions
+```
Then you will be able to use the default cookie based session handler in your
application:
- get '/' do
- session['counter'] ||= 0
- session['counter'] += 1
- "You've hit this page #{session['counter']} times!"
- end
+```ruby
+get '/' do
+ session['counter'] ||= 0
+ session['counter'] += 1
+ "You've hit this page #{session['counter']} times!"
+end
+```
Handlers can be extremely useful when used properly, probably the most common
use is the `params` convention, which gives you access to any parameters passed
@@ -165,29 +179,35 @@ default look in the `views` directory in your application root.
So in your route you would have:
- get '/' do
- erb :index # renders views/index.erb
- end
+```ruby
+get '/' do
+ erb :index # renders views/index.erb
+end
+```
or to specify a template located in a subdirectory
- get '/' do
- erb :"dogs/index"
- # would instead render views/dogs/index.erb
- end
+```ruby
+get '/' do
+ erb :"dogs/index"
+ # would instead render views/dogs/index.erb
+end
+```
Another default convention of Sinatra, is the layout, which automatically looks
for a `views/layout` template file to render before loading any other views. In
the case of using `erb`, your `views/layout.erb` would look something like
this:
- <html>
- <head>..</head>
- <body>
- <%= yield %>
- </body>
- </html>
+```ruby
+<html>
+ <head>..</head>
+ <body>
+ <%= yield %>
+ </body>
+</html>
+```
The possibilities are pretty much endless, here's a quick list of some of the
most common use-cases covered in the README:
@@ -211,14 +231,16 @@ For more specific details on how Sinatra handles templates, check the [README][t
Helpers are a great way to provide reusable code snippets in your application.
- helpers do
- def bar(name)
- "#{name}bar"
- end
- end
-
- get '/:name' do
- bar(params[:name])
- end
+```ruby
+helpers do
+ def bar(name)
+ "#{name}bar"
+ end
+end
+
+get '/:name' do
+ bar(params[:name])
+end
+```
View
58 book/Helpers.markdown
@@ -9,35 +9,39 @@ design, you'll have to implement a partial handler yourself.
Here is a really basic version:
- # Usage: partial :foo
- helpers do
- def partial(page, options={})
- haml page, options.merge!(:layout => false)
- end
- end
+```ruby
+# Usage: partial :foo
+helpers do
+ def partial(page, options={})
+ haml page, options.merge!(:layout => false)
+ end
+end
+```
A more advanced version that would handle passing local options, and looping over a hash would look like:
- # Render the page once:
- # Usage: partial :foo
- #
- # foo will be rendered once for each element in the array, passing in a local variable named "foo"
- # Usage: partial :foo, :collection => @my_foos
+```ruby
+# Render the page once:
+# Usage: partial :foo
+#
+# foo will be rendered once for each element in the array, passing in a local variable named "foo"
+# Usage: partial :foo, :collection => @my_foos
- helpers do
- def partial(template, *args)
- options = args.extract_options!
- options.merge!(:layout => false)
- if collection = options.delete(:collection) then
- collection.inject([]) do |buffer, member|
- buffer << haml(template, options.merge(
- :layout => false,
- :locals => {template.to_sym => member}
- )
- )
- end.join("\n")
- else
- haml(template, options)
- end
- end
+helpers do
+ def partial(template, *args)
+ options = args.extract_options!
+ options.merge!(:layout => false)
+ if collection = options.delete(:collection) then
+ collection.inject([]) do |buffer, member|
+ buffer << haml(template, options.merge(
+ :layout => false,
+ :locals => {template.to_sym => member}
+ )
+ )
+ end.join("\n")
+ else
+ haml(template, options)
end
+ end
+end
+```
View
42 book/Introduction.markdown
@@ -32,7 +32,9 @@ Installation
------------
The simplest way to install Sinatra is through Rubygems:
- $ gem install sinatra
+```
+$ gem install sinatra
+```
### Dependencies
@@ -44,7 +46,9 @@ For optimal experience, you should install the template engines you want to
work with. The Sinatra dev team suggests using either ERB, which is included
with Ruby, or installing HAML as your first template language.
- $ gem install haml
+```
+$ gem install haml
+```
### Living on the Edge
@@ -55,35 +59,43 @@ You can use the _edge_ version to try new functionality or to contribute to the
framework. You need to have [Git version control
software](http://www.git-scm.com) and [bundler](http://gembundler.com/).
- gem install bundler
+```
+$ gem install bundler
+```
To use Sinatra _edge_ with bundler, you'll have to create a `Gemfile` listing
Sinatra's and any other dependencies you're going to need.
- source :rubygems
- gem 'sinatra', :git => 'git://github.com/sinatra/sinatra.git'
+```ruby
+source :rubygems
+gem 'sinatra', :git => 'git://github.com/sinatra/sinatra.git'
+```
Here we use the gemcutter source to specify where to get Sinatra's
dependencies; alternatively you can use the git version, but that is up to you.
So now we can install our bundle:
- bundle install
+```
+$ bundle install
+```
Hello World Application
-----------------------
Sinatra is installed, how about making your first application?
- require 'rubygems'
+```ruby
+require 'rubygems'
- # If you're using bundler, you will need to add this
- require 'bundler/setup'
-
- require 'sinatra'
-
- get '/' do
- "Hello world, it's #{Time.now} at the server!"
- end
+# If you're using bundler, you will need to add this
+require 'bundler/setup'
+
+require 'sinatra'
+
+get '/' do
+ "Hello world, it's #{Time.now} at the server!"
+end
+```
Run this application by `$ ruby hello_world.rb` and load
`http://localhost:4567` in your browser.
View
28 book/Middleware.markdown
@@ -9,25 +9,29 @@ request/response to provide various types of common functionality.
Sinatra makes building Rack middleware pipelines a cinch via a top-level `use` method:
- require 'sinatra'
- require 'my_custom_middleware'
-
- use Rack::Lint
- use MyCustomMiddleware
-
- get '/hello' do
- 'Hello World'
- end
+```ruby
+require 'sinatra'
+require 'my_custom_middleware'
+
+use Rack::Lint
+use MyCustomMiddleware
+
+get '/hello' do
+ 'Hello World'
+end
+```
## Rack HTTP Basic Authentication
The semantics of "use" are identical to those defined for the
[Rack::Builder][rack_builder] DSL (most frequently used from rackup files). For
example, the use method accepts multiple/variable args as well as blocks:
- use Rack::Auth::Basic do |username, password|
- username == 'admin' && password == 'secret'
- end
+```ruby
+use Rack::Auth::Basic do |username, password|
+ username == 'admin' && password == 'secret'
+end
+```
Rack is distributed with a variety of standard middleware for logging,
debugging, URL routing, authentication, and session handling. Sinatra uses many
View
66 book/Models.markdown
@@ -8,43 +8,49 @@ Start out by getting the DataMapper gem if you don't already have it, and then
making sure it's in your application. A call to `setup` as usual will get the
show started, and this example will include a 'Post' model.
- require 'rubygems'
- require 'sinatra'
- require 'data_mapper' # metagem, requires common plugins too.
-
- # need install dm-sqlite-adapter
- DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/blog.db")
-
- class Post
- include DataMapper::Resource
- property :id, Serial
- property :title, String
- property :body, Text
- property :created_at, DateTime
- end
-
- # Perform basic sanity checks and initialize all relationships
- # Call this when you've defined all your models
- DataMapper.finalize
-
- # automatically create the post table
- Post.auto_upgrade!
+```ruby
+require 'rubygems'
+require 'sinatra'
+require 'data_mapper' # metagem, requires common plugins too.
+
+# need install dm-sqlite-adapter
+DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/blog.db")
+
+class Post
+ include DataMapper::Resource
+ property :id, Serial
+ property :title, String
+ property :body, Text
+ property :created_at, DateTime
+end
+
+# Perform basic sanity checks and initialize all relationships
+# Call this when you've defined all your models
+DataMapper.finalize
+
+# automatically create the post table
+Post.auto_upgrade!
+```
Once that is all well and good, you can actually start developing your
application!
- get '/' do
- # get the latest 20 posts
- @posts = Post.all(:order => [ :id.desc ], :limit => 20)
- erb :index
- end
+```ruby
+get '/' do
+ # get the latest 20 posts
+ @posts = Post.all(:order => [ :id.desc ], :limit => 20)
+ erb :index
+end
+```
Finally, the view at `./view/index.html`:
- <% @posts.each do |post| %>
- <h3><%= post.title %></h3>
- <p><%= post.body %></p>
- <% end %>
+```ruby
+<% @posts.each do |post| %>
+ <h3><%= post.title %></h3>
+ <p><%= post.body %></p>
+<% end %>
+```
For more information on DataMapper, check out the [project
documentation](http://datamapper.org/docs/ "DataMapper").
View
62 book/Organizing_your_application.markdown
@@ -26,41 +26,47 @@ This one is trickier. My advice is to look to Rails for advice. They have a
well structured set of directories to hold many of the components that make up
a larger application. Remember that this file structure is just a suggestion.
- |- config.ru # A rackup file. Load server.rb, and
- |- server.rb # Loads all files, is the base class
- |- app/
- \--- routes/
- \------ users.rb
- \--- models/
- \------ user.rb # Model. Database or not
- \--- views/
- \------ users/
- \--------- index.erb
- \--------- new.erb
- \--------- show.erb
+```
+|- config.ru # A rackup file. Load server.rb, and
+|- server.rb # Loads all files, is the base class
+|- app/
+\--- routes/
+\------ users.rb
+\--- models/
+\------ user.rb # Model. Database or not
+\--- views/
+\------ users/
+\--------- index.erb
+\--------- new.erb
+\--------- show.erb
+```
In `server.rb` it should be a barebones application.
- class Server < Sinatra::Base
- configure do
- # Load up database and such
- end
- end
+```ruby
+class Server < Sinatra::Base
+ configure do
+ # Load up database and such
+ end
+end
- # Load all route files
- Dir[File.dirname(__FILE___) + "/app/routes/**"].each do |route|
- require route
- end
+# Load all route files
+Dir[File.dirname(__FILE___) + "/app/routes/**"].each do |route|
+ require route
+end
+```
And the route files look something like:
- # users.rb
- class Server < Sinatra::Base
- get '/users/:id' do
- erb :"users/show"
- end
+```ruby
+# users.rb
+class Server < Sinatra::Base
+ get '/users/:id' do
+ erb :"users/show"
+ end
- # ...
- end
+ # more routes...
+end
+```
View
148 book/Testing.markdown
@@ -22,75 +22,87 @@ testing.
Imagine you have an application like this:
- # myapp.rb
- require 'sinatra'
-
- get '/' do
- "Welcome to my page!"
- end
-
- post '/' do
- "Hello #{params[:name]}!"
- end
+```ruby
+# myapp.rb
+require 'sinatra'
+
+get '/' do
+ "Welcome to my page!"
+end
+
+post '/' do
+ "Hello #{params[:name]}!"
+end
+```
You have to define an `app` method pointing to your application class (which is
`Sinatra::Application` per default):
- begin
- # try to use require_relative first
- # this only works for 1.9
- require_relative 'my-app.rb'
- rescue NameError
- # oops, must be using 1.8
- # no problem, this will load it then
- require File.expand_path('my-app.rb', __FILE__)
- end
-
- require 'test/unit'
- require 'rack/test'
-
- class MyAppTest < Test::Unit::TestCase
- include Rack::Test::Methods
-
- def app
- Sinatra::Application
- end
-
- def test_my_default
- get '/'
- assert last_response.ok?
- assert_equal 'Welcome to my page!', last_response.body
- end
-
- def test_with_params
- post '/', :name => 'Frank'
- assert_equal 'Hello Frank!', last_response.body
- end
- end
+```ruby
+begin
+ # try to use require_relative first
+ # this only works for 1.9
+ require_relative 'my-app.rb'
+rescue NameError
+ # oops, must be using 1.8
+ # no problem, this will load it then
+ require File.expand_path('my-app.rb', __FILE__)
+end
+
+require 'test/unit'
+require 'rack/test'
+
+class MyAppTest < Test::Unit::TestCase
+ include Rack::Test::Methods
+
+ def app
+ Sinatra::Application
+ end
+
+ def test_my_default
+ get '/'
+ assert last_response.ok?
+ assert_equal 'Welcome to my page!', last_response.body
+ end
+
+ def test_with_params
+ post '/', :name => 'Frank'
+ assert_equal 'Hello Frank!', last_response.body
+ end
+end
+```
### Modifying `env`
While parameters can be send via the second argument of a get/post/put/delete
call (see the post example above), the env hash (and thereby the HTTP headers)
can be modified with a third argument:
- get '/foo', {}, 'HTTP_USER_AGENT' => 'Songbird 1.0'
+```ruby
+get '/foo', {}, 'HTTP_USER_AGENT' => 'Songbird 1.0'
+```
This also allows passing internal `env` settings:
- get '/foo', {}, 'rack.session' => { 'user_id' => 20 }
+```ruby
+get '/foo', {}, 'rack.session' => { 'user_id' => 20 }
+```
### Cookies
For example, add the following to your app to test against:
- "Hello #{request.cookies['foo']}!"
+```ruby
+"Hello #{request.cookies['foo']}!"
+```
Use `set_cookie` for setting and removing cookies, and the access them in your response:
- response.set_cookie 'foo=bar'
- get '/'
- assert_equal 'Hello bar!', last_response.body
+```ruby
+response.set_cookie 'foo=bar'
+get '/'
+assert_equal 'Hello bar!', last_response.body
+```
### Asserting Expectations About The Response
@@ -110,12 +122,14 @@ available for making assertions:
Assertions are typically made against the `last_response` object.
Consider the following examples:
- def test_it_says_hello_world
- get '/'
- assert last_response.ok?
- assert_equal 'Hello World'.length.to_s, last_response.headers['Content-Length']
- assert_equal 'Hello World', last_response.body
- end
+```ruby
+def test_it_says_hello_world
+ get '/'
+ assert last_response.ok?
+ assert_equal 'Hello World'.length.to_s, last_response.headers['Content-Length']
+ assert_equal 'Hello World', last_response.body
+end
+```
### Optional Test Setup
@@ -125,29 +139,35 @@ a method named `app`.
If you're testing a modular application that has multiple `Sinatra::Base`
subclasses, simply set the `app` method to return your particular class.
- def app
- MySinatraApp
- end
+```ruby
+def app
+ MySinatraApp
+end
+```
If you're using a classic style Sinatra application, then you need to return an
instance of `Sinatra::Application`.
- def app
- Sinatra::Application
- end
+```ruby
+def app
+ Sinatra::Application
+end
+```
### Making `Rack::Test` available to all test cases
If you'd like the `Rack::Test` methods to be available to all test cases
without having to include it each time, you can include the `Rack::Test`
module in the `Test::Unit::TestCase` class:
- require 'test/unit'
- require 'rack/test'
+```ruby
+require 'test/unit'
+require 'rack/test'
- class Test::Unit::TestCase
- include Rack::Test::Methods
- end
+class Test::Unit::TestCase
+ include Rack::Test::Methods
+end
+```
Now all `TestCase` subclasses will automatically have `Rack::Test`
available to them.
View
91 book/Views.markdown
@@ -8,28 +8,30 @@ The [builder][builder] gem/library for creating XML is required in this recipe.
Assume that your site url is `http://liftoff.msfc.nasa.gov/`.
- get '/rss.xml' do
- builder do |xml|
- xml.instruct! :xml, :version => '1.0'
- xml.rss :version => "2.0" do
- xml.channel do
- xml.title "Liftoff News"
- xml.description "Liftoff to Space Exploration."
- xml.link "http://liftoff.msfc.nasa.gov/"
-
- @posts.each do |post|
- xml.item do
- xml.title post.title
- xml.link "http://liftoff.msfc.nasa.gov/posts/#{post.id}"
- xml.description post.body
- xml.pubDate Time.parse(post.created_at.to_s).rfc822()
- xml.guid "http://liftoff.msfc.nasa.gov/posts/#{post.id}"
- end
- end
+```ruby
+get '/rss.xml' do
+ builder do |xml|
+ xml.instruct! :xml, :version => '1.0'
+ xml.rss :version => "2.0" do
+ xml.channel do
+ xml.title "Liftoff News"
+ xml.description "Liftoff to Space Exploration."
+ xml.link "http://liftoff.msfc.nasa.gov/"
+
+ @posts.each do |post|
+ xml.item do
+ xml.title post.title
+ xml.link "http://liftoff.msfc.nasa.gov/posts/#{post.id}"
+ xml.description post.body
+ xml.pubDate Time.parse(post.created_at.to_s).rfc822()
+ xml.guid "http://liftoff.msfc.nasa.gov/posts/#{post.id}"
end
end
end
end
+ end
+end
+```
This will render the RSS inline, directly from the handler.
@@ -41,12 +43,14 @@ To render CoffeeScript templates you first need the `coffee-script` gem and
Here's an example of using CoffeeScript with Sinatra's template rendering
engine Tilt:
- ## You'll need to require coffee-script in your app
- require 'coffee-script'
+```ruby
+## You'll need to require coffee-script in your app
+require 'coffee-script'
- get '/application.js' do
- coffee :application
- end
+get '/application.js' do
+ coffee :application
+end
+```
Renders `./views/application.coffee`.
@@ -55,30 +59,34 @@ on your platform of choice and hosting environment. If that's not the case, but
you'd still like to use CoffeeScript, you can precompile your scripts using the
`coffee` binary:
- coffee -c -o public/javascripts/ src/
+```
+$ coffee -c -o public/javascripts/ src/
+```
Or you can use this example [rake][rake] task to compile them for you with the
`coffee-script` gem, which can use either `therubyracer` gem or the `coffee`
binary:
- require 'coffee-script'
-
- namespace :js do
- desc "compile coffee-scripts from ./src to ./public/javascripts"
- task :compile do
- source = "#{File.dirname(__FILE__)}/src/"
- javascripts = "#{File.dirname(__FILE__)}/public/javascripts/"
-
- Dir.foreach(source) do |cf|
- unless cf == '.' || cf == '..'
- js = CoffeeScript.compile File.read("#{source}#{cf}")
- open "#{javascripts}#{cf.gsub('.coffee', '.js')}", 'w' do |f|
- f.puts js
- end
- end
- end
- end
+```ruby
+require 'coffee-script'
+
+namespace :js do
+ desc "compile coffee-scripts from ./src to ./public/javascripts"
+ task :compile do
+ source = "#{File.dirname(__FILE__)}/src/"
+ javascripts = "#{File.dirname(__FILE__)}/public/javascripts/"
+
+ Dir.foreach(source) do |cf|
+ unless cf == '.' || cf == '..'
+ js = CoffeeScript.compile File.read("#{source}#{cf}")
+ open "#{javascripts}#{cf.gsub('.coffee', '.js')}", 'w' do |f|
+ f.puts js
+ end
+ end
end
+ end
+end
+```
Now, with this rake task you can compile your coffee-scripts to
`public/javascripts` by using the `rake js:compile` command.
@@ -100,4 +108,3 @@ in your application, these are a great place to start:
[nodejs]: http://nodejs.org/
[ruby-coffee-script]: http://github.com/josh/ruby-coffee-script
-

0 comments on commit cdd114c

Please sign in to comment.