Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction à Sinatra

Introduction à Sinatra

Présentation donnée le 10 mars 2011 à ConFoo 2011 (Montréal).

Rémi Prévost

March 10, 2011
Tweet

More Decks by Rémi Prévost

Other Decks in Programming

Transcript

  1. # contenu de hello.rb require "sinatra" get "/" do "Hello

    world." end $ ruby -rubygems hello.rb => == Sinatra/1.2 has taken the stage on 4567… $ curl http://localhost:4567/ => Hello world.
  2. $ rails new blogue => create README create Rakefile create

    config.ru create .gitignore create Gemfile create app … $ du -hd0 => 428K .
  3. # contenu de config.ru class RackApp def call(env) [200, {

    "Content-type" => "text/html" }, "Hello world."] end end run RackApp.new $ rackup --env development => INFO WEBrick::HTTPServer#start: pid=37743 port=9292 $ curl http://localhost:9292/ => Hello world.
  4. # contenu de config.ru require "blogue" run Blogue.new # contenu

    de blogue.rb require "sinatra" class Blogue < Sinatra::Base # Code l’application Sinatra end
  5. # contenu de config.ru require "blogue" run Sinatra::Application # contenu

    de blogue.rb require "sinatra" # Code l’application Sinatra au premier niveau
  6. get "/" do "Page principale du blogue" end post "/admin/article"

    do "Création d’un nouvel article" end
  7. get "/auteur/:username" do "Les billets de #{params[:username]}" end delete "/articles/:id"

    do "Suppression de l’article #{params[:id]}" end put "/articles/:id" do |id| "Modification de l’article #{id}" end
  8. get "/fichiers/*.*" do # GET /fichiers/images/2011/03/foo.jpg # params[:splat] => ["/images/2011/03/foo",

    ".jpg"] end get "/*" do # GET /url/inconnu # params[:splat] => ["url/inconnu"] end
  9. get /^\/(\d{4})$/ do |annee| "Les articles de l’année #{annee}" #

    params["captures"] => [annee] end get %r{^(\d{4})/(\d{2})$} do |annee, mois| "Les articles du mois #{mois} de #{annee}" # params["captures"] => [annee, mois] end # seulement ruby 1.9 get %r{^(?<annee>\d{4})/(?<mois>\d{2})$} do "Les articles du mois #{params[:mois]} de #{params[:annee]}" end
  10. get "/", :agent => /msie [\w.]+/i do "Page d’accueil pour

    Internet Explorer" end get "/" do "Page d’accueil pour les autres user-agents" end
  11. set(:secret) do |value| condition { params.include?(:secret) == value } end

    get "/", :secret => true do "Page d’accueil secrète!" end get "/" do "Page d’accueil régulière." end
  12. get "/admin/dashboard" do pass unless authenticate! "Le tableau de bord

    secret" end get "/admin/*" do "Vous semblez ne pas être identifié." end
  13. before "/admin/*" do halt(401, "Vous voulez hacker ce blogue?") unless

    authenticate! end get "/admin/dashboard" do "Tableau de bord de quelqu’un d’authentifié" end post "/admin/billets" do "Création d’un billet par quelqu’un d’authentifié" end
  14. before "/compte/*" do @user = User.find(session[:user_id]) end get "/compte/photo" do

    "Formulaire de modification de la photo de #{@user}" end get "/compte/motdepasse" do "Formulaire de modification du mot de passe de #{@user}" end
  15. get "/" do [200, "Page principale du blogue"] end get

    "/api/articles.json" do [200, { "Content-type": "application/json" }, "[]"] end
  16. get "/" do haml :index end get "/css/screen.css" do sass

    :screen end get "/api/articles.xml" do nokogiri :"api/articles" end get "/api/articles.json" do coffee :"api/articles" end
  17. get "/" do haml :index, :format => :html4 end get

    "/css/screen.css" do scss :screen, :style => :compressed end
  18. enable :inline_templates get "/" do haml :index end __END__ @@

    layout !!! %html %body =yield @@ index %h1 Bienvenue sur mon blogue.
  19. get "/" do haml :index # /views/index.haml end get "/css/screen.css"

    do sass :screen # /views/screen.sass end get "/api/articles.xml" do builder :"api/articles"# /views/api/articles.builder end get "/api/articles.json" do coffee :"api/articles" # /views/api/articles.coffee end
  20. get "/" do haml :index # template: views/index.haml # layout:

    views/layout.haml end get "/article/:id" do @article = Article.find(params[:id]) markdown :article, :layout_engine => :haml # template: views/article.markdown # layout: views/layout.haml end get "/ajax/article/:id.html" do @article = Article.find(params[:id]) haml :article, :layout => false # template: views/article.haml # layout: n/a end
  21. get "/" do @articles = Article.all haml :index end -#

    contenu de index.haml .hfeed - @articles.each do |article| .entry %h1= article.titre .entry-content = markdown(article.contenu)
  22. get "/" do articles = Article.all haml :index, :locals =>

    { :articles => articles } end -# contenu de index.haml .hfeed - articles.each do |article| .entry %h1= article.titre .entry-content = markdown(article.contenu)
  23. get "/" do @articles = Article.all haml :index end -#

    contenu de index.haml .hfeed - @articles.each do |article| .entry = haml :article, :locals => { :article => article } -# contenu de article.haml .entry %h1= article.titre .entry-content = markdown(article.contenu)
  24. helpers do def heading(level, text) "<h#{level}>#{text}</h#{level}>" end end %h1 Derniers

    articles %ul.articles - @articles.each do |article| %li =heading(2, article.title)
  25. helpers do def link_to(path, text) path = "#{request.host}#{path}" if request.xhr?

    "<a href=\"#{path}\">#{text}</a>" end end def other_link_to(path, text) # n’a pas accès à `request` "<a href=\"#{path}\">#{text}</a>" end %h1 Bienvenue %p= link_to "/", "Accueil" %p= other_link_to "/", "Accueil encore"
  26. $ shotgun --env development == Shotgun/WEBrick on http://127.0.0.1:9393/ $ thin

    start --env production >> Thin web server (v1.2.8 codename Black Keys) >> Listening on 0.0.0.0:3000, CTRL+C to stop $ rackup --env development => INFO WEBrick::HTTPServer#start: pid=37743 port=9292 $ rackup --env production => INFO WEBrick::HTTPServer#start: pid=37743 port=9292
  27. configure :development do set :scss, :style => :expanded set :haml,

    :ugly => false end configure :production do set :scss, :style => :compressed set :haml, :ugly => true end
  28. configure :development, :test do set :s3, { :bucket => "blogue-dev",

    :key => "efg456" } end configure :production do set :s3, { :bucket => "blogue", :key => "abc123" } end get "/" do "La valeur de s3/bucket est de #{settings.s3[:bucket]}" end
  29. $ tree . => "## blogue.rb "## config.ru "## public

    "## css % &## screen.css &## js &## global.js $ curl http://localhost:9292/css/screen.css => … $ curl http://localhost:9292/js/global.js => …
  30. get "/live/report.txt" do # Construction dynamique du fichier /tmp/report.txt #

    … send_file "/tmp/report.txt", :type => :attachment end
  31. enable :sessions before "/admin/*" do unless session[:admin] halt "Vous devez

    être <a href=\"/login\">connecté</a>." end end get "/login" do haml :login end post "/login" do if params[:username] == "foo" and params[:password] == "bar" session[:admin] = true redirect "/admin" end end
  32. before do unless request.cookies.include?("deja_venu_ici") response.set_cookies("deja_venu_ici", { :value => true, :expires

    => Time.now + (60*60*24*365) }) @nouveau_visiteur = true end end get "/" do haml :index # peut utiliser @nouveau_visiteur end
  33. require "blogue" require "test/unit" require "rack/test" class BlogueTest < Test::Unit::TestCase

    include Rack::Test::Methods def app; Blogue; end def test_page_accueil get "/" assert_equal "Page d’accueil du blogue", last_response.body end end
  34. require "blogue" require "test/unit" require "rack/test" class BlogueTest < Test::Unit::TestCase

    include Rack::Test::Methods def app; Blogue; end def test_redirection_mauvais_acces_au_tableau_de_bord get "/admin/dashboard" assert_equal "/admin/login", last_request.url assert last_response.ok? end def test_redirection_connexion_au_tableau_de_bord post "/admin/login", :username => "foo", :password => "bar" assert_equal "/admin/dashboard", last_request.url assert last_response.ok? end end
  35. $ ruby test.rb => Loaded suite test Started .. Finished

    in 0.009936 seconds. 2 tests, 2 assertions, 0 failures, 0 errors
  36. # Contenu de config.ru require "rubygems" require "sinatra" require "haml"

    require "dm-core" require "blogue" run Blogue.new
  37. $ gem install sinatra dm-core haml => Successfully installed rack

    1.2.1 Successfully installed tilt-1.2.2 Successfully installed sinatra-1.1.3 Successfully installed extlib-0.9.15 Successfully installed dm-core-1.0.2 Successfully installed haml-3.0.25
  38. $ bundle install --path .bundle/gems => Fetching source index for

    http://rubygems.org/ Installing addressable (2.2.4) Installing extlib (0.9.15) Installing dm-core (1.0.2) Installing haml (3.0.25) Installing rack (1.2.1) Installing tilt (1.2.2) Installing sinatra (1.1.3) Using bundler (1.0.10) Your bundle is complete! It was installed into ./bundle/gems
  39. $ gem install heroku => Successfully installed configuration-1.2.0 Successfully installed

    launchy-0.3.7 Successfully installed heroku-1.17.16 3 gems installed
  40. $ git add . $ git commit -m "Initial commit"

    $ git push heroku master => Counting objects: 14, done. Delta compression using up to 2 threads. Compressing objects: 100% (10/10), done. Writing objects: 100% (14/14), 1.81 KiB, done. Total 14 (delta 0), reused 0 (delta 0) -----> Heroku receiving push -----> Sinatra app detected -----> Gemfile detected, running Bundler version 1.0.7 Unresolved dependencies detected; Installing... … Your bundle is complete! Compiled slug size is 924K -----> Launching... done http://blogue.heroku.com deployed to Heroku To [email protected]:blogue.git * [new branch] master -> master