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