sinatra 2.2.4 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sinatra might be problematic. Click here for more details.

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)