Your SlideShare is downloading. ×
0
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Introduction à Sinatra
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Introduction à Sinatra

2,927

Published on

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,927
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
43
Comments
0
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Introduction àSinatraRémi Prévost — ConFoo 2011
  • 2. Rémi Prévost Développeur Web@remi + http://remiprevost.com
  • 3. Sinatra • Présentation • Installation • Utilisation • Déploiement
  • 4. Historique et possibilités
  • 5. Historique 2008 Blake Mizerany & Adam Wiggins
  • 6. Historique Problème Services Web légers
  • 7. Historique Solution Un micro-framework
  • 8. Historique Possibilités infinies
  • 9. Historique Prototypes d’applications Web
  • 10. Historique Applications Web complètes
  • 11. Historique APIs « RESTful »
  • 12. Avantages Les bons côtés
  • 13. Avantages Installation rapide
  • 14. $ gem install sinatra=> Successfully installed rack-1.2.1 Successfully installed tilt-1.2.2 Successfully installed sinatra-1.2.0
  • 15. Avantages Développement minimaliste
  • 16. # contenu de hello.rbrequire "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.
  • 17. $ rails new blogue=> create README create Rakefile create config.ru create .gitignore create Gemfile create app …$ du -hd0=> 428K .
  • 18. Avantages Déploiement facile
  • 19. Désavantages Les moins bons côtés
  • 20. Désavantages • Fonctionnalités réduites • Expansion moins guidée • Documentation moins large
  • 21. RackInterface HTTP
  • 22. Rack Framework pour frameworks
  • 23. # contenu de config.ruclass RackApp def call(env) [200, { "Content-type" => "text/html" }, "Hello world."] endendrun RackApp.new$ rackup --env development=> INFO WEBrick::HTTPServer#start: pid=37743 port=9292$ curl http://localhost:9292/=> Hello world.
  • 24. # contenu de blogue.rbrequire "sinatra"class Blogue < Sinatra::Base # Code l’application Sinatraend# contenu de config.rurequire "blogue"run Blogue.new
  • 25. # contenu de blogue.rbrequire "sinatra"# Code l’application Sinatra au premier niveau# contenu de config.rurequire "blogue"run Sinatra::Application
  • 26. RoutesLes directions
  • 27. Routes REST Basées sur les méthodes HTTP
  • 28. Routes • GET • POST • PUT • DELETE
  • 29. methode_http(route) { reponse }
  • 30. methode_http(route) { reponse }get("/") { "Hello world." }
  • 31. Routes Statiques Routes fixes
  • 32. get "/" do "Page principale du blogue"endpost "/admin/article" do "Création d’un nouvel article"end
  • 33. Routes Paramètres Routes variables
  • 34. get "/auteur/:username" do "Les billets de #{params[:username]}"enddelete "/articles/:id" do "Suppression de l’article #{params[:id]}"endput "/articles/:id" do |id| "Modification de l’article #{id}"end
  • 35. Routes Splat Routes avec « wildcards »
  • 36. get "/fichiers/*.*" do # GET /fichiers/images/2011/03/foo.jpg # params[:splat] => ["/images/2011/03/foo", ".jpg"]endget "/*" do # GET /url/inconnu # params[:splat] => ["url/inconnu"]end
  • 37. Routes Regex Routes avec expressions
  • 38. get /^/(d{4})$/ do |annee| "Les articles de l’année #{annee}" # params["captures"] => [annee]endget %r{^(d{4})/(d{2})$} do |annee, mois| "Les articles du mois #{mois} de #{annee}" # params["captures"] => [annee, mois]end# seulement ruby 1.9get %r{^(?<annee>d{4})/(?<mois>d{2})$} do "Les articles du mois #{params[:mois]} de #{params[:annee]}"end
  • 39. Routes Conditions Routes conditionnelles
  • 40. get "/", :agent => /msie [w.]+/i do "Page d’accueil pour Internet Explorer"endget "/" do "Page d’accueil pour les autres user-agents"end
  • 41. set(:secret) do |value| condition { params.include?(:secret) == value }endget "/", :secret => true do "Page d’accueil secrète!"endget "/" do "Page d’accueil régulière."end
  • 42. Routes • methode_http(route) { reponse } • Paramètres (réguliers, regex, splat) • Conditions
  • 43. ExécutionPasser, arrêter ou filtrer
  • 44. Exécution Passer d’une route à la suivante
  • 45. get "/admin/dashboard" do pass unless authenticate! "Le tableau de bord secret"endget "/admin/*" do "Vous semblez ne pas être identifié."end
  • 46. Exécution Arrêter l’exécution du code
  • 47. get "/admin/dashboard" do halt(401, "Vous voulez hacker ce blogue?") unless authenticate! "Le tableau de bord secret"end
  • 48. Exécution Filtrer avant et après
  • 49. Exécution before Avant la route
  • 50. before "/admin/*" do halt(401, "Vous voulez hacker ce blogue?") unless authenticate!endget "/admin/dashboard" do "Tableau de bord de quelqu’un d’authentifié"endpost "/admin/billets" do "Création d’un billet par quelqu’un d’authentifié"end
  • 51. before "/compte/*" do @user = User.find(session[:user_id])endget "/compte/photo" do "Formulaire de modification de la photo de #{@user}"endget "/compte/motdepasse" do "Formulaire de modification du mot de passe de #{@user}"end
  • 52. before :agent => /msie 6.0/i do @message = "Vous utilisez un navigateur dépassé…"end
  • 53. Exécution after Après la route
  • 54. after "*" do headers "X-Secret-Data" => "LOL"end
  • 55. Templates Les vues
  • 56. Templates Réponses compatibles avec Rack
  • 57. get "/" do "Page principale du blogue"end
  • 58. get "/" do [200, "Page principale du blogue"]endget "/api/articles.json" do [200, { "Content-type": "application/json" }, "[]"]end
  • 59. Templates Tilt Templates à la demande
  • 60. get "/" do haml :indexendget "/css/screen.css" do sass :screenendget "/api/articles.xml" do nokogiri :"api/articles"endget "/api/articles.json" do coffee :"api/articles"end
  • 61. Templates Options pour chaque engin
  • 62. get "/" do haml :index, :format => :html4endget "/css/screen.css" do scss :screen, :style => :compressedend
  • 63. set :haml, :format => :html5, :ugly => trueset :scss, :style => :compressed
  • 64. Templates Internes Stockés dans le code Ruby
  • 65. enable :inline_templatesget "/" do haml :indexend__END__@@ layout!!!%html %body =yield@@ index%h1 Bienvenue sur mon blogue.
  • 66. template :layout do "!!!n%htmln%bodyn=yieldn"endtemplate :index do "%h1 Bienvenue sur mon blogue."endget "/" do haml :indexend
  • 67. get "/" do haml "!!!n%body Bienvenue sur mon blogue."end
  • 68. Templates Externes Stockés en tant que fichiers
  • 69. get "/" do haml :index # /views/index.hamlendget "/css/screen.css" do sass :screen # /views/screen.sassendget "/api/articles.xml" do builder :"api/articles"# /views/api/articles.builderendget "/api/articles.json" do coffee :"api/articles" # /views/api/articles.coffeeend
  • 70. set :views, Proc.new { File.join(root, "templates") }
  • 71. Templates Layout Template commun
  • 72. get "/" do haml :index # template: views/index.haml # layout: views/layout.hamlendget "/article/:id" do @article = Article.find(params[:id]) markdown :article, :layout_engine => :haml # template: views/article.markdown # layout: views/layout.hamlendget "/ajax/article/:id.html" do @article = Article.find(params[:id]) haml :article, :layout => false # template: views/article.haml # layout: n/aend
  • 73. Templates Données Les utiliser dans les templates
  • 74. get "/" do @articles = Article.all haml :indexend-# contenu de index.haml.hfeed - @articles.each do |article| .entry %h1= article.titre .entry-content = markdown(article.contenu)
  • 75. 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)
  • 76. get "/" do @articles = Article.all haml :indexend-# 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)
  • 77. Templates Helpers Utilitaires disponibles partout
  • 78. helpers do def heading(level, text) "<h#{level}>#{text}</h#{level}>" endend%h1 Derniers articles%ul.articles - @articles.each do |article| %li =heading(2, article.title)
  • 79. helpers do def link_to(path, text) path = "#{request.host}#{path}" if request.xhr? "<a href="#{path}">#{text}</a>" endenddef 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"
  • 80. Templates • Tilt • Options • Internes + Externes • Données • Helpers
  • 81. Configuration et environnements
  • 82. Configuration Globale à tous les environnements
  • 83. configure do DataMapper.setup :default, ENV["DATABASE_URL"] DataMapper::Pagination.defaults[:per_page] = 20 DataMapper::Logger.new $stdout, :debugendget "/" do @articles = Article.all haml :indexend
  • 84. Configuration Spécifique à un environnement
  • 85. $ rackup --env development=> INFO WEBrick::HTTPServer#start: pid=37743 port=9292$ rackup --env production=> INFO WEBrick::HTTPServer#start: pid=37743 port=9292$ 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
  • 86. configure :development do set :scss, :style => :expanded set :haml, :ugly => falseendconfigure :production do set :scss, :style => :compressed set :haml, :ugly => trueend
  • 87. configure :development, :test do set :s3, { :bucket => "blogue-dev", :key => "efg456" }endconfigure :production do set :s3, { :bucket => "blogue", :key => "abc123" }endget "/" do "La valeur de s3/bucket est de #{settings.s3[:bucket]}"end
  • 88. Erreursgérées comme des routes
  • 89. Erreurs Routes introuvables
  • 90. not_found do "Cette page n’a pu être trouvée"end
  • 91. not_found do haml :erreurend
  • 92. Erreurs HTTP Codes d’erreurs standards
  • 93. error 403 do haml :"erreurs/interdit"enderror 405..500 do haml :"erreurs/autre"end
  • 94. Erreurs Exceptions personnalisées
  • 95. error UnauthenticatedUser do haml :"erreurs/non_authentifie"endbefore "/admin/*" do raise UnauthenticatedUser unless authenticate!end
  • 96. Fichierset téléchargements
  • 97. Fichiers Fichiers publics
  • 98. $ 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=> …
  • 99. set :public, Proc.new { File.join(root, "fichiers/statiques") }
  • 100. FichiersTéléchargements de fichiers
  • 101. get "/live/report.txt" do # Construction dynamique du fichier /tmp/report.txt # … send_file "/tmp/report.txt", :type => :attachmentend
  • 102. Sessions et cookies
  • 103. Sessions SessionsDonnées temporaires encryptées
  • 104. enable :sessionsbefore "/admin/*" do unless session[:admin] halt "Vous devez être <a href="/login">connecté</a>." endendget "/login" do haml :loginendpost "/login" do if params[:username] == "foo" and params[:password] == "bar" session[:admin] = true redirect "/admin" endend
  • 105. Sessions Cookies Données persistantes
  • 106. 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 endendget "/" do haml :index # peut utiliser @nouveau_visiteurend
  • 107. TestsVérifier le fonctionnement
  • 108. Sessions Rack::Test Tests pour applications Rack
  • 109. $ gem install rack-test=> Successfully installed rack-test-0.5.7
  • 110. 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 endend
  • 111. 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? endend
  • 112. $ ruby test.rb=> Loaded suite test Started .. Finished in 0.009936 seconds. 2 tests, 2 assertions, 0 failures, 0 errors
  • 113. Déploiement d’une application
  • 114. Déploiement Bundler Gestionnaire de gems
  • 115. Déploiement Sans Bundler
  • 116. # Contenu de config.rurequire "rubygems"require "sinatra"require "haml"require "dm-core"require "blogue"run Blogue.new
  • 117. $ 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
  • 118. Déploiement Avec Bundler
  • 119. $ gem install bundler=> Successfully installed bundler-1.0.10
  • 120. # Contenu du fichier Gemfilesource "http://rubygems.org"gem "sinatra"gem "haml"gem "dm-core", "~> 1.0"
  • 121. $ 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
  • 122. # Contenu de config.rurequire "bundler"Bundler.requirerequire "blogue"run Blogue.new
  • 123. $ bundle exec rackup=> INFO WEBrick::HTTPServer#start: pid=22866 port=9292
  • 124. Déploiement Heroku Plateforme de déploiement
  • 125. $ gem install heroku=> Successfully installed configuration-1.2.0 Successfully installed launchy-0.3.7 Successfully installed heroku-1.17.16 3 gems installed
  • 126. $ git init=> Initialized empty Git repository in /Code/blogue/.git/$ echo ".bundle" > .gitignore
  • 127. $ heroku create blogue=> Creating blogue.... done http://blogue.heroku.com/ | git@heroku.com:blogue.git Git remote heroku added
  • 128. $ 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 git@heroku.com:blogue.git * [new branch] master -> master
  • 129. RésuméSinatra en bref
  • 130. Résumé Rack Compatible avec tout (!)
  • 131. Résumé Développement minimaliste
  • 132. Résumé Routes orientées « REST »
  • 133. Résumé Templates flexibles
  • 134. Résumé Sessions, cookies, tests, filtres, etc.
  • 135. Résumé Déploiement facile avec Bundler
  • 136. RésuméSinatra en bref
  • 137. Ressources • sinatrarb.com • sinatra-book.gittr.com/ • peepcode.com/products/sinatra • irc.freenode.net/sinatra (IRC) • github.com/remiprev/nid (exemple)
  • 138. Questions? Commentaires? @remi

×