sinatra 2.0.7 → 3.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.fr.md DELETED
@@ -1,3014 +0,0 @@
1
- # Sinatra
2
- *Attention : Ce document correspond à la traduction de la version anglaise et
3
- il n'est peut-être plus à jour.*
4
-
5
- Sinatra est un [DSL](https://fr.wikipedia.org/wiki/Langage_dédié) pour
6
- créer rapidement et facilement des applications web en Ruby :
7
-
8
- ```ruby
9
- # mon_application.rb
10
- require 'sinatra'
11
-
12
- get '/' do
13
- 'Bonjour le monde !'
14
- end
15
- ```
16
-
17
- Installez la gem Sinatra :
18
-
19
- ```shell
20
- gem install sinatra
21
- ```
22
-
23
- Puis lancez votre programme :
24
-
25
- ```shell
26
- ruby mon_application.rb
27
- ```
28
-
29
- Le résultat est visible sur :
30
- [http://localhost:4567](http://localhost:4567)
31
-
32
- Il est recommandé d'exécuter également `gem install thin`, pour que
33
- Sinatra utilise le server Thin quand il est disponible.
34
-
35
- ## Table des matières
36
-
37
- * [Sinatra](#sinatra)
38
- * [Table des matières](#table-des-matières)
39
- * [Routes](#routes)
40
- * [Conditions](#conditions)
41
- * [Valeurs de retour](#valeurs-de-retour)
42
- * [Masques de route spécifiques](#masques-de-route-spécifiques)
43
- * [Fichiers statiques](#fichiers-statiques)
44
- * [Vues / Templates](#vues--templates)
45
- * [Templates littéraux](#templates-littéraux)
46
- * [Langages de template disponibles](#langages-de-template-disponibles)
47
- * [Templates Haml](#templates-haml)
48
- * [Templates Erb](#templates-erb)
49
- * [Templates Builder](#templates-builder)
50
- * [Templates Nokogiri](#templates-nokogiri)
51
- * [Templates Sass](#templates-sass)
52
- * [Templates SCSS](#templates-scss)
53
- * [Templates Less](#templates-less)
54
- * [Templates Liquid](#templates-liquid)
55
- * [Templates Markdown](#templates-markdown)
56
- * [Templates Textile](#templates-textile)
57
- * [Templates RDoc](#templates-rdoc)
58
- * [Templates Radius](#templates-radius)
59
- * [Templates Markaby](#templates-markaby)
60
- * [Templates RABL](#templates-rabl)
61
- * [Templates Slim](#templates-slim)
62
- * [Templates Creole](#templates-creole)
63
- * [Templates CoffeeScript](#templates-coffeescript)
64
- * [Templates Stylus](#templates-stylus)
65
- * [Templates Yajl](#templates-yajl)
66
- * [Templates WLang](#templates-wlang)
67
- * [Accéder aux variables dans un Template](#accéder-aux-variables-dans-un-template)
68
- * [Templates avec `yield` et layouts imbriqués](#templates-avec-yield-et-layouts-imbriqués)
69
- * [Templates dans le fichier source](#templates-dans-le-fichier-source)
70
- * [Templates nommés](#templates-nommés)
71
- * [Associer des extensions de fichier](#associer-des-extensions-de-fichier)
72
- * [Ajouter son propre moteur de rendu](#ajouter-son-propre-moteur-de-rendu)
73
- * [Filtres](#filtres)
74
- * [Helpers](#helpers)
75
- * [Utiliser les sessions](#utiliser-les-sessions)
76
- * [Halt](#halt)
77
- * [Passer](#passer)
78
- * [Déclencher une autre route](#déclencher-une-autre-route)
79
- * [Définir le corps, le code retour et les en-têtes](#définir-le-corps-le-code-retour-et-les-en-têtes)
80
- * [Faire du streaming](#faire-du-streaming)
81
- * [Journalisation (Logging)](#journalisation-logging)
82
- * [Types Mime](#types-mime)
83
- * [Former des URLs](#former-des-urls)
84
- * [Redirection du navigateur](#redirection-du-navigateur)
85
- * [Contrôle du cache](#contrôle-du-cache)
86
- * [Envoyer des fichiers](#envoyer-des-fichiers)
87
- * [Accéder à l'objet requête](#accéder-à-lobjet-requête)
88
- * [Fichiers joints](#fichiers-joints)
89
- * [Gérer Date et Time](#gérer-date-et-time)
90
- * [Chercher les fichiers de templates](#chercher-les-fichiers-de-templates)
91
- * [Configuration](#configuration)
92
- * [Se protéger des attaques](#se-protéger-des-attaques)
93
- * [Paramètres disponibles](#paramètres-disponibles)
94
- * [Environements](#environements)
95
- * [Gérer les erreurs](#gérer-les-erreurs)
96
- * [NotFound](#notfound)
97
- * [Error](#error)
98
- * [Les Middlewares Rack](#les-middlewares-rack)
99
- * [Tester](#tester)
100
- * [Sinatra::Base - Les Middlewares, Bibliothèques, et Applications Modulaires](#sinatrabase---les-middlewares-bibliothèques-et-applications-modulaires)
101
- * [Style modulaire vs. style classique](#style-modulaire-vs-style-classique)
102
- * [Servir une application modulaire](#servir-une-application-modulaire)
103
- * [Utiliser une application de style classique avec un fichier config.ru](#utiliser-une-application-de-style-classique-avec-un-fichier-configru)
104
- * [Quand utiliser un fichier config.ru ?](#quand-utiliser-un-fichier-configru-)
105
- * [Utiliser Sinatra comme Middleware](#utiliser-sinatra-comme-middleware)
106
- * [Création dynamique d'applications](#création-dynamique-dapplications)
107
- * [Contextes et Binding](#contextes-et-binding)
108
- * [Contexte de l'application/classe](#contexte-de-lapplicationclasse)
109
- * [Contexte de la requête/instance](#contexte-de-la-requêteinstance)
110
- * [Le contexte de délégation](#le-contexte-de-délégation)
111
- * [Ligne de commande](#ligne-de-commande)
112
- * [Multi-threading](#multi-threading)
113
- * [Configuration nécessaire](#configuration-nécessaire)
114
- * [Essuyer les plâtres](#essuyer-les-plâtres)
115
- * [Installer avec Bundler](#installer-avec-bundler)
116
- * [Faire un clone local](#faire-un-clone-local)
117
- * [Installer globalement](#installer-globalement)
118
- * [Versions](#versions)
119
- * [Mais encore](#mais-encore)
120
-
121
- ## Routes
122
-
123
- Dans Sinatra, une route est une méthode HTTP couplée à un masque (pattern)
124
- URL. Chaque route est associée à un bloc :
125
-
126
- ```ruby
127
- get '/' do
128
- .. montrer quelque chose ..
129
- end
130
-
131
- post '/' do
132
- .. créer quelque chose ..
133
- end
134
-
135
- put '/' do
136
- .. remplacer quelque chose ..
137
- end
138
-
139
- patch '/' do
140
- .. changer quelque chose ..
141
- end
142
-
143
- delete '/' do
144
- .. effacer quelque chose ..
145
- end
146
-
147
- options '/' do
148
- .. paramétrer quelque chose ..
149
- end
150
-
151
- link '/' do
152
- .. relier quelque chose ..
153
- end
154
-
155
- unlink '/' do
156
- .. séparer quelque chose ..
157
- end
158
- ```
159
-
160
- Les routes sont évaluées dans l'ordre où elles ont été définies. La première
161
- route qui correspond à la requête est appelée.
162
-
163
- Les masques peuvent inclure des paramètres nommés, accessibles par
164
- l'intermédiaire du hash `params` :
165
-
166
- ```ruby
167
- get '/bonjour/:nom' do
168
- # répond aux requêtes "GET /bonjour/foo" et "GET /bonjour/bar"
169
- # params['nom'] est 'foo' ou 'bar'
170
- "Bonjour #{params['nom']} !"
171
- end
172
- ```
173
-
174
- Vous pouvez aussi accéder aux paramètres nommés directement grâce aux
175
- paramètres du bloc comme ceci :
176
-
177
- ```ruby
178
- get '/bonjour/:nom' do |n|
179
- # répond aux requêtes "GET /bonjour/foo" et "GET /bonjour/bar"
180
- # params['nom'] est 'foo' ou 'bar'
181
- # n contient params['nom']
182
- "Bonjour #{n} !"
183
- end
184
- ```
185
-
186
- Une route peut contenir un `splat` (caractère joker), accessible par
187
- l'intermédiaire du tableau `params['splat']` :
188
-
189
- ```ruby
190
- get '/dire/*/a/*' do
191
- # répond à /dire/bonjour/a/monde
192
- params['splat'] # => ["bonjour", "monde"]
193
- end
194
-
195
- get '/telecharger/*.*' do
196
- # répond à /telecharger/chemin/vers/fichier.xml
197
- params['splat'] # => ["chemin/vers/fichier", "xml"]
198
- end
199
- ```
200
-
201
- Ou par l'intermédiaire des paramètres du bloc :
202
-
203
- ```ruby
204
- get '/telecharger/*.*' do |chemin, ext|
205
- [chemin, ext] # => ["path/to/file", "xml"]
206
- end
207
- ```
208
-
209
- Une route peut aussi être définie par une expression régulière :
210
-
211
- ```ruby
212
- get /\/bonjour\/([\w]+)/ do
213
- "Bonjour, #{params['captures'].first} !"
214
- end
215
- ```
216
-
217
- Là encore on peut utiliser les paramètres de bloc :
218
-
219
- ```ruby
220
- get %r{/bonjour/([\w]+)} do |c|
221
- # répond à "GET /meta/bonjour/monde", "GET /bonjour/monde/1234" etc.
222
- "Bonjour, #{c} !"
223
- end
224
- ```
225
-
226
- Les routes peuvent aussi comporter des paramètres optionnels :
227
-
228
- ```ruby
229
- get '/articles/:format?' do
230
- # répond à "GET /articles/" ou avec une extension "GET /articles/json", "GET /articles/xml" etc...
231
- end
232
- ```
233
-
234
- Ainsi que des paramètres d'URL :
235
-
236
- ```ruby
237
- get '/articles' do
238
- # répond à "GET /articles?titre=foo&auteur=bar"
239
- titre = params['titre']
240
- auteur = params['auteur']
241
- # utilise les variables titre et auteur qui sont des paramètres d'URL optionnels pour la route /articles
242
- end
243
- ```
244
-
245
- A ce propos, à moins d'avoir désactivé la protection contre les attaques par
246
- "path transversal" (voir plus loin), l'URL demandée peut avoir été modifiée
247
- avant d'être comparée à vos routes.
248
-
249
- ## Conditions
250
-
251
- Les routes peuvent définir toutes sortes de conditions, comme par exemple le
252
- "user agent" :
253
-
254
- ```ruby
255
- get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
256
- "Vous utilisez Songbird version #{params['agent'][0]}"
257
- end
258
-
259
- get '/foo' do
260
- # Correspond à tous les autres navigateurs
261
- end
262
- ```
263
-
264
- Les autres conditions disponibles sont `host_name` et `provides` :
265
-
266
- ```ruby
267
- get '/', :host_name => /^admin\./ do
268
- "Zone Administrateur, Accès refusé !"
269
- end
270
-
271
- get '/', :provides => 'html' do
272
- haml :index
273
- end
274
-
275
- get '/', :provides => ['rss', 'atom', 'xml'] do
276
- builder :feed
277
- end
278
- ```
279
- `provides` se base sur l'en-tête `Accept` de la requête.
280
-
281
- Vous pouvez facilement définir vos propres conditions :
282
-
283
- ```ruby
284
- set(:chance) { |valeur| condition { rand <= valeur } }
285
-
286
- get '/gagner_une_voiture', :chance => 0.1 do
287
- "Vous avez gagné !"
288
- end
289
-
290
- get '/gagner_une_voiture' do
291
- "Désolé, vous avez perdu."
292
- end
293
- ```
294
-
295
- Utilisez un `splat` (caractère joker) dans le cas d'une condition qui prend
296
- plusieurs valeurs :
297
-
298
- ```ruby
299
- set(:auth) do |*roles| # <- ici on utilise un splat
300
- condition do
301
- unless logged_in? && roles.any? {|role| current_user.in_role? role }
302
- redirect "/login/", 303
303
- end
304
- end
305
- end
306
-
307
- get "/mon/compte/", :auth => [:user, :admin] do
308
- "Informations sur votre compte"
309
- end
310
-
311
- get "/reserve/aux/admins/", :auth => :admin do
312
- "Seuls les administrateurs sont acceptés ici !"
313
- end
314
- ```
315
-
316
- ## Valeurs de retour
317
-
318
- La valeur renvoyée par le bloc correspondant à une route constitue le corps de
319
- la réponse qui sera transmise au client HTTP ou du moins au prochain `middleware`
320
- dans la pile Rack. Le plus souvent, il s'agit d'une chaîne de caractères,
321
- comme dans les exemples précédents. Cependant, d'autres valeurs sont
322
- acceptées.
323
-
324
- Vous pouvez renvoyer n'importe quel objet qu'il s'agisse d'une réponse Rack
325
- valide, d'un corps de réponse Rack ou d'un code statut HTTP :
326
-
327
- * Un tableau de 3 éléments : `[code statut (Integer), en-têtes (Hash), corps
328
- de la réponse (répondant à #each)]`
329
- * Un tableau de 2 élements : `[code statut (Integer), corps de la réponse
330
- (répondant à #each)]`
331
- * Un objet qui répond à `#each` et qui ne transmet que des chaînes de
332
- caractères au bloc fourni
333
- * Un Integer représentant le code statut
334
-
335
- Ainsi, on peut facilement implémenter un exemple de streaming :
336
-
337
- ```ruby
338
- class Stream
339
- def each
340
- 100.times { |i| yield "#{i}\n" }
341
- end
342
- end
343
-
344
- get('/') { Stream.new }
345
- ```
346
-
347
- Vous pouvez aussi utiliser le helper `stream` (présenté un peu plus loin) pour
348
- éviter les répétitions et intégrer le traitement relatif au streaming dans le bloc
349
- de code de la route.
350
-
351
- ## Masques de route spécifiques
352
-
353
- Comme cela a été vu auparavant, Sinatra offre la possibilité d'utiliser des
354
- masques sous forme de chaines de caractères ou des expressions régulières
355
- pour définir les routes. Mais il est possible de faire bien plus. Vous pouvez
356
- facilement définir vos propres masques :
357
-
358
- ```ruby
359
- class MasqueToutSauf
360
- Masque = Struct.new(:captures)
361
-
362
- def initialize(except)
363
- @except = except
364
- @captures = Masque.new([])
365
- end
366
-
367
- def match(str)
368
- @caputres unless @except === str
369
- end
370
- end
371
-
372
- def tout_sauf(masque)
373
- MasqueToutSauf.new(masque)
374
- end
375
-
376
- get tout_sauf("/index") do
377
- # ...
378
- end
379
- ```
380
-
381
- Notez que l'exemple ci-dessus est plus compliqué qu'il ne devrait et peut être implémenté de la façon suivante :
382
-
383
- ```ruby
384
- get // do
385
- pass if request.path_info == "/index"
386
- # ...
387
- end
388
- ```
389
-
390
- Ou bien en utilisant cette expression regulière :
391
-
392
- ```ruby
393
- get %r{(?!/index)} do
394
- # ...
395
- end
396
- ```
397
-
398
- ## Fichiers statiques
399
-
400
- Les fichiers du dossier `./public` sont servis de façon statique. Vous pouvez spécifier un autre dossier avec le paramètre `:public_folder` :
401
-
402
- ```ruby
403
- set :public_folder, File.dirname(__FILE__) + '/statique'
404
- ```
405
-
406
- Notez que le nom du dossier public n'apparait pas dans l'URL. Le fichier
407
- `./public/css/style.css` sera accessible à l'URL :
408
- `http://exemple.com/css/style.css`.
409
-
410
- Utilisez le paramètre `:static_cache_control` pour ajouter l'information
411
- d'en-tête `Cache-Control` (voir plus bas).
412
-
413
- ## Vues / Templates
414
-
415
- Chaque langage de template est disponible via sa propre méthode de rendu,
416
- lesquelles renvoient tout simplement une chaîne de caractères.
417
-
418
- ```ruby
419
- get '/' do
420
- erb :index
421
- end
422
- ```
423
-
424
- Ceci génère la vue `views/index.erb`.
425
-
426
- Plutôt que d'utiliser le nom d'un template, vous pouvez directement passer
427
- le contenu du template :
428
-
429
- ```ruby
430
- get '/' do
431
- code = "<%= Time.now %>"
432
- erb code
433
- end
434
- ```
435
-
436
- Les méthodes de templates acceptent un hash d'options comme second argument :
437
-
438
- ```ruby
439
- get '/' do
440
- erb :index, :layout => :post
441
- end
442
- ```
443
-
444
- Ceci génèrera la vue `views/index.erb` en l'intégrant au *layout* `views/post.erb` (`views/layout.erb` est la valeur par défaut si ce fichier existe).
445
-
446
- Toute option que Sinatra ne comprend pas sera passée au moteur de rendu :
447
-
448
- ```ruby
449
- get '/' do
450
- haml :index, :format => :html5
451
- end
452
- ```
453
-
454
- Vous pouvez également définir les options de chaque langage de template de façon
455
- générale :
456
-
457
- ```ruby
458
- set :haml, :format => html5
459
-
460
- get '/' do
461
- haml :index
462
- end
463
- ```
464
-
465
- Les arguments passés à la méthode de rendu prennent le pas sur les options définies au moyen de `set`.
466
-
467
- Options disponibles :
468
-
469
- <dl>
470
- <dt>locals</dt>
471
- <dd>
472
- Liste de variables locales passées au document. Pratique pour les vues
473
- partielles.
474
- Exemple : <tt>erb "<%= foo %>", :locals => {:foo => "bar"}</tt>.
475
- </dd>
476
-
477
- <dt>default_encoding</dt>
478
- <dd>
479
- Encodage de caractères à utiliser en cas d'incertitude. Par défaut
480
- <tt>settings.default_encoding</tt>.
481
- </dd>
482
-
483
- <dt>views</dt>
484
- <dd>
485
- Dossier de vues dans lequel chercher les templates. Par défaut
486
- <tt>settings.views</tt>.
487
- </dd>
488
-
489
- <dt>layout</dt>
490
- <dd>
491
- S'il faut ou non utiliser un layout (<tt>true</tt> ou <tt>false</tt>).
492
- Ou indique le template à utiliser lorsque c'est un symbole. Exemple :
493
- <tt>erb :index, :layout => !request.xhr?</tt>.
494
- </dd>
495
-
496
- <dt>content_type</dt>
497
- <dd>
498
- Content-Type que le template génère. La valeur par défaut dépend du langage de template.
499
- </dd>
500
-
501
- <dt>scope</dt>
502
- <dd>
503
- Contexte dans lequel effectuer le rendu du template. Par défaut il s'agit
504
- de l'instance de l'application. Si vous changez cela, les variables
505
- d'instance et les méthodes utilitaires ne seront pas disponibles.
506
- </dd>
507
-
508
- <dt>layout_engine</dt>
509
- <dd>
510
- Moteur de rendu à utiliser pour le layout. Utile pour les langages ne
511
- supportant pas les layouts. Il s'agit par défaut du moteur utilisé pour
512
- le rendu du template. Exemple : <tt>set :rdoc, :layout_engine => :erb</tt>
513
- </dd>
514
-
515
- <dt>layout_options</dt>
516
- <dd>
517
- Options spécifiques à la génération du layout. Exemple : <tt>set :rdoc,
518
- :layout_options => { :views => 'views/layouts' }</tt>
519
- </dd>
520
- </dl>
521
-
522
- Les templates sont supposés se trouver directement dans le dossier
523
- `./views`. Pour utiliser un dossier de vues différent :
524
-
525
- ```ruby
526
- set :views, settings.root + '/templates'
527
- ```
528
-
529
- Il est important de se souvenir que les templates sont toujours référencés
530
- sous forme de symboles, même lorsqu'ils sont dans un sous-répertoire (dans
531
- ce cas, utilisez `:'sous_repertoire/template'`). Il faut utiliser
532
- un symbole car les méthodes de rendu évaluent le contenu des chaînes de
533
- caractères au lieu de les considérer comme un chemin vers un fichier.
534
-
535
- ### Templates littéraux
536
-
537
- ```ruby
538
- get '/' do
539
- haml '%div.title Bonjour le monde'
540
- end
541
- ```
542
-
543
- Utilisera la chaine de caractères comme template pour générer la réponse.
544
-
545
- ### Langages de template disponibles
546
-
547
- Certains langages ont plusieurs implémentations. Pour préciser l'implémentation
548
- à utiliser (et garantir l'aspect thread-safe), vous devez simplement l'avoir
549
- chargée au préalable :
550
-
551
- ```ruby
552
- require 'rdiscount' # ou require 'bluecloth'
553
- get('/') { markdown :index }
554
- ```
555
-
556
- #### Templates Haml
557
-
558
- <table>
559
- <tr>
560
- <td>Dépendances</td>
561
- <td><a href="http://haml.info/" title="haml">haml</a></td>
562
- </tr>
563
- <tr>
564
- <td>Extensions de fichier</td>
565
- <td><tt>.haml</tt></td>
566
- </tr>
567
- <tr>
568
- <td>Exemple</td>
569
- <td><tt>haml :index, :format => :html5</tt></td>
570
- </tr>
571
- </table>
572
-
573
- #### Templates Erb
574
-
575
- <table>
576
- <tr>
577
- <td>Dépendances</td>
578
- <td>
579
- <a href="http://www.kuwata-lab.com/erubis/" title="erubis">erubis</a>
580
- ou erb (inclus avec Ruby)
581
- </td>
582
- </tr>
583
- <tr>
584
- <td>Extensions de fichier</td>
585
- <td><tt>.erb</tt>, <tt>.rhtml</tt> ou <tt>.erubis</tt> (Erubis seulement)</td>
586
- </tr>
587
- <tr>
588
- <td>Exemple</td>
589
- <td><tt>erb :index</tt></td>
590
- </tr>
591
- </table>
592
-
593
- #### Templates Builder
594
-
595
- <table>
596
- <tr>
597
- <td>Dépendances</td>
598
- <td>
599
- <a href="https://github.com/jimweirich/builder" title="builder">builder</a>
600
- </td>
601
- </tr>
602
- <tr>
603
- <td>Extensions de fichier</td>
604
- <td><tt>.builder</tt></td>
605
- </tr>
606
- <tr>
607
- <td>Exemple</td>
608
- <td><tt>builder { |xml| xml.em "salut" }</tt></td>
609
- </tr>
610
- </table>
611
-
612
- Ce moteur accepte également un bloc pour des templates en ligne (voir
613
- exemple).
614
-
615
- #### Templates Nokogiri
616
-
617
- <table>
618
- <tr>
619
- <td>Dépendances</td>
620
- <td><a href="http://www.nokogiri.org/" title="nokogiri">nokogiri</a></td>
621
- </tr>
622
- <tr>
623
- <td>Extensions de fichier</td>
624
- <td><tt>.nokogiri</tt></td>
625
- </tr>
626
- <tr>
627
- <td>Exemple</td>
628
- <td><tt>nokogiri { |xml| xml.em "salut" }</tt>
629
- </td>
630
- </tr>
631
- </table>
632
-
633
- Ce moteur accepte également un bloc pour des templates en ligne (voir
634
- exemple).
635
-
636
- #### Templates Sass
637
-
638
- <table>
639
- <tr>
640
- <td>Dépendances</td>
641
- <td><a href="http://sass-lang.com/" title="sass">sass</a></td>
642
- </tr>
643
- <tr>
644
- <td>Extensions de fichier</td>
645
- <td><tt>.sass</tt></td>
646
- </tr>
647
- <tr>
648
- <td>Exemple</td>
649
- <td><tt>sass :stylesheet, :style => :expanded</tt></td>
650
- </tr>
651
- </table>
652
-
653
- #### Templates SCSS
654
-
655
- <table>
656
- <tr>
657
- <td>Dépendances</td>
658
- <td><a href="http://sass-lang.com/" title="sass">sass</a></td>
659
- </tr>
660
- <tr>
661
- <td>Extensions de fichier</td>
662
- <td><tt>.scss</tt></td>
663
- </tr>
664
- <tr>
665
- <td>Exemple</td>
666
- <td><tt>scss :stylesheet, :style => :expanded</tt></p>
667
- </td>
668
- </tr>
669
- </table>
670
-
671
- #### Templates Less
672
-
673
- <table>
674
- <tr>
675
- <td>Dépendances</td>
676
- <td><a href="http://lesscss.org/" title="less">less</a></td>
677
- </tr>
678
- <tr>
679
- <td>Extensions de fichier</td>
680
- <td><tt>.less</tt></td>
681
- </tr>
682
- <tr>
683
- <td>Exemple</td>
684
- <td><tt>less :stylesheet</tt>
685
- </td>
686
- </tr>
687
- </table>
688
-
689
- #### Templates Liquid
690
-
691
- <table>
692
- <tr>
693
- <td>Dépendances</td>
694
- <td><a href="https://shopify.github.io/liquid/" title="liquid">liquid</a></td>
695
- </tr>
696
- <tr>
697
- <td>Extensions de fichier</td>
698
- <td><tt>.liquid</tt></td>
699
- </tr>
700
- <tr>
701
- <td>Exemple</td>
702
- <td><tt>liquid :index, :locals => { :key => 'value' }</tt></td>
703
- </tr>
704
- </table>
705
-
706
- Comme vous ne pouvez appeler de méthodes Ruby (autres que `yield`)
707
- dans un template Liquid, vous aurez sûrement à lui passer des variables
708
- locales.
709
-
710
- #### Templates Markdown
711
-
712
- <table>
713
- <tr>
714
- <td><p>Dépendances</p></td>
715
- <td>
716
- Au choix :
717
- <a href="https://github.com/davidfstr/rdiscount" title="RDiscount">RDiscount</a>,
718
- <a href="https://github.com/vmg/redcarpet" title="RedCarpet">RedCarpet</a>,
719
- <a href="https://github.com/ged/bluecloth" title="bluecloth">BlueCloth</a>,
720
- <a href="http://kramdown.gettalong.org/" title="kramdown">kramdown</a>,
721
- <a href="https://github.com/bhollis/maruku" title="maruku">maruku</a>
722
- </td>
723
- </tr>
724
-
725
- <tr>
726
- <td>Extensions de fichier</td>
727
- <td><tt>.markdown</tt>, <tt>.mkd</tt> et <tt>.md</tt></td>
728
- </tr>
729
- <tr>
730
- <td>Exemple</td>
731
- <td><tt>markdown :index, :layout_engine => :erb</tt></td>
732
- </tr>
733
- </table>
734
-
735
- Il n’est pas possible d’appeler des méthodes depuis markdown, ni de
736
- lui passer de variables locales. Par conséquent, il sera souvent utilisé
737
- en combinaison avec un autre moteur de rendu :
738
-
739
- ```ruby
740
- erb :accueil, :locals => { :text => markdown(:introduction) }
741
- ```
742
-
743
- Notez que vous pouvez également appeler la méthode `markdown` depuis un autre template :
744
-
745
- ```ruby
746
- %h1 Bonjour depuis Haml !
747
- %p= markdown(:bienvenue)
748
- ```
749
-
750
- Comme vous ne pouvez pas appeler de méthode Ruby depuis Markdown, vous ne
751
- pouvez pas utiliser de layouts écrits en Markdown. Toutefois, il
752
- est possible d’utiliser un moteur de rendu différent pour le template et
753
- pour le layout en utilisant l’option `:layout_engine`.
754
-
755
- #### Templates Textile
756
-
757
- <table>
758
- <tr>
759
- <td>Dépendances</td>
760
- <td><a href="http://redcloth.org/" title="RedCloth">RedCloth</a></td>
761
- </tr>
762
- <tr>
763
- <td>Extensions de fichier</td>
764
- <td><tt>.textile</tt></td>
765
- </tr>
766
- <tr>
767
- <td>Exemple</td>
768
- <td><tt>textile :index, :layout_engine => :erb</tt></td>
769
- </tr>
770
- </table>
771
-
772
- Il n’est pas possible d’appeler de méthodes depuis textile, ni de lui
773
- passer de variables locales. Par conséquent, il sera souvent utilisé en
774
- combinaison avec un autre moteur de rendu :
775
-
776
- ```ruby
777
- erb :accueil, :locals => { :text => textile(:introduction) }
778
- ```
779
-
780
- Notez que vous pouvez également appeler la méthode `textile` depuis un autre template :
781
-
782
- ```ruby
783
- %h1 Bonjour depuis Haml !
784
- %p= textile(:bienvenue)
785
- ```
786
-
787
- Comme vous ne pouvez pas appeler de méthode Ruby depuis Textile, vous ne pouvez
788
- pas utiliser de layouts écrits en Textile. Toutefois, il est
789
- possible d’utiliser un moteur de rendu différent pour le template et
790
- pour le layout en utilisant l’option `:layout_engine`.
791
-
792
- #### Templates RDoc
793
-
794
- <table>
795
- <tr>
796
- <td>Dépendances</td>
797
- <td><a href="http://rdoc.sourceforge.net/" title="RDoc">RDoc</a></td>
798
- </tr>
799
- <tr>
800
- <td>Extensions de fichier</td>
801
- <td><tt>.rdoc</tt></td>
802
- </tr>
803
- <tr>
804
- <td>Exemple</td>
805
- <td><tt>rdoc :README, :layout_engine => :erb</tt></td>
806
- </tr>
807
- </table>
808
-
809
- Il n’est pas possible d’appeler de méthodes Ruby depuis rdoc, ni de lui
810
- passer de variables locales. Par conséquent, il sera souvent utilisé en
811
- combinaison avec un autre moteur de rendu :
812
-
813
- ```ruby
814
- erb :accueil, :locals => { :text => rdoc(:introduction) }
815
- ```
816
-
817
- Notez que vous pouvez également appeler la méthode `rdoc` depuis un autre template :
818
-
819
- ```ruby
820
- %h1 Bonjour depuis Haml !
821
- %p= rdoc(:bienvenue)
822
- ```
823
-
824
- Comme vous ne pouvez pas appeler de méthodes Ruby depuis RDoc, vous ne pouvez
825
- pas utiliser de layouts écrits en RDoc. Toutefois, il est
826
- possible d’utiliser un moteur de rendu différent pour le template et
827
- pour le layout en utilisant l’option `:layout_engine`.
828
-
829
- #### Templates Radius
830
- <table>
831
- <tr>
832
- <td>Dépendances</td>
833
- <td><a href="https://github.com/jlong/radius" title="Radius">Radius</a></td>
834
- </tr>
835
- <tr>
836
- <td>Extensions de fichier</td>
837
- <td><tt>.radius</tt></td>
838
- </tr>
839
- <tr>
840
- <td>Exemple</td>
841
- <td><tt>radius :index, :locals => { :key => 'value' }</tt></td>
842
- </tr>
843
- </table>
844
-
845
- Comme vous ne pouvez pas appeler de méthodes Ruby depuis un template
846
- Radius, vous aurez sûrement à lui passer des variables locales.
847
-
848
- #### Templates Markaby
849
-
850
- <table>
851
- <tr>
852
- <td>Dépendances</td>
853
- <td><a href="http://markaby.github.io/" title="Markaby">Markaby</a></td>
854
- </tr>
855
- <tr>
856
- <td>Extensions de fichier</td>
857
- <td><tt>.mab</tt></td>
858
- </tr>
859
- <tr>
860
- <td>Exemple</td>
861
- <td><tt>markaby { h1 "Bienvenue !" }</tt></td>
862
- </tr>
863
- </table>
864
-
865
- Ce moteur accepte également un bloc pour des templates en ligne (voir
866
- exemple).
867
-
868
- #### Templates RABL
869
-
870
- <table>
871
- <tr>
872
- <td>Dépendances</td>
873
- <td><a href="https://github.com/nesquena/rabl" title="Rabl">Rabl</a></td>
874
- </tr>
875
- <tr>
876
- <td>Extensions de fichier</td>
877
- <td><tt>.rabl</tt></td>
878
- </tr>
879
- <tr>
880
- <td>Exemple</td>
881
- <td><tt>rabl :index</tt></td>
882
- </tr>
883
- </table>
884
-
885
- #### Templates Slim
886
-
887
- <table>
888
- <tr>
889
- <td>Dépendances</td>
890
- <td><a href="http://slim-lang.com/" title="Slim Lang">Slim Lang</a></td>
891
- </tr>
892
- <tr>
893
- <td>Extensions de fichier</td>
894
- <td><tt>.slim</tt></td>
895
- </tr>
896
- <tr>
897
- <td>Exemple</td>
898
- <td><tt>slim :index</tt></td>
899
- </tr>
900
- </table>
901
-
902
- #### Templates Creole
903
-
904
- <table>
905
- <tr>
906
- <td>Dépendances</td>
907
- <td><a href="https://github.com/minad/creole" title="Creole">Creole</a></td>
908
- </tr>
909
- <tr>
910
- <td>Extensions de fichier</td>
911
- <td><tt>.creole</tt></td>
912
- </tr>
913
- <tr>
914
- <td>Exemple</td>
915
- <td><tt>creole :wiki, :layout_engine => :erb</tt></td>
916
- </tr>
917
- </table>
918
-
919
- Il n'est pas possible d'appeler de méthodes Ruby depuis creole, ni de lui
920
- passer de variables locales. Par conséquent, il sera souvent utilisé en
921
- combinaison avec un autre moteur de rendu :
922
-
923
- ```ruby
924
- erb :accueil, :locals => { :text => markdown(:introduction) }
925
- ```
926
-
927
- Notez que vous pouvez également appeler la méthode `creole` depuis un autre template :
928
-
929
- ```ruby
930
- %h1 Bonjour depuis Haml !
931
- %p= creole(:bienvenue)
932
- ```
933
-
934
- Comme vous ne pouvez pas appeler de méthodes Ruby depuis Creole, vous ne pouvez
935
- pas utiliser de layouts écrits en Creole. Toutefois, il est possible
936
- d'utiliser un moteur de rendu différent pour le template et pour le layout
937
- en utilisant l'option `:layout_engine`.
938
-
939
- #### Templates CoffeeScript
940
-
941
- <table>
942
- <tr>
943
- <td>Dépendances</td>
944
- <td>
945
- <a href="https://github.com/josh/ruby-coffee-script" title="Ruby CoffeeScript">
946
- CoffeeScript
947
- </a>
948
- et un
949
- <a href="https://github.com/sstephenson/execjs/blob/master/README.md#readme" title="ExecJS">
950
- moyen d'exécuter javascript
951
- </a>
952
- </td>
953
- </tr>
954
- <tr>
955
- <td>Extensions de fichier</td>
956
- <td><tt>.coffee</tt></td>
957
- </tr>
958
- <tr>
959
- <td>Exemple</td>
960
- <td><tt>coffee :index</tt></td>
961
- </tr>
962
- </table>
963
-
964
- #### Templates Stylus
965
-
966
- <table>
967
- <tr>
968
- <td>Dépendances</td>
969
- <td>
970
- <a href="https://github.com/forgecrafted/ruby-stylus" title="Ruby Stylus">
971
- Stylus
972
- </a>
973
- et un
974
- <a href="https://github.com/sstephenson/execjs/blob/master/README.md#readme" title="ExecJS">
975
- moyen d'exécuter javascript
976
- </a>
977
- </td>
978
- </tr>
979
- <tr>
980
- <td>Extensions de fichier</td>
981
- <td><tt>.styl</tt></td>
982
- </tr>
983
- <tr>
984
- <td>Exemple</td>
985
- <td><tt>stylus :index</tt></td>
986
- </tr>
987
- </table>
988
-
989
- Avant de pouvoir utiliser des templates Stylus, vous devez auparavant charger
990
- `stylus` et `stylus/tilt` :
991
-
992
- ```ruby
993
- require 'sinatra'
994
- require 'stylus'
995
- require 'stylus/tilt'
996
-
997
- get '/' do
998
- stylus :exemple
999
- end
1000
- ```
1001
-
1002
- #### Templates Yajl
1003
-
1004
- <table>
1005
- <tr>
1006
- <td>Dépendances</td>
1007
- <td>
1008
- <a href="https://github.com/brianmario/yajl-ruby" title="yajl-ruby">yajl-ruby</a>
1009
- </td>
1010
- </tr>
1011
- <tr>
1012
- <td>Extensions de fichier</td>
1013
- <td><tt>.yajl</tt></td>
1014
- </tr>
1015
- <tr>
1016
- <td>Exemple</td>
1017
- <td><tt>yajl :index, :locals => { :key => 'qux' }, :callback => 'present', :variable => 'ressource'</tt></p>
1018
- </td>
1019
- </tr>
1020
- </table>
1021
-
1022
- La source du template est évaluée en tant que chaine Ruby, puis la
1023
- variable json obtenue est convertie avec #to_json.
1024
-
1025
- ```ruby
1026
- json = { :foo => 'bar' }
1027
- json[:baz] = key
1028
- ```
1029
-
1030
- Les options `:callback` et `:variable` peuvent être utilisées pour décorer
1031
- l’objet retourné.
1032
-
1033
- ```ruby
1034
- var ressource = {"foo":"bar","baz":"qux"}; present(ressource);</pre>
1035
- ```
1036
-
1037
- #### Templates WLang
1038
-
1039
- <table>
1040
- <tr>
1041
- <td>Dépendances</td>
1042
- <td><a href="https://github.com/blambeau/wlang/" title="wlang">wlang</a></td>
1043
- </tr>
1044
- <tr>
1045
- <td>Extensions de fichier</td>
1046
- <td><tt>.wlang</tt></td>
1047
- </tr>
1048
- <tr>
1049
- <td>Exemple</td>
1050
- <td><tt>wlang :index, :locals => { :key => 'value' }</tt></td>
1051
- </tr>
1052
- </table>
1053
-
1054
- L’appel de code ruby au sein des templates n’est pas idiomatique en wlang.
1055
- L’écriture de templates sans logique est encouragée, via le passage de variables
1056
- locales. Il est néanmoins possible d’écrire un layout en wlang et d’y utiliser
1057
- `yield`.
1058
-
1059
- ### Accéder aux variables dans un Template
1060
-
1061
- Un template est évalué dans le même contexte que l'endroit d'où il a été
1062
- appelé (gestionnaire de route). Les variables d'instance déclarées dans le
1063
- gestionnaire de route sont directement accessibles dans le template :
1064
-
1065
- ```ruby
1066
- get '/:id' do
1067
- @foo = Foo.find(params['id'])
1068
- haml '%h1= @foo.nom'
1069
- end
1070
- ```
1071
-
1072
- Alternativement, on peut passer un hash contenant des variables locales :
1073
-
1074
- ```ruby
1075
- get '/:id' do
1076
- foo = Foo.find(params['id'])
1077
- haml '%h1= foo.nom', :locals => { :foo => foo }
1078
- end
1079
- ```
1080
-
1081
- Ceci est généralement nécessaire lorsque l'on veut utiliser un template depuis un autre template (partiel) et qu'il faut donc adapter le nom des variables.
1082
-
1083
- ### Templates avec `yield` et layouts imbriqués
1084
-
1085
- En général, un layout est un simple template qui appelle `yield`. Ce genre de
1086
- template peut s'utiliser via l'option `:template` comme décrit précédemment ou
1087
- peut être rendu depuis un bloc :
1088
-
1089
- ```ruby
1090
- erb :post, :layout => false do
1091
- erb :index
1092
- end
1093
- ```
1094
-
1095
- Ce code est plus ou moins équivalent à `erb :index, :layout => :post`.
1096
-
1097
- Le fait de passer des blocs aux méthodes de rendu est particulièrement utile
1098
- pour gérer des templates imbriqués :
1099
-
1100
- ```ruby
1101
- erb :layout_principal, :layout => false do
1102
- erb :layout_admin do
1103
- erb :utilisateur
1104
- end
1105
- end
1106
- ```
1107
-
1108
- Ou plus brièvement :
1109
-
1110
- ```ruby
1111
- erb :layout_admin, :layout => :layout_principal do
1112
- erb :utilisateur
1113
- end
1114
- ```
1115
-
1116
- Actuellement, les méthodes de rendu qui acceptent un bloc sont : `erb`, `haml`,
1117
- `liquid`, `slim ` et `wlang`. La méthode générale `render` accepte elle aussi
1118
- un bloc.
1119
-
1120
-
1121
- ### Templates dans le fichier source
1122
-
1123
- Des templates peuvent être définis dans le fichier source comme ceci :
1124
-
1125
- ```ruby
1126
- require 'sinatra'
1127
-
1128
- get '/' do
1129
- haml :index
1130
- end
1131
-
1132
- __END__
1133
-
1134
- @@ layout
1135
- %html
1136
- = yield
1137
-
1138
- @@ index
1139
- %div.title Bonjour le monde !
1140
- ```
1141
-
1142
- NOTE : Les templates du fichier source qui contient `require 'sinatra'`
1143
- sont automatiquement chargés. Si vous avez des templates dans d'autres
1144
- fichiers source, il faut explicitement les déclarer avec
1145
- `enable :inline_templates`.
1146
-
1147
-
1148
- ### Templates nommés
1149
-
1150
- Les templates peuvent aussi être définis grâce à la méthode de haut niveau `template` :
1151
-
1152
- ```ruby
1153
- template :layout do
1154
- "%html\n =yield\n"
1155
- end
1156
-
1157
- template :index do
1158
- '%div.title Bonjour le monde !'
1159
- end
1160
-
1161
- get '/' do
1162
- haml :index
1163
- end
1164
- ```
1165
-
1166
- Si un template nommé "layout" existe, il sera utilisé à chaque fois qu'un
1167
- template sera affiché. Vous pouvez désactivez les layouts au cas par cas en
1168
- passant `:layout => false` ou bien les désactiver par défaut au moyen
1169
- de `set :haml, :layout => false` :
1170
-
1171
- ```ruby
1172
- get '/' do
1173
- haml :index, :layout => !request.xhr?
1174
- end
1175
- ```
1176
-
1177
- ### Associer des extensions de fichier
1178
-
1179
- Pour associer une extension de fichier avec un moteur de rendu, utilisez
1180
- `Tilt.register`. Par exemple, si vous désirez utiliser l'extension
1181
- de fichier `tt` pour les templates Textile, vous pouvez faire comme suit :
1182
-
1183
- ```ruby
1184
- Tilt.register :tt, Tilt[:textile]
1185
- ```
1186
-
1187
- ### Ajouter son propre moteur de rendu
1188
-
1189
- En premier lieu, déclarez votre moteur de rendu avec Tilt, ensuite créez
1190
- votre méthode de rendu :
1191
-
1192
- ```ruby
1193
- Tilt.register :monmoteur, MonMerveilleuxMoteurDeRendu
1194
-
1195
- helpers do
1196
- def monmoteur(*args) render(:monmoteur, *args) end
1197
- end
1198
-
1199
- get '/' do
1200
- monmoteur :index
1201
- end
1202
- ```
1203
-
1204
- Utilisera `./views/index.monmoteur`. Voir [le projet Github](https://github.com/rtomayko/tilt) pour en savoir plus sur Tilt.
1205
-
1206
- ## Filtres
1207
-
1208
- Les filtres `before` sont exécutés avant chaque requête, dans le même contexte
1209
- que les routes, et permettent de modifier la requête et sa réponse. Les
1210
- variables d'instance déclarées dans les filtres sont accessibles au niveau
1211
- des routes et des templates :
1212
-
1213
- ```ruby
1214
- before do
1215
- @note = 'Coucou !'
1216
- request.path_info = '/foo/bar/baz'
1217
- end
1218
-
1219
- get '/foo/*' do
1220
- @note #=> 'Coucou !'
1221
- params['splat'] #=> 'bar/baz'
1222
- end
1223
- ```
1224
-
1225
- Les filtres `after` sont exécutés après chaque requête à l'intérieur du même
1226
- contexte et permettent de modifier la requête et sa réponse. Les variables
1227
- d'instance déclarées dans les filtres `before` ou les routes sont accessibles
1228
- au niveau des filtres `after` :
1229
-
1230
- ```ruby
1231
- after do
1232
- puts response.status
1233
- end
1234
- ```
1235
-
1236
- Note : Le corps de la réponse n'est pas disponible au niveau du filtre `after`
1237
- car il ne sera généré que plus tard (sauf dans le cas où vous utilisez la
1238
- méthode `body` au lieu de simplement renvoyer une chaine depuis vos routes).
1239
-
1240
- Les filtres peuvent être associés à un masque, ce qui permet de limiter leur
1241
- exécution aux cas où la requête correspond à ce masque :
1242
-
1243
- ```ruby
1244
- before '/secret/*' do
1245
- authentification!
1246
- end
1247
-
1248
- after '/faire/:travail' do |travail|
1249
- session['dernier_travail'] = travail
1250
- end
1251
- ```
1252
-
1253
- Tout comme les routes, les filtres acceptent également des conditions :
1254
-
1255
- ```ruby
1256
- before :agent => /Songbird/ do
1257
- # ...
1258
- end
1259
-
1260
- after '/blog/*', :host_name => 'example.com' do
1261
- # ...
1262
- end
1263
- ```
1264
-
1265
- ## Helpers
1266
-
1267
- Utilisez la méthode de haut niveau `helpers` pour définir des méthodes
1268
- qui seront accessibles dans vos gestionnaires de route et dans vos templates :
1269
-
1270
- ```ruby
1271
- helpers do
1272
- def bar(nom)
1273
- "#{nom}bar"
1274
- end
1275
- end
1276
-
1277
- get '/:nom' do
1278
- bar(params['nom'])
1279
- end
1280
- ```
1281
-
1282
- Vous pouvez aussi définir les méthodes helper dans un module séparé :
1283
-
1284
- ```ruby
1285
- module FooUtils
1286
- def foo(nom) "#{nom}foo" end
1287
- end
1288
-
1289
- module BarUtils
1290
- def bar(nom) "#{nom}bar" end
1291
- end
1292
-
1293
- helpers FooUtils, BarUtils
1294
- ```
1295
-
1296
- Cela a le même résultat que d'inclure les modules dans la classe de
1297
- l'application.
1298
-
1299
- ### Utiliser les sessions
1300
-
1301
- Les sessions sont utilisées pour conserver un état entre les requêtes. Une fois
1302
- activées, vous avez un hash de session par session utilisateur :
1303
-
1304
- ```ruby
1305
- enable :sessions
1306
-
1307
- get '/' do
1308
- "valeur = " << session['valeur'].inspect
1309
- end
1310
-
1311
- get '/:valeur' do
1312
- session['valeur'] = params['valeur']
1313
- end
1314
- ```
1315
-
1316
- Notez que `enable :sessions` enregistre en fait toutes les données dans
1317
- un cookie. Ce n'est pas toujours ce que vous voulez (enregistrer beaucoup de
1318
- données va augmenter le traffic par exemple). Vous pouvez utiliser n'importe
1319
- quel middleware Rack de session afin d'éviter cela. N'utilisez **pas**
1320
- `enable :sessions` dans ce cas mais chargez le middleware de votre
1321
- choix comme vous le feriez pour n'importe quel autre middleware :
1322
-
1323
- ```ruby
1324
- use Rack::Session::Pool, :expire_after => 2592000
1325
-
1326
- get '/' do
1327
- "valeur = " << session['valeur'].inspect
1328
- end
1329
-
1330
- get '/:valeur' do
1331
- session['valeur'] = params['valeur']
1332
- end
1333
- ```
1334
-
1335
- Pour renforcer la sécurité, les données de session dans le cookie sont signées
1336
- avec une clé secrète de session. Une clé secrète est générée pour vous au
1337
- hasard par Sinatra. Toutefois, comme cette clé change à chaque démarrage de
1338
- votre application, vous pouvez définir cette clé vous-même afin que toutes
1339
- les instances de votre application la partage :
1340
-
1341
- ```ruby
1342
- set :session_secret, 'super secret'
1343
- ```
1344
-
1345
- Si vous souhaitez avoir plus de contrôle, vous pouvez également enregistrer un
1346
- hash avec des options lors de la configuration de `sessions` :
1347
-
1348
- ```ruby
1349
- set :sessions, :domain => 'foo.com'
1350
- ```
1351
-
1352
- Pour que les différents sous-domaines de foo.com puissent partager une session,
1353
- vous devez précéder le domaine d'un *.* (point) :
1354
-
1355
- ```ruby
1356
- set :sessions, :domain => '.foo.com'
1357
- ```
1358
-
1359
-
1360
- ### Halt
1361
-
1362
- Pour arrêter immédiatement la requête dans un filtre ou un gestionnaire de
1363
- route :
1364
-
1365
- ```ruby
1366
- halt
1367
- ```
1368
-
1369
- Vous pouvez aussi passer le code retour ...
1370
-
1371
- ```ruby
1372
- halt 410
1373
- ```
1374
-
1375
- Ou le texte ...
1376
-
1377
- ```ruby
1378
- halt 'Ceci est le texte'
1379
- ```
1380
-
1381
- Ou les deux ...
1382
-
1383
- ```ruby
1384
- halt 401, 'Partez !'
1385
- ```
1386
-
1387
- Ainsi que les en-têtes ...
1388
-
1389
- ```ruby
1390
- halt 402, {'Content-Type' => 'text/plain'}, 'revanche'
1391
- ```
1392
-
1393
- Bien sûr il est possible de combiner un template avec `halt` :
1394
-
1395
- ```ruby
1396
- halt erb(:erreur)
1397
- ```
1398
-
1399
- ### Passer
1400
-
1401
- Une route peut passer le relais aux autres routes qui correspondent également
1402
- avec `pass` :
1403
-
1404
- ```ruby
1405
- get '/devine/:qui' do
1406
- pass unless params['qui'] == 'Frank'
1407
- "Tu m'as eu !"
1408
- end
1409
-
1410
- get '/devine/*' do
1411
- 'Manqué !'
1412
- end
1413
- ```
1414
-
1415
- On sort donc immédiatement de ce gestionnaire et on continue à chercher,
1416
- dans les masques suivants, le prochain qui correspond à la requête.
1417
- Si aucun des masques suivants ne correspond, un code 404 est retourné.
1418
-
1419
- ### Déclencher une autre route
1420
-
1421
- Parfois, `pass` n'est pas ce que vous recherchez, au lieu de cela vous
1422
- souhaitez obtenir le résultat d'une autre route. Pour cela, utilisez
1423
- simplement `call` :
1424
-
1425
- ```ruby
1426
- get '/foo' do
1427
- status, headers, body = call env.merge("PATH_INFO" => '/bar')
1428
- [status, headers, body.map(&:upcase)]
1429
- end
1430
-
1431
- get '/bar' do
1432
- "bar"
1433
- end
1434
- ```
1435
-
1436
- Notez que dans l'exemple ci-dessus, vous faciliterez les tests et améliorerez
1437
- la performance en déplaçant simplement `"bar"` dans un helper
1438
- utilisé à la fois par `/foo` et `/bar`.
1439
-
1440
- Si vous souhaitez que la requête soit envoyée à la même instance de
1441
- l'application plutôt qu'à une copie, utilisez `call!` au lieu de
1442
- `call`.
1443
-
1444
- Lisez la spécification Rack si vous souhaitez en savoir plus sur
1445
- `call`.
1446
-
1447
- ### Définir le corps, le code retour et les en-têtes
1448
-
1449
- Il est possible et recommandé de définir le code retour et le corps de la
1450
- réponse au moyen de la valeur de retour d'un bloc définissant une route.
1451
- Quoiqu'il en soit, dans certains cas vous pourriez avoir besoin de définir
1452
- le coprs de la réponse à un moment arbitraire de l'exécution. Vous pouvez le
1453
- faire au moyen de la méthode `body`. Si vous faites ainsi, vous pouvez alors
1454
- utiliser cette même méthode pour accéder au corps de la réponse :
1455
-
1456
- ```ruby
1457
- get '/foo' do
1458
- body "bar"
1459
- end
1460
-
1461
- after do
1462
- puts body
1463
- end
1464
- ```
1465
-
1466
- Il est également possible de passer un bloc à `body`, qui sera exécuté par le
1467
- gestionnaire Rack (ceci peut être utilisé pour implémenter un streaming,
1468
- voir "Valeurs de retour").
1469
-
1470
- Pareillement au corps de la réponse, vous pouvez également définir le code
1471
- retour et les en-têtes :
1472
-
1473
- ```ruby
1474
- get '/foo' do
1475
- status 418
1476
- headers \
1477
- "Allow" => "BREW, POST, GET, PROPFIND, WHEN",
1478
- "Refresh" => "Refresh: 20; http://www.ietf.org/rfc/rfc2324.txt"
1479
- body "Je suis une théière !"
1480
- end
1481
- ```
1482
-
1483
- Comme pour `body`, `headers` et `status` peuvent être utilisés sans arguments
1484
- pour accéder à leurs valeurs.
1485
-
1486
- ### Faire du streaming
1487
-
1488
- Il y a des cas où vous voulez commencer à renvoyer des données pendant que
1489
- vous êtes en train de générer le reste de la réponse. Dans les cas les plus
1490
- extrèmes, vous souhaitez continuer à envoyer des données tant que le client
1491
- n'abandonne pas la connexion. Vous pouvez alors utiliser le helper `stream`
1492
- pour éviter de créer votre propre système :
1493
-
1494
- ```ruby
1495
- get '/' do
1496
- stream do |out|
1497
- out << "Ca va être hallu -\n"
1498
- sleep 0.5
1499
- out << " (attends la suite) \n"
1500
- sleep 1
1501
- out << "- cinant !\n"
1502
- end
1503
- end
1504
- ```
1505
-
1506
- Cela permet d'implémenter des API de streaming ou de
1507
- [Server Sent Events](https://w3c.github.io/eventsource/) et peut servir de
1508
- base pour des [WebSockets](https://en.wikipedia.org/wiki/WebSocket). Vous
1509
- pouvez aussi l'employer pour augmenter le débit quand une partie du contenu
1510
- provient d'une ressource lente.
1511
-
1512
- Le fonctionnement du streaming, notamment le nombre de requêtes simultanées,
1513
- dépend énormément du serveur web utilisé. Certains ne prennent pas du tout en
1514
- charge le streaming. Lorsque le serveur ne gère pas le streaming, la partie
1515
- body de la réponse sera envoyée au client en une seule fois, après
1516
- l'exécution du bloc passé au helper `stream`. Le streaming ne
1517
- fonctionne pas du tout avec Shotgun.
1518
-
1519
- En utilisant le helper `stream` avec le paramètre `keep_open`, il n'appelera
1520
- pas la méthode `close` du flux, vous laissant la possibilité de le fermer à
1521
- tout moment au cours de l'exécution. Ceci ne fonctionne qu'avec les serveurs
1522
- evented (ie non threadés) tels que Thin et Rainbows. Les autres serveurs
1523
- fermeront malgré tout le flux :
1524
-
1525
- ```ruby
1526
- # interrogation prolongée
1527
-
1528
- set :server, :thin
1529
- connexions = []
1530
-
1531
- get '/souscrire' do
1532
- # abonne un client aux évènements du serveur
1533
- stream(:keep_open) do |out|
1534
- connexions << out
1535
- # purge les connexions abandonnées
1536
- connexions.reject!(&:closed?)
1537
- end
1538
- end
1539
-
1540
- post '/message' do
1541
- connexions.each do |out|
1542
- # prévient le client qu'un nouveau message est arrivé
1543
- out << params['message'] << "\n"
1544
-
1545
- # indique au client de se connecter à nouveau
1546
- out.close
1547
- end
1548
-
1549
- # compte-rendu
1550
- "message reçu"
1551
- end
1552
- ```
1553
-
1554
- ### Journalisation (Logging)
1555
-
1556
- Dans le contexte de la requête, la méthode utilitaire `logger` expose une
1557
- instance de `Logger` :
1558
-
1559
- ```ruby
1560
- get '/' do
1561
- logger.info "chargement des données"
1562
- # ...
1563
- end
1564
- ```
1565
-
1566
- Ce logger va automatiquement prendre en compte les paramètres de
1567
- configuration pour la journalisation de votre gestionnaire Rack. Si la
1568
- journalisation est désactivée, cette méthode renverra un objet factice et
1569
- vous n'avez pas à vous en inquiéter dans vos routes en le filtrant.
1570
-
1571
- Notez que la journalisation est seulement activée par défaut pour
1572
- `Sinatra::Application`, donc si vous héritez de `>Sinatra::Base`,
1573
- vous aurez à l'activer vous-même :
1574
-
1575
- ```ruby
1576
- class MonApp < Sinatra::Base
1577
- configure :production, :development do
1578
- enable :logging
1579
- end
1580
- end
1581
- ```
1582
-
1583
- Si vous souhaitez utiliser votre propre logger, vous devez définir le paramètre
1584
- `logging` à `nil` pour être certain qu'aucun middleware de logging ne sera
1585
- installé (notez toutefois que `logger` renverra alors `nil`). Dans ce cas,
1586
- Sinatra utilisera ce qui sera présent dans `env['rack.logger']`.
1587
-
1588
- ### Types Mime
1589
-
1590
- Quand vous utilisez `send_file` ou des fichiers statiques, vous
1591
- pouvez rencontrer des types mime que Sinatra ne connaît pas. Utilisez
1592
- `mime_type` pour les déclarer par extension de fichier :
1593
-
1594
- ```ruby
1595
- configure do
1596
- mime_type :foo, 'text/foo'
1597
- end
1598
- ```
1599
-
1600
- Vous pouvez également les utiliser avec la méthode `content_type` :
1601
-
1602
- ```ruby
1603
- get '/' do
1604
- content_type :foo
1605
- "foo foo foo"
1606
- end
1607
- ```
1608
-
1609
- ### Former des URLs
1610
-
1611
- Pour former des URLs, vous devriez utiliser la méthode `url`, par exemple en
1612
- Haml :
1613
-
1614
- ```ruby
1615
- %a{:href => url('/foo')} foo
1616
- ```
1617
-
1618
- Cela prend en compte les proxy inverse et les routeurs Rack, s'ils existent.
1619
-
1620
- Cette méthode est également disponible sous l'alias `to` (voir ci-dessous
1621
- pour un exemple).
1622
-
1623
- ### Redirection du navigateur
1624
-
1625
- Vous pouvez déclencher une redirection du navigateur avec la méthode
1626
- `redirect` :
1627
-
1628
- ```ruby
1629
- get '/foo' do
1630
- redirect to('/bar')
1631
- end
1632
- ```
1633
-
1634
- Tout paramètre additionnel sera utilisé comme argument pour la méthode
1635
- `halt` :
1636
-
1637
- ```ruby
1638
- redirect to('/bar'), 303
1639
- redirect 'http://www.google.com/', 'mauvais endroit mon pote'
1640
- ```
1641
-
1642
- Vous pouvez aussi rediriger vers la page dont l'utilisateur venait au moyen de
1643
- `redirect back` :
1644
-
1645
- ```ruby
1646
- get '/foo' do
1647
- "<a href='/bar'>faire quelque chose</a>"
1648
- end
1649
-
1650
- get '/bar' do
1651
- faire_quelque_chose
1652
- redirect back
1653
- end
1654
- ```
1655
-
1656
- Pour passer des arguments à une redirection, ajoutez-les soit à la requête :
1657
-
1658
- ```ruby
1659
- redirect to('/bar?sum=42')
1660
- ```
1661
-
1662
- Ou bien utilisez une session :
1663
-
1664
- ```ruby
1665
- enable :sessions
1666
-
1667
- get '/foo' do
1668
- session['secret'] = 'foo'
1669
- redirect to('/bar')
1670
- end
1671
-
1672
- get '/bar' do
1673
- session['secret']
1674
- end
1675
- ```
1676
-
1677
- ### Contrôle du cache
1678
-
1679
- Définissez correctement vos en-têtes à la base pour un bon cache HTTP.
1680
-
1681
- Vous pouvez facilement définir l'en-tête Cache-Control de la manière suivante :
1682
-
1683
- ```ruby
1684
- get '/' do
1685
- cache_control :public
1686
- "met le en cache !"
1687
- end
1688
- ```
1689
-
1690
- Conseil de pro : définir le cache dans un filtre before :
1691
-
1692
- ```ruby
1693
- before do
1694
- cache_control :public, :must_revalidate, :max_age => 60
1695
- end
1696
- ```
1697
-
1698
- Si vous utilisez la méthode `expires` pour définir l'en-tête correspondant,
1699
- `Cache-Control` sera alors défini automatiquement :
1700
-
1701
- ```ruby
1702
- before do
1703
- expires 500, :public, :must_revalidate
1704
- end
1705
- ```
1706
-
1707
- Pour utiliser correctement le cache, vous devriez utiliser `etag` ou
1708
- `last_modified`. Il est recommandé d'utiliser ces méthodes *avant* de faire
1709
- d'importantes modifications, car elles vont immédiatement déclencher la réponse
1710
- si le client a déjà la version courante dans son cache :
1711
-
1712
- ```ruby
1713
- get '/article/:id' do
1714
- @article = Article.find params['id']
1715
- last_modified @article.updated_at
1716
- etag @article.sha1
1717
- erb :article
1718
- end
1719
- ```
1720
-
1721
- Il est également possible d'utiliser un
1722
- [weak ETag](https://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation) :
1723
-
1724
- ```ruby
1725
- etag @article.sha1, :weak
1726
- ```
1727
-
1728
- Ces méthodes ne sont pas chargées de mettre des données en cache, mais elles
1729
- fournissent les informations nécessaires pour le cache de votre navigateur. Si vous êtes à la
1730
- recherche d'une solution rapide pour un reverse-proxy de cache, essayez
1731
- [rack-cache](https://github.com/rtomayko/rack-cache) :
1732
-
1733
- ```ruby
1734
- require "rack/cache"
1735
- require "sinatra"
1736
-
1737
- use Rack::Cache
1738
-
1739
- get '/' do
1740
- cache_control :public, :max_age => 36000
1741
- sleep 5
1742
- "hello"
1743
- end
1744
- ```
1745
-
1746
- Utilisez le paramètre `:static_cache_control` pour ajouter l'information
1747
- d'en-tête `Cache-Control` (voir plus loin).
1748
-
1749
- D'après la RFC 2616, votre application devrait se comporter différement lorsque
1750
- l'en-tête If-Match ou If-None-Match est défini à `*` en tenant compte du
1751
- fait que la ressource demandée existe déjà ou pas. Sinatra considère que les
1752
- requêtes portant sur des ressources sûres (tel que get) ou idempotentes (tel que
1753
- put) existent déjà et pour les autres ressources (par exemple dans le cas
1754
- de requêtes post) qu'il s'agit de nouvelles ressources. Vous pouvez modifier ce
1755
- comportement en passant une option `:new_resource` :
1756
-
1757
- ```ruby
1758
- get '/create' do
1759
- etag '', :new_resource => true
1760
- Article.create
1761
- erb :nouvel_article
1762
- end
1763
- ```
1764
-
1765
- Si vous souhaitez avoir un ETag faible, utilisez l'option `:kind` :
1766
-
1767
- ```ruby
1768
- etag '', :new_resource => true, :kind => :weak
1769
- ```
1770
-
1771
- ### Envoyer des fichiers
1772
-
1773
- Pour envoyer des fichiers, vous pouvez utiliser la méthode `send_file` :
1774
-
1775
- ```ruby
1776
- get '/' do
1777
- send_file 'foo.png'
1778
- end
1779
- ```
1780
-
1781
- Quelques options sont également acceptées :
1782
-
1783
- ```ruby
1784
- send_file 'foo.png', :type => :jpg
1785
- ```
1786
-
1787
- Les options sont :
1788
-
1789
- <dl>
1790
- <dt>filename</dt>
1791
- <dd>
1792
- le nom du fichier dans la réponse, par défaut le nom du fichier envoyé.
1793
- </dd>
1794
-
1795
- <dt>last_modified</dt>
1796
- <dd>
1797
- valeur pour l’en-tête Last-Modified, par défaut la date de modification du
1798
- fichier.
1799
- </dd>
1800
-
1801
- <dt>type</dt>
1802
- <dd>
1803
- type de contenu à utiliser, deviné à partir de l’extension de fichier si
1804
- absent
1805
- </dd>
1806
-
1807
- <dt>disposition</dt>
1808
- <dd>
1809
- utilisé pour Content-Disposition, les valeurs possibles étant : <tt>nil</tt>
1810
- (par défaut), <tt>:attachment</tt> et <tt>:inline</tt>
1811
- </dd>
1812
-
1813
- <dt>length</dt>
1814
- <dd>en-tête Content-Length, par défaut la taille du fichier</dd>
1815
-
1816
- <dt>status</dt>
1817
- <dd>
1818
- code état à renvoyer. Utile quand un fichier statique sert de page d’erreur.
1819
-
1820
- Si le gestionnaire Rack le supporte, d'autres moyens que le streaming via le
1821
- processus Ruby seront utilisés. Si vous utilisez cette méthode, Sinatra gérera
1822
- automatiquement les requêtes de type range.
1823
- </dd>
1824
- </dl>
1825
-
1826
- ### Accéder à l'objet requête
1827
-
1828
- L'objet correspondant à la requête envoyée peut être récupéré dans le contexte
1829
- de la requête (filtres, routes, gestionnaires d'erreur) au moyen de la méthode
1830
- `request` :
1831
-
1832
- ```ruby
1833
- # application tournant à l'adresse http://exemple.com/exemple
1834
- get '/foo' do
1835
- t = %w[text/css text/html application/javascript]
1836
- request.accept # ['text/html', '*/*']
1837
- request.accept? 'text/xml' # vrai
1838
- request.preferred_type(t) # 'text/html'
1839
- request.body # corps de la requête envoyée par le client
1840
- # (voir ci-dessous)
1841
- request.scheme # "http"
1842
- request.script_name # "/exemple"
1843
- request.path_info # "/foo"
1844
- request.port # 80
1845
- request.request_method # "GET"
1846
- request.query_string # ""
1847
- request.content_length # taille de request.body
1848
- request.media_type # type de média pour request.body
1849
- request.host # "exemple.com"
1850
- request.get? # vrai (méthodes similaires pour les autres
1851
- # verbes HTTP)
1852
- request.form_data? # faux
1853
- request["UN_ENTETE"] # valeur de l'en-tête UN_ENTETE
1854
- request.referrer # référant du client ou '/'
1855
- request.user_agent # user agent (utilisé par la condition :agent)
1856
- request.cookies # tableau contenant les cookies du navigateur
1857
- request.xhr? # requête AJAX ?
1858
- request.url # "http://exemple.com/exemple/foo"
1859
- request.path # "/exemple/foo"
1860
- request.ip # adresse IP du client
1861
- request.secure? # faux
1862
- request.forwarded? # vrai (si on est derrière un proxy inverse)
1863
- request.env # tableau brut de l'environnement fourni par Rack
1864
- end
1865
- ```
1866
-
1867
- Certaines options, telles que `script_name` ou `path_info`
1868
- peuvent également être modifiées :
1869
-
1870
- ```ruby
1871
- before { request.path_info = "/" }
1872
-
1873
- get "/" do
1874
- "toutes les requêtes arrivent ici"
1875
- end
1876
- ```
1877
-
1878
- `request.body` est un objet IO ou StringIO :
1879
-
1880
- ```ruby
1881
- post "/api" do
1882
- request.body.rewind # au cas où il a déjà été lu
1883
- donnees = JSON.parse request.body.read
1884
- "Bonjour #{donnees['nom']} !"
1885
- end
1886
- ```
1887
-
1888
- ### Fichiers joints
1889
-
1890
- Vous pouvez utiliser la méthode `attachment` pour indiquer au navigateur que
1891
- la réponse devrait être stockée sur le disque plutôt qu'affichée :
1892
-
1893
-
1894
- ```ruby
1895
- get '/' do
1896
- attachment
1897
- "enregistre-le !"
1898
- end
1899
- ```
1900
-
1901
- Vous pouvez également lui passer un nom de fichier :
1902
-
1903
- ```ruby
1904
- get '/' do
1905
- attachment "info.txt"
1906
- "enregistre-le !"
1907
- end
1908
- ```
1909
-
1910
- ### Gérer Date et Time
1911
-
1912
- Sinatra fourni un helper `time_for` pour convertir une valeur donnée en
1913
- objet `Time`. Il peut aussi faire la conversion à partir d'objets `DateTime`,
1914
- `Date` ou de classes similaires :
1915
-
1916
- ```ruby
1917
- get '/' do
1918
- pass if Time.now > time_for('Dec 23, 2012')
1919
- "encore temps"
1920
- end
1921
- ```
1922
-
1923
- Cette méthode est utilisée en interne par `expires`, `last_modified` et
1924
- consorts. Par conséquent, vous pouvez très facilement étendre le
1925
- fonctionnement de ces méthodes en surchargeant le helper `time_for` dans
1926
- votre application :
1927
-
1928
- ```ruby
1929
- helpers do
1930
- def time_for(value)
1931
- case value
1932
- when :yesterday then Time.now - 24*60*60
1933
- when :tomorrow then Time.now + 24*60*60
1934
- else super
1935
- end
1936
- end
1937
- end
1938
-
1939
- get '/' do
1940
- last_modified :yesterday
1941
- expires :tomorrow
1942
- "salut"
1943
- end
1944
- ```
1945
-
1946
- ### Chercher les fichiers de templates
1947
-
1948
- La méthode `find_template` est utilisée pour trouver les fichiers de
1949
- templates à générer :
1950
-
1951
- ```ruby
1952
- find_template settings.views, 'foo', Tilt[:haml] do |file|
1953
- puts "pourrait être #{file}"
1954
- end
1955
- ```
1956
-
1957
- Ce n'est pas très utile. En revanche, il est utile de pouvoir surcharger
1958
- cette méthode afin de définir son propre mécanisme de recherche. Par exemple,
1959
- vous pouvez utiliser plus d'un répertoire de vues :
1960
-
1961
- ```ruby
1962
- set :views, ['views', 'templates']
1963
-
1964
- helpers do
1965
- def find_template(views, name, engine, &block)
1966
- Array(views).each { |v| super(v, name, engine, &block) }
1967
- end
1968
- end
1969
- ```
1970
-
1971
- Un autre exemple est d'utiliser des répertoires différents pour des moteurs
1972
- de rendu différents :
1973
-
1974
- ```ruby
1975
- set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views'
1976
-
1977
- helpers do
1978
- def find_template(vues, nom, moteur, &bloc)
1979
- _, dossier = vues.detect { |k,v| moteur == Tilt[k] }
1980
- dossier ||= vues[:default]
1981
- super(dossier, nom, moteur, &bloc)
1982
- end
1983
- end
1984
- ```
1985
-
1986
- Vous pouvez également écrire cela dans une extension et la partager avec
1987
- d'autres !
1988
-
1989
- Notez que `find_template` ne vérifie pas que le fichier existe mais
1990
- va plutôt exécuter le bloc pour tous les chemins possibles. Cela n'induit pas
1991
- de problème de performance dans le sens où `render` va utiliser `break` dès
1992
- qu'un fichier sera trouvé. De plus, l'emplacement des templates (et leur
1993
- contenu) est mis en cache si vous n'êtes pas en mode développement. Vous
1994
- devez garder cela en tête si vous écrivez une méthode vraiment dingue.
1995
-
1996
- ## Configuration
1997
-
1998
- Lancé une seule fois au démarrage de tous les environnements :
1999
-
2000
- ```ruby
2001
- configure do
2002
- # définir un paramètre
2003
- set :option, 'valeur'
2004
-
2005
- # définir plusieurs paramètres
2006
- set :a => 1, :b => 2
2007
-
2008
- # équivalent à "set :option, true"
2009
- enable :option
2010
-
2011
- # équivalent à "set :option, false""
2012
- disable :option
2013
-
2014
- # vous pouvez également avoir des paramètres dynamiques avec des blocs
2015
- set(:css_dir) { File.join(views, 'css') }
2016
- end
2017
- ```
2018
-
2019
- Lancé si l'environnement (variable d'environnement APP_ENV) est `:production` :
2020
-
2021
- ```ruby
2022
- configure :production do
2023
- ...
2024
- end
2025
- ```
2026
-
2027
- Lancé si l'environnement est `:production` ou `:test` :
2028
-
2029
- ```ruby
2030
- configure :production, :test do
2031
- ...
2032
- end
2033
- ```
2034
-
2035
- Vous pouvez accéder à ces paramètres via `settings` :
2036
-
2037
- ```ruby
2038
- configure do
2039
- set :foo, 'bar'
2040
- end
2041
-
2042
- get '/' do
2043
- settings.foo? # => true
2044
- settings.foo # => 'bar'
2045
- ...
2046
- end
2047
- ```
2048
-
2049
- ### Se protéger des attaques
2050
-
2051
- Sinatra utilise [Rack::Protection](https://github.com/sinatra/sinatra/tree/master/rack-protection#readme)
2052
- pour protéger votre application contre les principales attaques opportunistes.
2053
- Vous pouvez très simplement désactiver cette fonctionnalité (ce qui exposera
2054
- votre application à beaucoup de vulnerabilités courantes) :
2055
-
2056
- ```ruby
2057
- disable :protection
2058
- ```
2059
-
2060
- Pour désactiver seulement un type de protection, vous pouvez définir `protection`
2061
- avec un hash d'options :
2062
-
2063
- ```ruby
2064
- set :protection, :except => :path_traversal
2065
- ```
2066
-
2067
- Vous pouvez également lui passer un tableau pour désactiver plusieurs types de
2068
- protection :
2069
-
2070
- ```ruby
2071
- set :protection, :except => [:path_traversal, :session_hijacking]
2072
- ```
2073
-
2074
- Par défaut, il faut que `:sessions` soit activé pour que Sinatra mette en place
2075
- un système de protection au niveau de la session. Dans le cas où vous gérez
2076
- vous même les sessions, vous devez utiliser l'option `:session` pour que cela
2077
- soit le cas :
2078
-
2079
- ```ruby
2080
- use Rack::Session::Pool
2081
- set :protection, :session => true
2082
- ```
2083
-
2084
- ### Paramètres disponibles
2085
-
2086
- <dl>
2087
- <dt>absolute_redirects</dt>
2088
- <dd>Si désactivé, Sinatra permettra les redirections relatives. Toutefois,
2089
- Sinatra ne sera plus conforme à la RFC 2616 (HTTP 1.1), qui n’autorise
2090
- que les redirections absolues.</p>
2091
-
2092
- Activez si votre application tourne derrière un proxy inverse qui n’a
2093
- pas été correctement configuré. Notez que la méthode <tt>url</tt>
2094
- continuera de produire des URLs absolues, sauf si vous lui passez
2095
- <tt>false</tt> comme second argument.</p>
2096
-
2097
- <p>Désactivé par défaut.</p></dd>
2098
-
2099
- <dt>add_charset</dt>
2100
- <dd><p>types mime pour lesquels la méthode <tt>content_type</tt> va
2101
- automatiquement ajouter l’information du <tt>charset</tt>.</p>
2102
-
2103
- <p>Vous devriez lui ajouter des valeurs plutôt que de l’écraser :</p>
2104
-
2105
- <pre>settings.add_charset >> "application/foobar"</pre></dd>
2106
-
2107
- <dt>app_file</dt>
2108
- <dd><p>chemin pour le fichier de l’application principale, utilisé pour
2109
- détecter la racine du projet, les dossiers public et vues, et les
2110
- templates en ligne.</p></dd>
2111
-
2112
- <dt>bind</dt>
2113
- <dd>adresse IP sur laquelle se brancher (par défaut : 0.0.0.0). Utiliser
2114
- seulement pour le serveur intégré.</dd>
2115
-
2116
- <dt>default_encoding</dt>
2117
- <dd>encodage à utiliser si inconnu (par défaut <tt>"utf-8"</tt>)</dd>
2118
-
2119
- <dt>dump_errors</dt>
2120
- <dd>afficher les erreurs dans le <tt>log</tt>.
2121
- </dd>
2122
-
2123
- <dt>environment</dt>
2124
- <dd>environnement courant, par défaut <tt>ENV['APP_ENV']</tt>, ou
2125
- <tt>"development"</tt> si absent.</dd>
2126
-
2127
- <dt>logging</dt>
2128
- <dd>utiliser le <tt>logger</tt>.</dd>
2129
-
2130
- <dt>lock</dt>
2131
- <dd><p>Place un <tt>lock</tt> autour de chaque requête, n’exécutant donc
2132
- qu’une seule requête par processus Ruby.</p>
2133
-
2134
- <p>Activé si votre application n’est pas <tt>thread-safe</tt>. Désactivé
2135
- par défaut.</p></dd>
2136
-
2137
- <dt>method_override</dt>
2138
- <dd>utilise la magie de <tt>_method</tt> afin de permettre des formulaires
2139
- put/delete dans des navigateurs qui ne le permettent pas.
2140
-
2141
- </dd>
2142
- <dt>port</dt>
2143
- <dd>port à écouter. Utiliser seulement pour le serveur intégré.</dd>
2144
-
2145
- <dt>prefixed_redirects</dt>
2146
- <dd>si oui ou non <tt>request.script_name</tt> doit être inséré dans les
2147
- redirections si un chemin non absolu est utilisé. Ainsi, <tt>redirect
2148
- '/foo'</tt> se comportera comme <tt>redirect to('/foo')</tt>. Désactivé
2149
- par défaut.</dd>
2150
-
2151
- <dt>protection</dt>
2152
- <dd>défini s’il faut activer ou non la protection contre les attaques web.
2153
- Voir la section protection précédente.</dd>
2154
-
2155
- <dt>public_dir</dt>
2156
- <dd>alias pour <tt>public_folder</tt>. Voir ci-dessous.</dd>
2157
-
2158
- <dt>public_folder</dt>
2159
- <dd>chemin pour le dossier à partir duquel les fichiers publics sont servis.
2160
- Utilisé seulement si les fichiers statiques doivent être servis (voir le
2161
- paramètre <tt>static</tt>). Si non défini, il découle du paramètre
2162
- <tt>app_file</tt>.</dd>
2163
-
2164
- <dt>reload_templates</dt>
2165
- <dd>si oui ou non les templates doivent être rechargés entre les requêtes.
2166
- Activé en mode développement.</dd>
2167
-
2168
- <dt>root</dt>
2169
- <dd>chemin pour le dossier racine du projet. Si non défini, il découle du
2170
- paramètre <tt>app_file</tt>.</dd>
2171
-
2172
- <dt>raise_errors</dt>
2173
- <dd>soulever les erreurs (ce qui arrêtera l’application). Désactivé par
2174
- défaut sauf lorsque <tt>environment</tt> est défini à
2175
- <tt>"test"</tt>.</dd>
2176
-
2177
- <dt>run</dt>
2178
- <dd>si activé, Sinatra s’occupera de démarrer le serveur, ne pas activer si
2179
- vous utiliser rackup ou autres.</dd>
2180
-
2181
- <dt>running</dt>
2182
- <dd>est-ce que le serveur intégré est en marche ? ne changez pas ce
2183
- paramètre !</dd>
2184
-
2185
- <dt>server</dt>
2186
- <dd>serveur ou liste de serveurs à utiliser pour le serveur intégré. Par
2187
- défaut [‘thin’, ‘mongrel’, ‘webrick’], l’ordre indiquant la
2188
- priorité.</dd>
2189
-
2190
- <dt>sessions</dt>
2191
- <dd>active le support des sessions basées sur les cookies, en utilisant
2192
- <tt>Rack::Session::Cookie</tt>. Reportez-vous à la section ‘Utiliser les
2193
- sessions’ pour plus d’informations.</dd>
2194
-
2195
- <dt>show_exceptions</dt>
2196
- <dd>affiche la trace de l’erreur dans le navigateur lorsqu’une exception se
2197
- produit. Désactivé par défaut sauf lorsque <tt>environment</tt> est
2198
- défini à <tt>"development"</tt>.</dd>
2199
-
2200
- <dt>static</dt>
2201
- <dd>Si oui ou non Sinatra doit s’occuper de servir les fichiers statiques.
2202
- Désactivez si vous utilisez un serveur capable de le gérer lui même. Le
2203
- désactiver augmentera la performance. Activé par défaut pour le style
2204
- classique, désactivé pour le style modulaire.</dd>
2205
-
2206
- <dt>static_cache_control</dt>
2207
- <dd>A définir quand Sinatra rend des fichiers statiques pour ajouter les
2208
- en-têtes <tt>Cache-Control</tt>. Utilise le helper <tt>cache_control</tt>.
2209
- Désactivé par défaut. Utiliser un array explicite pour définir des
2210
- plusieurs valeurs : <tt>set :static_cache_control, [:public, :max_age =>
2211
- 300]</tt></dd>
2212
-
2213
- <dt>threaded</dt>
2214
- <dd>à définir à <tt>true</tt> pour indiquer à Thin d’utiliser
2215
- <tt>EventMachine.defer</tt> pour traiter la requête.</dd>
2216
-
2217
- <dt>views</dt>
2218
- <dd>chemin pour le dossier des vues. Si non défini, il découle du paramètre
2219
- <tt>app_file</tt>.</dd>
2220
-
2221
- <dt>x_cascade</dt>
2222
- <dd>
2223
- Indique s'il faut ou non définir le header X-Cascade lorsqu'aucune route
2224
- ne correspond. Défini à <tt>true</tt> par défaut.
2225
- </dd>
2226
- </dl>
2227
-
2228
- ## Environements
2229
-
2230
- Il existe trois environnements prédéfinis : `"development"`,
2231
- `"production"` et `"test"`. Les environements peuvent être
2232
- sélectionné via la variable d'environnement `APP_ENV`. Sa valeur par défaut
2233
- est `"development"`. Dans ce mode, tous les templates sont rechargés à
2234
- chaque requête. Des handlers spécifiques pour `not_found` et
2235
- `error` sont installés pour vous permettre d'avoir une pile de trace
2236
- dans votre navigateur. En mode `"production"` et `"test"` les
2237
- templates sont mis en cache par défaut.
2238
-
2239
- Pour exécuter votre application dans un environnement différent, définissez la
2240
- variable d'environnement `APP_ENV` :
2241
-
2242
- ``` shell
2243
- APP_ENV=production ruby my_app.rb
2244
- ```
2245
-
2246
- Vous pouvez utiliser une des méthodes `development?`, `test?` et `production?`
2247
- pour déterminer quel est l'environnement en cours :
2248
-
2249
- ```ruby
2250
- get '/' do
2251
- if settings.development?
2252
- "développement !"
2253
- else
2254
- "pas en développement !"
2255
- end
2256
- end
2257
- ```
2258
-
2259
- ## Gérer les erreurs
2260
-
2261
- Les gestionnaires d'erreur s'exécutent dans le même contexte que les routes ou
2262
- les filtres, ce qui veut dire que vous avez accès (entre autres) aux bons
2263
- vieux `haml`, `erb`, `halt`, etc.
2264
-
2265
- ### NotFound
2266
-
2267
- Quand une exception <tt>Sinatra::NotFound</tt> est soulevée, ou que le code
2268
- retour est 404, le gestionnaire <tt>not_found</tt> est invoqué :
2269
-
2270
- ```ruby
2271
- not_found do
2272
- 'Pas moyen de trouver ce que vous cherchez'
2273
- end
2274
- ```
2275
-
2276
- ### Error
2277
-
2278
- Le gestionnaire `error` est invoqué à chaque fois qu'une exception est
2279
- soulevée dans une route ou un filtre. L'objet exception est accessible via la
2280
- variable Rack `sinatra.error` :
2281
-
2282
- ```ruby
2283
- error do
2284
- 'Désolé mais une méchante erreur est survenue - ' + env['sinatra.error'].message
2285
- end
2286
- ```
2287
-
2288
- Erreur sur mesure :
2289
-
2290
- ```ruby
2291
- error MonErreurSurMesure do
2292
- 'Oups ! Il est arrivé...' + env['sinatra.error'].message
2293
- end
2294
- ```
2295
-
2296
- Donc si cette erreur est soulevée :
2297
-
2298
- ```ruby
2299
- get '/' do
2300
- raise MonErreurSurMesure, 'quelque chose de mal'
2301
- end
2302
- ```
2303
-
2304
- La réponse sera :
2305
-
2306
- ```
2307
- Oups ! Il est arrivé... quelque chose de mal
2308
- ```
2309
-
2310
- Alternativement, vous pouvez avoir un gestionnaire d'erreur associé à un code
2311
- particulier :
2312
-
2313
- ```ruby
2314
- error 403 do
2315
- 'Accès interdit'
2316
- end
2317
-
2318
- get '/secret' do
2319
- 403
2320
- end
2321
- ```
2322
-
2323
- Ou un intervalle :
2324
-
2325
- ```ruby
2326
- error 400..510 do
2327
- 'Boom'
2328
- end
2329
- ```
2330
-
2331
- Sinatra installe pour vous quelques gestionnaires `not_found` et
2332
- `error` génériques lorsque vous êtes en environnement de
2333
- `development`.
2334
-
2335
- ## Les Middlewares Rack
2336
-
2337
- Sinatra fonctionne avec [Rack](http://rack.github.io/), une interface standard
2338
- et minimale pour les web frameworks Ruby. Un des points forts de Rack est le
2339
- support de ce que l'on appelle des "middlewares" -- composants qui viennent se
2340
- situer entre le serveur et votre application, et dont le but est de
2341
- visualiser/manipuler la requête/réponse HTTP, et d'offrir diverses
2342
- fonctionnalités classiques.
2343
-
2344
- Sinatra permet d'utiliser facilement des middlewares Rack via la méthode de
2345
- haut niveau `use` :
2346
-
2347
- ```ruby
2348
- require 'sinatra'
2349
- require 'mon_middleware_perso'
2350
-
2351
- use Rack::Lint
2352
- use MonMiddlewarePerso
2353
-
2354
- get '/bonjour' do
2355
- 'Bonjour le monde'
2356
- end
2357
- ```
2358
-
2359
- La sémantique de `use` est identique à celle définie dans le DSL de
2360
- [Rack::Builder](http://www.rubydoc.info/github/rack/rack/master/Rack/Builder)
2361
- (le plus souvent utilisé dans un fichier `rackup`). Par exemple, la méthode
2362
- `use` accepte divers arguments ainsi que des blocs :
2363
-
2364
- ```ruby
2365
- use Rack::Auth::Basic do |identifiant, mot_de_passe|
2366
- identifiant == 'admin' && mot_de_passe == 'secret'
2367
- end
2368
- ```
2369
-
2370
- Rack est distribué avec de nombreux middlewares standards pour loguer, débuguer,
2371
- faire du routage URL, de l'authentification ou gérer des sessions. Sinatra gère
2372
- plusieurs de ces composants automatiquement via son système de configuration, ce
2373
- qui vous dispense de faire un `use` pour ces derniers.
2374
-
2375
- Vous trouverez d'autres middlewares intéressants sur
2376
- [rack](https://github.com/rack/rack/tree/master/lib/rack),
2377
- [rack-contrib](https://github.com/rack/rack-contrib#readm),
2378
- ou en consultant le [wiki de Rack](https://github.com/rack/rack/wiki/List-of-Middleware).
2379
-
2380
- ## Tester
2381
-
2382
- Les tests pour Sinatra peuvent être écrit avec n'importe quelle bibliothèque
2383
- basée sur Rack. [Rack::Test](http://gitrdoc.com/brynary/rack-test) est
2384
- recommandé :
2385
-
2386
- ```ruby
2387
- require 'mon_application_sinatra'
2388
- require 'minitest/autorun'
2389
- require 'rack/test'
2390
-
2391
- class MonTest < Minitest::Test
2392
- include Rack::Test::Methods
2393
-
2394
- def app
2395
- Sinatra::Application
2396
- end
2397
-
2398
- def test_ma_racine
2399
- get '/'
2400
- assert_equal 'Bonjour le monde !', last_response.body
2401
- end
2402
-
2403
- def test_avec_des_parametres
2404
- get '/rencontrer', :nom => 'Frank'
2405
- assert_equal 'Salut Frank !', last_response.body
2406
- end
2407
-
2408
- def test_avec_agent
2409
- get '/', {}, 'HTTP_USER_AGENT' => 'Songbird'
2410
- assert_equal "Vous utilisez Songbird !", last_response.body
2411
- end
2412
- end
2413
- ```
2414
-
2415
- ## Sinatra::Base - Les Middlewares, Bibliothèques, et Applications Modulaires
2416
-
2417
- Définir votre application au niveau supérieur fonctionne bien dans le cas des
2418
- micro-applications mais présente pas mal d'inconvénients pour créer des
2419
- composants réutilisables sous forme de middlewares Rack, de Rails metal, de
2420
- simples librairies avec un composant serveur ou même d'extensions Sinatra. Le
2421
- niveau supérieur suppose une configuration dans le style des micro-applications
2422
- (une application d'un seul fichier, des répertoires `./public` et
2423
- `./views`, des logs, une page d'erreur, etc...). C'est là que
2424
- `Sinatra::Base` prend tout son intérêt :
2425
-
2426
- ```ruby
2427
- require 'sinatra/base'
2428
-
2429
- class MonApplication < Sinatra::Base
2430
- set :sessions, true
2431
- set :foo, 'bar'
2432
-
2433
- get '/' do
2434
- 'Bonjour le monde !'
2435
- end
2436
- end
2437
- ```
2438
-
2439
- Les méthodes de la classe `Sinatra::Base` sont parfaitement identiques à
2440
- celles disponibles via le DSL de haut niveau. Il suffit de deux modifications
2441
- pour transformer la plupart des applications de haut niveau en un composant
2442
- `Sinatra::Base` :
2443
-
2444
- * Votre fichier doit charger `sinatra/base` au lieu de `sinatra`, sinon toutes
2445
- les méthodes du DSL Sinatra seront importées dans l'espace de nom principal.
2446
- * Les gestionnaires de routes, la gestion d'erreur, les filtres et les options
2447
- doivent être placés dans une classe héritant de `Sinatra::Base`.
2448
-
2449
- `Sinatra::Base` est une page blanche. La plupart des options sont
2450
- désactivées par défaut, y compris le serveur intégré. Reportez-vous à
2451
- [Options et Configuration](http://www.sinatrarb.com/configuration.html)
2452
- pour plus d'informations sur les options et leur fonctionnement. Si vous
2453
- souhaitez un comportement plus proche de celui obtenu lorsque vous définissez
2454
- votre application au niveau supérieur (aussi connu sous le nom de style
2455
- Classique), vous pouvez créer une classe héritant de `Sinatra::Application`.
2456
-
2457
- ```ruby
2458
- require 'sinatra/base'
2459
-
2460
- class MyApp < Sinatra::Application
2461
- get '/' do
2462
- 'Bonjour le monde !'
2463
- end
2464
- end
2465
- ```
2466
-
2467
- ### Style modulaire vs. style classique
2468
-
2469
- Contrairement aux idées reçues, il n'y a rien de mal à utiliser le style
2470
- classique. Si c'est ce qui convient pour votre application, vous n'avez
2471
- aucune raison de passer à une application modulaire.
2472
-
2473
- Le principal inconvénient du style classique sur le style modulaire est que vous
2474
- ne pouvez avoir qu'une application par processus Ruby. Si vous pensez en
2475
- utiliser plus, passez au style modulaire. Et rien ne vous empêche de mixer style
2476
- classique et style modulaire.
2477
-
2478
- Si vous passez d'un style à l'autre, souvenez-vous des quelques différences
2479
- mineures en ce qui concerne les paramètres par défaut :
2480
-
2481
- <table>
2482
- <tr>
2483
- <th>Paramètre</th>
2484
- <th>Classique</th>
2485
- <th>Modulaire</th>
2486
- <th>Modulaire</th>
2487
- </tr>
2488
-
2489
- <tr>
2490
- <td>app_file</td>
2491
- <td>fichier chargeant sinatra</td>
2492
- <td>fichier héritant de Sinatra::Base</td>
2493
- <td>fichier héritant de Sinatra::Application</td>
2494
- </tr>
2495
-
2496
- <tr>
2497
- <td>run</td>
2498
- <td>$0 == app_file</td>
2499
- <td>false</td>
2500
- <td>false</td>
2501
- </tr>
2502
-
2503
- <tr>
2504
- <td>logging</td>
2505
- <td>true</td>
2506
- <td>false</td>
2507
- <td>true</td>
2508
- </tr>
2509
-
2510
- <tr>
2511
- <td>method_override</td>
2512
- <td>true</td>
2513
- <td>false</td>
2514
- <td>true</td>
2515
- </tr>
2516
-
2517
- <tr>
2518
- <td>inline_templates</td>
2519
- <td>true</td>
2520
- <td>false</td>
2521
- <td>true</td>
2522
- </tr>
2523
-
2524
- <tr>
2525
- <td>static</td>
2526
- <td>true</td>
2527
- <td>File.exist?(public_folder)</td>
2528
- <td>true</td>
2529
- </tr>
2530
- </table>
2531
-
2532
- ### Servir une application modulaire
2533
-
2534
- Il y a deux façons de faire pour démarrer une application modulaire, démarrez
2535
- avec `run!` :
2536
-
2537
- ```ruby
2538
- # my_app.rb
2539
- require 'sinatra/base'
2540
-
2541
- class MyApp < Sinatra::Base
2542
- # ... code de l'application ici ...
2543
-
2544
- # démarre le serveur si ce fichier est directement exécuté
2545
- run! if app_file == $0
2546
- end
2547
- ```
2548
-
2549
- Démarrez ensuite avec :
2550
-
2551
- ```shell
2552
- ruby my_app.rb
2553
- ```
2554
-
2555
- Ou alors avec un fichier `config.ru`, qui permet d'utiliser n'importe
2556
- quel gestionnaire Rack :
2557
-
2558
- ```ruby
2559
- # config.ru
2560
- require './my_app'
2561
- run MyApp
2562
- ```
2563
-
2564
- Exécutez :
2565
-
2566
- ```shell
2567
- rackup -p 4567
2568
- ```
2569
-
2570
- ### Utiliser une application de style classique avec un fichier config.ru
2571
-
2572
- Ecrivez votre application :
2573
-
2574
- ```ruby
2575
- # app.rb
2576
- require 'sinatra'
2577
-
2578
- get '/' do
2579
- 'Bonjour le monde !'
2580
- end
2581
- ```
2582
-
2583
- Et un fichier `config.ru` correspondant :
2584
-
2585
- ```ruby
2586
- require './app'
2587
- run Sinatra::Application
2588
- ```
2589
-
2590
- ### Quand utiliser un fichier config.ru ?
2591
-
2592
- Quelques cas où vous devriez utiliser un fichier `config.ru` :
2593
-
2594
- * Vous souhaitez déployer avec un autre gestionnaire Rack (Passenger, Unicorn,
2595
- Heroku, ...).
2596
- * Vous souhaitez utiliser plus d'une sous-classe de `Sinatra::Base`.
2597
- * Vous voulez utiliser Sinatra comme un middleware, non en tant que
2598
- endpoint.
2599
-
2600
- **Il n'est pas nécessaire de passer par un fichier `config.ru` pour la
2601
- seule raison que vous êtes passé au style modulaire, et vous n'avez pas besoin
2602
- de passer au style modulaire pour utiliser un fichier `config.ru`.**
2603
-
2604
- ### Utiliser Sinatra comme Middleware
2605
-
2606
- Non seulement Sinatra peut utiliser d'autres middlewares Rack, il peut
2607
- également être à son tour utilisé au-dessus de n'importe quel endpoint Rack
2608
- en tant que middleware. Cet endpoint peut très bien être une autre
2609
- application Sinatra, ou n'importe quelle application basée sur Rack
2610
- (Rails/Ramaze/Camping/...) :
2611
-
2612
- ```ruby
2613
- require 'sinatra/base'
2614
-
2615
- class EcranDeConnexion < Sinatra::Base
2616
- enable :sessions
2617
-
2618
- get('/connexion') { haml :connexion }
2619
-
2620
- post('/connexion') do
2621
- if params['nom'] = 'admin' && params['motdepasse'] = 'admin'
2622
- session['nom_utilisateur'] = params['nom']
2623
- else
2624
- redirect '/connexion'
2625
- end
2626
- end
2627
- end
2628
-
2629
- class MonApp < Sinatra::Base
2630
- # le middleware sera appelé avant les filtres
2631
- use EcranDeConnexion
2632
-
2633
- before do
2634
- unless session['nom_utilisateur']
2635
- halt "Accès refusé, merci de vous <a href='/connexion'>connecter</a>."
2636
- end
2637
- end
2638
-
2639
- get('/') { "Bonjour #{session['nom_utilisateur']}." }
2640
- end
2641
- ```
2642
-
2643
- ### Création dynamique d'applications
2644
-
2645
- Il se peut que vous ayez besoin de créer une nouvelle application à l'exécution
2646
- sans avoir à les assigner à une constante, vous pouvez le faire grâce à
2647
- `Sinatra.new` :
2648
-
2649
- ```ruby
2650
- require 'sinatra/base'
2651
- mon_app = Sinatra.new { get('/') { "salut" } }
2652
- mon_app.run!
2653
- ```
2654
-
2655
- L'application dont elle hérite peut être passé en argument optionnel :
2656
-
2657
- ```ruby
2658
- # config.ru
2659
- require 'sinatra/base'
2660
-
2661
- controleur = Sinatra.new do
2662
- enable :logging
2663
- helpers MyHelpers
2664
- end
2665
-
2666
- map('/a') do
2667
- run Sinatra.new(controleur) { get('/') { 'a' } }
2668
- end
2669
-
2670
- map('/b') do
2671
- run Sinatra.new(controleur) { get('/') { 'b' } }
2672
- end
2673
- ```
2674
-
2675
- C'est notamment utile pour tester des extensions pour Sinatra ou bien pour
2676
- utiliser Sinatra dans votre propre bibliothèque.
2677
-
2678
- Cela permet également d'utiliser très facilement Sinatra comme middleware :
2679
-
2680
- ```ruby
2681
- require 'sinatra/base'
2682
-
2683
- use Sinatra do
2684
- get('/') { ... }
2685
- end
2686
-
2687
- run RailsProject::Application
2688
- ```
2689
-
2690
- ## Contextes et Binding
2691
-
2692
- Le contexte dans lequel vous êtes détermine les méthodes et variables
2693
- disponibles.
2694
-
2695
- ### Contexte de l'application/classe
2696
-
2697
- Une application Sinatra correspond à une sous-classe de `Sinatra::Base`. Il
2698
- s'agit de `Sinatra::Application` si vous utilisez le DSL de haut niveau
2699
- (`require 'sinatra'`). Sinon c'est la sous-classe que vous avez définie. Dans
2700
- le contexte de cette classe, vous avez accès aux méthodes telles que `get` ou
2701
- `before`, mais pas aux objets `request` ou `session` étant donné que toutes
2702
- les requêtes sont traitées par une seule classe d'application.
2703
-
2704
- Les options définies au moyen de `set` deviennent des méthodes de classe :
2705
-
2706
- ```ruby
2707
- class MonApp < Sinatra::Base
2708
- # Eh, je suis dans le contexte de l'application !
2709
- set :foo, 42
2710
- foo # => 42
2711
-
2712
- get '/foo' do
2713
- # Eh, je ne suis plus dans le contexte de l'application !
2714
- end
2715
- end
2716
- ```
2717
-
2718
- Vous avez le binding du contexte de l'application dans :
2719
-
2720
- * Le corps de la classe d'application
2721
- * Les méthodes définies par les extensions
2722
- * Le bloc passé à `helpers`
2723
- * Les procs/blocs utilisés comme argument pour `set`
2724
- * Le bloc passé à `Sinatra.new`
2725
-
2726
- Vous pouvez atteindre ce contexte (donc la classe) de la façon suivante :
2727
-
2728
- * Via l'objet passé dans les blocs `configure` (`configure { |c| ... }`)
2729
- * En utilisant `settings` dans le contexte de la requête
2730
-
2731
- ### Contexte de la requête/instance
2732
-
2733
- Pour chaque requête traitée, une nouvelle instance de votre classe
2734
- d'application est créée et tous vos gestionnaires sont exécutés dans ce
2735
- contexte. Depuis celui-ci, vous pouvez accéder aux objets `request` et
2736
- `session` ou faire appel aux fonctions de rendu telles que `erb` ou `haml`.
2737
- Vous pouvez accéder au contexte de l'application depuis le contexte de la
2738
- requête au moyen de `settings` :
2739
-
2740
- ```ruby
2741
- class MonApp < Sinatra::Base
2742
- # Eh, je suis dans le contexte de l'application !
2743
- get '/ajouter_route/:nom' do
2744
- # Contexte de la requête pour '/ajouter_route/:nom'
2745
- @value = 42
2746
-
2747
- settings.get("/#{params['nom']}") do
2748
- # Contexte de la requête pour "/#{params['nom']}"
2749
- @value # => nil (on est pas au sein de la même requête)
2750
- end
2751
-
2752
- "Route ajoutée !"
2753
- end
2754
- end
2755
- ```
2756
-
2757
- Vous avez le binding du contexte de la requête dans :
2758
-
2759
- * les blocs get, head, post, put, delete, options, patch, link et unlink
2760
- * les filtres before et after
2761
- * les méthodes utilitaires (définies au moyen de `helpers`)
2762
- * les vues et templates
2763
-
2764
- ### Le contexte de délégation
2765
-
2766
- Le contexte de délégation se contente de transmettre les appels de méthodes au
2767
- contexte de classe. Toutefois, il ne se comporte pas à 100% comme le contexte
2768
- de classe car vous n'avez pas le binding de la classe : seules les méthodes
2769
- spécifiquement déclarées pour délégation sont disponibles et il n'est pas
2770
- possible de partager de variables/états avec le contexte de classe
2771
- (comprenez : `self` n'est pas le même). Vous pouvez ajouter des délégations de
2772
- méthode en appelant `Sinatra::Delegator.delegate :method_name`.
2773
-
2774
- Vous avez le binding du contexte de délégation dans :
2775
-
2776
- * Le binding de haut niveau, si vous avez utilisé `require "sinatra"`
2777
- * Un objet qui inclut le module `Sinatra::Delegator`
2778
-
2779
- Pour vous faire une idée, vous pouvez jeter un coup d'oeil au
2780
- [mixin Sinatra::Delegator](https://github.com/sinatra/sinatra/blob/ca06364/lib/sinatra/base.rb#L1609-1633)
2781
- qui [étend l'objet principal](https://github.com/sinatra/sinatra/blob/ca06364/lib/sinatra/main.rb#L28-30).
2782
-
2783
- ## Ligne de commande
2784
-
2785
- Les applications Sinatra peuvent être lancées directement :
2786
-
2787
- ```shell
2788
- ruby mon_application.rb [-h] [-x] [-e ENVIRONNEMENT] [-p PORT] [-o HOTE] [-s SERVEUR]
2789
- ```
2790
-
2791
- Avec les options :
2792
-
2793
- ```
2794
- -h # aide
2795
- -p # déclare le port (4567 par défaut)
2796
- -o # déclare l'hôte (0.0.0.0 par défaut)
2797
- -e # déclare l'environnement (development par défaut)
2798
- -s # déclare le serveur/gestionnaire à utiliser (thin par défaut)
2799
- -x # active le mutex lock (off par défaut)
2800
- ```
2801
-
2802
- ### Multi-threading
2803
-
2804
- _Cette partie est basée sur [une réponse StackOverflow][so-answer] de Konstantin._
2805
-
2806
- Sinatra n'impose pas de modèle de concurrence. Sinatra est thread-safe, vous pouvez
2807
- donc utiliser n'importe quel gestionnaire Rack, comme Thin, Puma ou WEBrick en mode
2808
- multi-threaded.
2809
-
2810
- Cela signifie néanmoins qu'il vous faudra spécifier les paramètres correspondant au
2811
- gestionnaire Rack utilisé lors du démarrage du serveur.
2812
-
2813
- L'exemple ci-dessous montre comment vous pouvez exécuter un serveur Thin de manière
2814
- multi-threaded:
2815
-
2816
- ```
2817
- # app.rb
2818
- require 'sinatra/base'
2819
-
2820
- classe App < Sinatra::Base
2821
-   get '/' do
2822
- 'Bonjour le monde !'
2823
-   end
2824
- end
2825
-
2826
- App.run!
2827
- ```
2828
-
2829
- Pour démarrer le serveur, exécuter la commande suivante:
2830
-
2831
- ```
2832
- thin --threaded start
2833
- ```
2834
-
2835
- [so-answer]: http://stackoverflow.com/questions/6278817/is-sinatra-multi-threaded/6282999#6282999)
2836
-
2837
- ## Configuration nécessaire
2838
-
2839
- Les versions suivantes de Ruby sont officiellement supportées :
2840
-
2841
- <dl>
2842
- <dt>Ruby 1.8.7</dt>
2843
- <dd>
2844
- 1.8.7 est complètement supporté, toutefois si rien ne vous en empêche,
2845
- nous vous recommandons de faire une mise à jour ou bien de passer à JRuby
2846
- ou Rubinius. Le support de Ruby 1.8.7 ne sera pas supprimé avant la sortie
2847
- de Sinatra 2.0. Ruby 1.8.6 n’est plus supporté.
2848
- </dd>
2849
-
2850
- <dt>Ruby 1.9.2</dt>
2851
- <dd>
2852
- 1.9.2 est totalement supporté. N’utilisez pas 1.9.2p0 car il provoque des
2853
- erreurs de segmentation à l’exécution de Sinatra. Son support continuera
2854
- au minimum jusqu’à la sortie de Sinatra 1.5.
2855
- </dd>
2856
-
2857
- <dt>Ruby 1.9.3</dt>
2858
- <dd>
2859
- 1.9.3 est totalement supporté et recommandé. Nous vous rappelons que passer
2860
- à 1.9.3 depuis une version précédente annulera toutes les sessions. 1.9.3
2861
- sera supporté jusqu'à la sortie de Sinatra 2.0.
2862
- </dd>
2863
-
2864
- <dt>Ruby 2.0.0</dt>
2865
- <dd>
2866
- 2.0.0 est totalement supporté et recommandé. L'abandon de son support
2867
- officiel n'est pas à l'ordre du jour.
2868
- </dd>
2869
-
2870
- <dt>Rubinius</dt>
2871
- <dd>
2872
- Rubinius est officiellement supporté (Rubinius >= 2.x). Un <tt>gem install
2873
- puma</tt> est recommandé.
2874
- </dd>
2875
-
2876
- <dt>JRuby</dt>
2877
- <dd>
2878
- La dernière version stable de JRuby est officiellement supportée. Il est
2879
- déconseillé d'utiliser des extensions C avec JRuby. Un <tt>gem install
2880
- trinidad</tt> est recommandé.
2881
- </dd>
2882
- </dl>
2883
-
2884
- Nous gardons également un oeil sur les versions Ruby à venir.
2885
-
2886
- Les implémentations Ruby suivantes ne sont pas officiellement supportées mais
2887
- sont malgré tout connues pour permettre de faire fonctionner Sinatra :
2888
-
2889
- * Versions plus anciennes de JRuby et Rubinius
2890
- * Ruby Enterprise Edition
2891
- * MacRuby, Maglev, IronRuby
2892
- * Ruby 1.9.0 et 1.9.1 (mais nous déconseillons leur utilisation)
2893
-
2894
- Le fait de ne pas être officiellement supporté signifie que si quelque chose
2895
- ne fonctionne pas sur cette plateforme uniquement alors c'est un problème de la
2896
- plateforme et pas un bug de Sinatra.
2897
-
2898
- Nous lançons également notre intégration continue (CI) avec ruby-head (la
2899
- future 2.1.0), mais nous ne pouvont rien garantir étant donné les évolutions
2900
- continuelles. La version 2.1.0 devrait être totalement supportée.
2901
-
2902
- Sinatra devrait fonctionner sur n'importe quel système d'exploitation
2903
- supporté par l'implémentation Ruby choisie.
2904
-
2905
- Si vous utilisez MacRuby, vous devriez `gem install control_tower`.
2906
-
2907
- Il n'est pas possible d'utiliser Sinatra sur Cardinal, SmallRuby, BlueRuby ou
2908
- toute version de Ruby antérieure à 1.8.7 à l'heure actuelle.
2909
-
2910
- ## Essuyer les plâtres
2911
-
2912
- Si vous souhaitez tester la toute dernière version de Sinatra, n'hésitez pas
2913
- à faire tourner votre application sur la branche master, celle-ci devrait être
2914
- stable.
2915
-
2916
- Pour cela, la méthode la plus simple est d'installer une gem de prerelease que
2917
- nous publions de temps en temps :
2918
-
2919
- ```shell
2920
- gem install sinatra --pre
2921
- ```
2922
- Ce qui permet de bénéficier des toutes dernières fonctionnalités.
2923
-
2924
- ### Installer avec Bundler
2925
-
2926
- Il est cependant conseillé de passer par [Bundler](http://bundler.io) pour
2927
- faire tourner votre application avec la dernière version de Sinatra.
2928
-
2929
- Pour commencer, installez bundler si nécessaire :
2930
-
2931
- ```shell
2932
- gem install bundler
2933
- ```
2934
-
2935
- Ensuite, créez un fichier `Gemfile` dans le dossier de votre projet :
2936
-
2937
- ```ruby
2938
- source 'https://rubygems.org'
2939
- gem 'sinatra', :github => "sinatra/sinatra"
2940
-
2941
- # autres dépendances
2942
- gem 'haml' # si par exemple vous utilisez haml
2943
- gem 'activerecord', '~> 3.0' # au cas où vous auriez besoin de ActiveRecord 3.x
2944
- ```
2945
-
2946
- Notez que vous devez lister toutes les dépendances de votre application dans
2947
- ce fichier `Gemfile`. Les dépendances directes de Sinatra (Rack et Tilt) seront
2948
- automatiquement téléchargées et ajoutées par Bundler.
2949
-
2950
- Vous pouvez alors lancer votre application de la façon suivante :
2951
-
2952
- ```shell
2953
- bundle exec ruby myapp.rb
2954
- ```
2955
-
2956
- ### Faire un clone local
2957
-
2958
- Si vous ne souhaitez pas employer Bundler, vous pouvez cloner Sinatra en local
2959
- dans votre projet et démarrez votre application avec le dossier `sinatra/lib`
2960
- dans le `$LOAD_PATH` :
2961
-
2962
- ```shell
2963
- cd myapp
2964
- git clone git://github.com/sinatra/sinatra.git
2965
- ruby -I sinatra/lib myapp.rb
2966
- ```
2967
-
2968
- Et de temps en temps, vous devrez récupérer la dernière version du code source
2969
- de Sinatra :
2970
-
2971
- ```shell
2972
- cd myapp/sinatra
2973
- git pull
2974
- ```
2975
-
2976
- ### Installer globalement
2977
-
2978
- Une dernière méthode consiste à construire la gem vous-même :
2979
-
2980
- ```shell
2981
- git clone git://github.com/sinatra/sinatra.git
2982
- cd sinatra
2983
- rake sinatra.gemspec
2984
- rake install
2985
- ```
2986
-
2987
- Si vous installez les gems en tant que root, vous devez encore faire un :
2988
-
2989
- ```shell
2990
- sudo rake install
2991
- ```
2992
-
2993
- ## Versions
2994
-
2995
- Sinatra se conforme aux [versions sémantiques](http://semver.org/), aussi bien
2996
- SemVer que SemVerTag.
2997
-
2998
- ## Mais encore
2999
-
3000
- * [Site internet](http://www.sinatrarb.com/) - Plus de documentation,
3001
- de news, et des liens vers d'autres ressources.
3002
- * [Contribuer](http://www.sinatrarb.com/contributing) - Vous avez trouvé un
3003
- bug ? Besoin d'aide ? Vous avez un patch ?
3004
- * [Suivi des problèmes](https://github.com/sinatra/sinatra/issues)
3005
- * [Twitter](https://twitter.com/sinatra)
3006
- * [Mailing List](http://groups.google.com/group/sinatrarb/topics)
3007
- * IRC : [#sinatra](irc://chat.freenode.net/#sinatra) sur http://freenode.net
3008
- * [Sinatra Book](https://github.com/sinatra/sinatra-book/) Tutoriels et recettes
3009
- * [Sinatra Recipes](http://recipes.sinatrarb.com/) trucs et astuces rédigés par
3010
- la communauté
3011
- * Documentation API de la [dernière version](http://www.rubydoc.info/gems/sinatra)
3012
- ou du [HEAD courant](http://www.rubydoc.info/github/sinatra/sinatra) sur
3013
- http://www.rubydoc.info/
3014
- * [CI server](https://travis-ci.org/sinatra/sinatra)