sinatra 1.2.0 → 1.2.1
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/AUTHORS +2 -0
- data/CHANGES +13 -0
- data/Gemfile +1 -6
- data/README.de.rdoc +173 -11
- data/README.es.rdoc +22 -8
- data/README.fr.rdoc +1033 -172
- data/README.rdoc +33 -17
- data/README.zh.rdoc +2 -2
- data/Rakefile +17 -2
- data/lib/sinatra/base.rb +23 -7
- data/sinatra.gemspec +2 -2
- data/test/base_test.rb +1 -1
- data/test/helper.rb +6 -0
- data/test/helpers_test.rb +29 -0
- data/test/request_test.rb +1 -1
- data/test/routing_test.rb +13 -7
- data/test/settings_test.rb +1 -1
- data/test/sinatra_test.rb +1 -1
- data/test/templates_test.rb +8 -0
- metadata +197 -225
data/AUTHORS
CHANGED
data/CHANGES
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
= 1.2.1 / 2011-03-17
|
2
|
+
|
3
|
+
* Use a generated session secret when using `enable :sessions`. (Konstantin
|
4
|
+
Haase)
|
5
|
+
|
6
|
+
* Fixed a bug where the wrong content type was used if no content type was set
|
7
|
+
and a template engine was used with a different engine for the layout with
|
8
|
+
different default content types, say Less embedded in Slim. (Konstantin
|
9
|
+
Haase)
|
10
|
+
|
11
|
+
* README translations improved (Gabriel Andretta, burningTyger, Sylvain Desvé,
|
12
|
+
Gregor Schmidt)
|
13
|
+
|
1
14
|
= 1.2.0 / 2011-03-03
|
2
15
|
|
3
16
|
* Added `slim` rendering method for rendering Slim templates. (Steve
|
data/Gemfile
CHANGED
@@ -21,6 +21,7 @@ gem 'less', :group => 'less'
|
|
21
21
|
gem 'liquid', :group => 'liquid'
|
22
22
|
gem 'nokogiri', :group => 'nokogiri'
|
23
23
|
gem 'slim', :group => 'slim'
|
24
|
+
gem 'RedCloth', :group => 'redcloth'
|
24
25
|
|
25
26
|
|
26
27
|
if RUBY_VERSION > '1.8.6'
|
@@ -40,12 +41,6 @@ platforms :ruby_18, :jruby do
|
|
40
41
|
gem 'radius', :group => 'radius'
|
41
42
|
end
|
42
43
|
|
43
|
-
platforms :mri do
|
44
|
-
# bundler platforms are broken
|
45
|
-
next unless RUBY_ENGINE == 'ruby'
|
46
|
-
gem 'RedCloth', :group => 'redcloth'
|
47
|
-
end
|
48
|
-
|
49
44
|
platforms :mri_18 do
|
50
45
|
# bundler platforms are broken
|
51
46
|
next unless RUBY_ENGINE == 'ruby'
|
data/README.de.rdoc
CHANGED
@@ -18,10 +18,13 @@ Einfach via +rubygems+ installieren und starten:
|
|
18
18
|
|
19
19
|
Die Seite kann nun unter http://localhost:4567 betrachtet werden.
|
20
20
|
|
21
|
+
Es wird empfohlen den Thin Server via <tt>gem install thin</tt> zu installieren,
|
22
|
+
den Sinatra, soweit vorhanden, dann automatisch verwendet.
|
23
|
+
|
21
24
|
== Routen
|
22
25
|
|
23
26
|
In Sinatra wird eine Route durch eine HTTP-Methode und ein URL-Muster
|
24
|
-
definiert. Jeder dieser Routen wird ein Ruby-Block zugeordnet
|
27
|
+
definiert. Jeder dieser Routen wird ein Ruby-Block zugeordnet:
|
25
28
|
|
26
29
|
get '/' do
|
27
30
|
.. zeige etwas ..
|
@@ -62,7 +65,7 @@ Man kann auf diese auch mit Blockparametern zugreifen:
|
|
62
65
|
end
|
63
66
|
|
64
67
|
Routenmuster können auch mit Splat- oder Wildcardparametern über das
|
65
|
-
<tt>params[:splat]</tt> Array angesprochen werden
|
68
|
+
<tt>params[:splat]</tt> Array angesprochen werden:
|
66
69
|
|
67
70
|
get '/sag/*/zu/*' do
|
68
71
|
# passt auf /sag/hallo/zu/welt
|
@@ -156,6 +159,46 @@ Damit lässt sich relativ einfach Streaming implementieren:
|
|
156
159
|
|
157
160
|
get('/') { Stream.new }
|
158
161
|
|
162
|
+
===Eigene Routenmuster
|
163
|
+
Wie oben schon beschrieben, ist Sinatra von Haus aus mit Unterstützung für
|
164
|
+
String Muster und Reguläre Ausdrücke zum Abgleichen von Routen ausgestattet.
|
165
|
+
Das muss aber noch nicht alles sein, man kann ohne größeren Aufwand auch
|
166
|
+
eigene Routenmuster erstellen:
|
167
|
+
|
168
|
+
class AllButPattern
|
169
|
+
Match = Struct.new(:captures)
|
170
|
+
|
171
|
+
def initialize(except)
|
172
|
+
@except = except
|
173
|
+
@captures = Match.new([])
|
174
|
+
end
|
175
|
+
|
176
|
+
def match(str)
|
177
|
+
@captures unless @except === str
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def all_but(pattern)
|
182
|
+
AllButPattern.new(pattern)
|
183
|
+
end
|
184
|
+
|
185
|
+
get all_but("/index") do
|
186
|
+
# ...
|
187
|
+
end
|
188
|
+
|
189
|
+
Beachte, dass das obige Beispiel etwas übertrieben wirkt. Es geht auch leichter:
|
190
|
+
|
191
|
+
get // do
|
192
|
+
pass if request.path_info == "/index"
|
193
|
+
# ...
|
194
|
+
end
|
195
|
+
|
196
|
+
Oder unter Verwendung eines negativen look ahead:
|
197
|
+
|
198
|
+
get %r{^(?!/index$)} do
|
199
|
+
# ...
|
200
|
+
end
|
201
|
+
|
159
202
|
== Statische Dateien
|
160
203
|
|
161
204
|
Statische Dateien werden aus dem <tt>./public</tt> Ordner ausgeliefert. Es ist
|
@@ -407,6 +450,7 @@ Ebenso ist es möglich Markdown mit BlueCloth anstelle von RDiscount zu parsen:
|
|
407
450
|
end
|
408
451
|
|
409
452
|
Das sollte <tt>./views/index.md</tt> mit BlueCloth rendern.
|
453
|
+
|
410
454
|
=== Textile-Templates
|
411
455
|
|
412
456
|
Das +redcloth+ gem wird benötigt, um Textile-Templates rendern zu können:
|
@@ -460,7 +504,7 @@ mit <tt>./views/post.haml</tt> als Layout rendern.
|
|
460
504
|
|
461
505
|
Das +rdoc+ gem wird benötigt, um RDoc-Templates rendern zu können:
|
462
506
|
|
463
|
-
#
|
507
|
+
# rdoc/markup/to_html muss eingebunden werden
|
464
508
|
require "rdoc/markup/to_html"
|
465
509
|
|
466
510
|
get '/' do
|
@@ -643,13 +687,13 @@ werden:
|
|
643
687
|
end
|
644
688
|
|
645
689
|
Wenn ein Template mit dem Namen "layout" existiert, wird es bei jedem Aufruf
|
646
|
-
verwendet. Durch <tt>:layout => false</tt> kann das Ausführen verhindert werden
|
690
|
+
verwendet. Durch <tt>:layout => false</tt> kann das Ausführen verhindert werden:
|
647
691
|
|
648
692
|
get '/' do
|
649
693
|
haml :index, :layout => !request.xhr?
|
650
694
|
end
|
651
695
|
|
652
|
-
===
|
696
|
+
=== Dateiendungen zuordnen
|
653
697
|
|
654
698
|
Um eine Dateiendung einer Template Engine zuzuordnen, benutzt man am besten
|
655
699
|
<tt>Tilt.register</tt>. Wenn man zum Beispiel die Dateiendung +tt+ für Textile
|
@@ -673,7 +717,8 @@ Rendering-Methode erstellen:
|
|
673
717
|
end
|
674
718
|
|
675
719
|
Dieser Code rendert <tt>./views/application.mtt</tt>. Siehe
|
676
|
-
https://github.com/rtomayko/tilt
|
720
|
+
github.com/rtomayko/tilt[https://github.com/rtomayko/tilt],
|
721
|
+
um mehr über Tilt zu lernen.
|
677
722
|
|
678
723
|
== Filter
|
679
724
|
|
@@ -736,6 +781,44 @@ definiert, die in Routen und Templates verwendet werden können:
|
|
736
781
|
bar(params[:name])
|
737
782
|
end
|
738
783
|
|
784
|
+
===Sessions verwenden
|
785
|
+
Sessions werden verwendet, um Zustände zwischen den Requests zu speichern.
|
786
|
+
Sind sie aktiviert, hat man einen Session Hash pro Benutzer Session:
|
787
|
+
|
788
|
+
enable :sessions
|
789
|
+
|
790
|
+
get '/' do
|
791
|
+
"value = " << session[:value].inspect
|
792
|
+
end
|
793
|
+
|
794
|
+
get '/:value' do
|
795
|
+
session[:value] = params[:value]
|
796
|
+
end
|
797
|
+
|
798
|
+
Beachte, dass <tt>enable :sessions</tt> alle Daten in einem Cookie speichert.
|
799
|
+
Unter Umständen kann dies negative Effekte haben, z.B. verursachen viele Daten
|
800
|
+
höheren, teilweise überflüssigen Traffic. Um das zu vermeiden, kann man eine
|
801
|
+
Rack Session Middleware verwenden. Dann aber *nicht* <tt>enable :sessions</tt>
|
802
|
+
aufrufen, sondern die Middleware wie üblich in das Programm einbinden:
|
803
|
+
|
804
|
+
use Rack::Session::Pool, :expire_after => 2592000
|
805
|
+
|
806
|
+
get '/' do
|
807
|
+
"value = " << session[:value].inspect
|
808
|
+
end
|
809
|
+
|
810
|
+
get '/:value' do
|
811
|
+
session[:value] = params[:value]
|
812
|
+
end
|
813
|
+
|
814
|
+
Um die Sicherheit zu erhöhen, werden Cookies, die Session-Daten führen, mit
|
815
|
+
einem sogenannten Session Secret signiert. Da sich jedoch dieses Geheimwort
|
816
|
+
bei jedem Neustart der Applikation automatisch ändert, ist es sinnvoll selber
|
817
|
+
eins zu wählen, damit alle Instanzen der Applikation sich das gleiche Session
|
818
|
+
Secret teilen:
|
819
|
+
|
820
|
+
set :session_secret, 'super secret'
|
821
|
+
|
739
822
|
== Anhalten
|
740
823
|
|
741
824
|
Zum sofortigen stoppen eines Request in einem Filter oder einer Route:
|
@@ -758,6 +841,10 @@ Sogar mit Headers:
|
|
758
841
|
|
759
842
|
halt 402, {'Content-Type' => 'text/plain'}, 'Rache'
|
760
843
|
|
844
|
+
Natürlich ist es auch möglich ein Template mit +halt+ zu verwenden:
|
845
|
+
|
846
|
+
halt erb(:error)
|
847
|
+
|
761
848
|
== Weiterspringen
|
762
849
|
|
763
850
|
Eine Route kann mittels <tt>pass</tt> zu der nächsten passenden Route springen:
|
@@ -868,7 +955,7 @@ werden:
|
|
868
955
|
redirect to('/bar')
|
869
956
|
end
|
870
957
|
|
871
|
-
Weitere Parameter werden wie Argumente der +halt+ Methode behandelt
|
958
|
+
Weitere Parameter werden wie Argumente der +halt+ Methode behandelt:
|
872
959
|
|
873
960
|
redirect to('/bar'), 303
|
874
961
|
redirect 'http://google.com', 'Hier bist Du falsch'
|
@@ -987,6 +1074,23 @@ Der <tt>request.body</tt> ist einn IO- oder StringIO-Objekt:
|
|
987
1074
|
"Hallo #{daten['name']}!"
|
988
1075
|
end
|
989
1076
|
|
1077
|
+
=== Anhänge
|
1078
|
+
|
1079
|
+
Damit der Browser erkennt, dass ein Response gespeichert werden soll und nicht
|
1080
|
+
im Browser angezeigt wird, kann der +attachment+ Helfer verwendet werden:
|
1081
|
+
|
1082
|
+
get '/' do
|
1083
|
+
attachment
|
1084
|
+
"Speichern!"
|
1085
|
+
end
|
1086
|
+
|
1087
|
+
Ebenso kann man einen Dateinamen als Parameter hinzufügen:
|
1088
|
+
|
1089
|
+
get '/' do
|
1090
|
+
attachment "info.txt"
|
1091
|
+
"Speichern!"
|
1092
|
+
end
|
1093
|
+
|
990
1094
|
|
991
1095
|
=== Nachschlagen von Template Dateien
|
992
1096
|
|
@@ -1232,7 +1336,7 @@ Alternativ kann ein Error Handler auch für Statuscode definiert werden:
|
|
1232
1336
|
Oder ein Statuscode-Bereich:
|
1233
1337
|
|
1234
1338
|
error 400..510 do
|
1235
|
-
'
|
1339
|
+
'Bums'
|
1236
1340
|
end
|
1237
1341
|
|
1238
1342
|
Sinatra setzt verschiedene <tt>not_found</tt> und <tt>error</tt>
|
@@ -1448,7 +1552,7 @@ Es ist nicht nur möglich andere Rack-Middleware mit Sinatra zu nutzen, man
|
|
1448
1552
|
kann außerdem jede Sinatra-Anwendung selbst als Middlware vor jeden beliebigen
|
1449
1553
|
Rack-Endpunkt hängen. Bei diesem Endpunkt muss es sich nicht um eine andere
|
1450
1554
|
Sinatra-Anwendung handen, es kann jede andere Rack-Anwendung sein
|
1451
|
-
(Rails/Ramaze/Camping/...)
|
1555
|
+
(Rails/Ramaze/Camping/...):
|
1452
1556
|
|
1453
1557
|
require 'sinatra/base'
|
1454
1558
|
|
@@ -1525,7 +1629,7 @@ Für jede eingehende Anfrage wird eine neue Instanz der Anwendungsklasse
|
|
1525
1629
|
erstellt und alle Handlers werden in diesem Scope ausgeführt. Aus diesem Scope
|
1526
1630
|
heraus kann man auf +request+ oder +session+ zugreifen und Methoden wie +erb+
|
1527
1631
|
oder +haml+ aufrufen. Man kann mit der +settings+ Methode außerdem auf den
|
1528
|
-
Anwengungsscope zugreifen
|
1632
|
+
Anwengungsscope zugreifen:
|
1529
1633
|
|
1530
1634
|
class MyApp < Sinatra::Base
|
1531
1635
|
# Hey, ich bin im Anwendungsscope!
|
@@ -1562,7 +1666,8 @@ anderes +self+). Man kann mit <tt>Sinatra::Delegator.delegate
|
|
1562
1666
|
Im Delegation-Scop befindet man sich:
|
1563
1667
|
|
1564
1668
|
* Im Top-Level, wenn man <tt>require 'sinatra'</tt> aufgerufen hat.
|
1565
|
-
* In einem Objekt, dass mit dem <tt>Sinatra::Delegator</tt> mixin erweitert
|
1669
|
+
* In einem Objekt, dass mit dem <tt>Sinatra::Delegator</tt> mixin erweitert
|
1670
|
+
wurde.
|
1566
1671
|
|
1567
1672
|
Schau am besten im Code nach: Hier ist
|
1568
1673
|
{Sinatra::Delegator mixin}[http://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L1064]
|
@@ -1584,6 +1689,59 @@ Die Optionen sind:
|
|
1584
1689
|
-s # Rack Server/Handler setzen (Standard ist thin)
|
1585
1690
|
-x # Mutex lock einschalten (Standard ist off)
|
1586
1691
|
|
1692
|
+
== Systemanforderungen
|
1693
|
+
|
1694
|
+
Es wird empfohlen Sinatra unter Ruby 1.8.7, 1.9.2, JRuby oder Rubinius zu
|
1695
|
+
installieren.
|
1696
|
+
|
1697
|
+
Die folgenden Versionen werden offiziell unterstützt:
|
1698
|
+
|
1699
|
+
[ Ruby 1.8.6 ]
|
1700
|
+
Es wird nicht empfohlen 1.8.6 für Sinatra einzusetzen. Trotzdem wird es
|
1701
|
+
offiziell bis Sinatra 1.3.0 unterstützt werden. RDoc und CoffeeScript
|
1702
|
+
Templates werden in dieser Version nicht unterstützt. 1.8.6 hat ein größeres
|
1703
|
+
Speicherleck in seiner Hash Implementation, das von Sinatra Versionen vor
|
1704
|
+
1.1.1 ausgelöst wird. Die aktuelle Version verhindert das zwar explizit, aber
|
1705
|
+
unter Einbussen in der Performance. Ebenso muss Sinatra mit Rack 1.1.x laufen,
|
1706
|
+
da Rack >= 1.2 Ruby 1.8.6 nicht mehr unterstützt.
|
1707
|
+
|
1708
|
+
[ Ruby 1.8.7 ]
|
1709
|
+
1.8.7 wird vollständig unterstützt, aber solange nichts dagegen spricht,
|
1710
|
+
wird ein Update auf 1.9.2 oder ein Umstieg auf JRuby/Rubinius empfohlen.
|
1711
|
+
|
1712
|
+
[ Ruby 1.9.2 ]
|
1713
|
+
1.9.2 wird unterstützt und empfohlen. Beachte, dass Markaby und Radius
|
1714
|
+
momentan noch nicht kompatibel sind mit 1.9. Version 1.9.0p0 sollte nicht
|
1715
|
+
verwendet werden, da unter Sinatra immer wieder Segfaults auftreten.
|
1716
|
+
|
1717
|
+
[ Rubinius ]
|
1718
|
+
Rubinius (rbx >= 1.2.2) wird offiziell unter Ausnahme von Textile
|
1719
|
+
Templates unterstützt.
|
1720
|
+
|
1721
|
+
[ JRuby ]
|
1722
|
+
Jruby wird offiziell unterstützt (JRuby >= 1.5.6). Probleme mit Template
|
1723
|
+
Bibliotheken Dritter sind nicht bekannt. Falls JRuby zum Einsatz kommt, sollte
|
1724
|
+
aber darauf geachtet werden, dass ein JRuby Rack Handler zum Einsatz kommen –
|
1725
|
+
der Thin Web Server wird bisher noch nicht unterstütz.
|
1726
|
+
|
1727
|
+
Weiterhin werden wir auf kommende Ruby Versionen ein Auge haben.
|
1728
|
+
|
1729
|
+
Die nachfolgend aufgeführten Ruby Implementationen werden offiziell nicht von
|
1730
|
+
Sinatra unterstützt, funktionieren aber normalerweise:
|
1731
|
+
|
1732
|
+
* Ältere Versionen von JRuby und Rubinius
|
1733
|
+
* MacRuby
|
1734
|
+
* Maglev
|
1735
|
+
* IronRuby
|
1736
|
+
* Ruby 1.9.0 und 1.9.1
|
1737
|
+
|
1738
|
+
Nicht offiziell unterstützt bedeutet, dass wenn Sachen nicht funktionieren,
|
1739
|
+
dann gehen wir davon aus, dass es nicht an Sinatra, sondern an der jeweiligen
|
1740
|
+
Implentierung liegt.
|
1741
|
+
|
1742
|
+
Sinatra sollte auf jedem Betriebssystem laufen, dass den gewählten Ruby
|
1743
|
+
Interpreter unterstützt.
|
1744
|
+
|
1587
1745
|
== Der neueste Stand (The Bleeding Edge)
|
1588
1746
|
Um auf dem neusten Stand zu bleiben, kannst Du den Master Branch verwenden. Er
|
1589
1747
|
sollte recht stabil sein. Ebenso gibt es von Zeit zu Zeit prerelease Gems, die
|
@@ -1657,7 +1815,10 @@ so lauten:
|
|
1657
1815
|
|
1658
1816
|
sudo rake install
|
1659
1817
|
|
1818
|
+
== Versionsverfahren
|
1660
1819
|
|
1820
|
+
Sinatra folgt dem sog. {Semantic Versioning}[http://semver.org/], d.h. SemVer
|
1821
|
+
und SemVerTag.
|
1661
1822
|
|
1662
1823
|
== Mehr
|
1663
1824
|
|
@@ -1669,3 +1830,4 @@ Fehler gefunden? Brauchst du Hilfe? Hast du einen Patch?
|
|
1669
1830
|
* {Twitter}[http://twitter.com/sinatra]
|
1670
1831
|
* {Mailingliste}[http://groups.google.com/group/sinatrarb]
|
1671
1832
|
* {IRC: #sinatra}[irc://chat.freenode.net/#sinatra] auf http://freenode.net
|
1833
|
+
|
data/README.es.rdoc
CHANGED
@@ -66,7 +66,7 @@ También podés acceder a los parámetros nombrados usando parámetros de bloque
|
|
66
66
|
end
|
67
67
|
|
68
68
|
Los patrones de ruta también pueden incluir parámetros splat (o wildcard),
|
69
|
-
accesibles a través del arreglo <tt>params[:splat]</tt
|
69
|
+
accesibles a través del arreglo <tt>params[:splat]</tt>:
|
70
70
|
|
71
71
|
get '/decir/*/al/*' do
|
72
72
|
# coincide con /decir/hola/al/mundo
|
@@ -165,11 +165,11 @@ definir tus propios comparadores muy fácilmente:
|
|
165
165
|
|
166
166
|
def initialize(excepto)
|
167
167
|
@excepto = excepto
|
168
|
-
@
|
168
|
+
@capturas = Match.new([])
|
169
169
|
end
|
170
170
|
|
171
171
|
def match(str)
|
172
|
-
@
|
172
|
+
@capturas unless @excepto === str
|
173
173
|
end
|
174
174
|
end
|
175
175
|
|
@@ -687,7 +687,7 @@ Las plantillas también pueden ser definidas usando el método top-level
|
|
687
687
|
Si existe una plantilla con el nombre "layout", va a ser usada cada vez que
|
688
688
|
una plantilla es renderizada. Podés desactivar los layouts individualmente
|
689
689
|
pasando <tt>:layout => false</tt> o globalmente con
|
690
|
-
<tt>set :haml, :layout => false</tt
|
690
|
+
<tt>set :haml, :layout => false</tt>:
|
691
691
|
|
692
692
|
get '/' do
|
693
693
|
haml :index, :layout => !request.xhr?
|
@@ -816,6 +816,15 @@ pero con la salvedad de que *no* tenés que llamar a <tt>enable :sessions</tt>:
|
|
816
816
|
session[:valor] = params[:valor]
|
817
817
|
end
|
818
818
|
|
819
|
+
Para incrementar la seguridad, los datos de la sesión almacenados en
|
820
|
+
la cookie son firmados con un secreto de sesión. Este secreto, es
|
821
|
+
generado aleatoriamente por Sinatra. De cualquier manera, hay que
|
822
|
+
tener en cuenta que cada vez que inicies la aplicación se va a generar
|
823
|
+
uno nuevo. Así, si querés que todas las instancias de tu aplicación
|
824
|
+
compartan un único secreto, tenés que definirlo vos:
|
825
|
+
|
826
|
+
set :session_secret, 'super secreto'
|
827
|
+
|
819
828
|
=== Interrupción
|
820
829
|
|
821
830
|
Para detener inmediatamente una petición dentro de un filtro o una ruta usá:
|
@@ -997,7 +1006,7 @@ Podés asignar el encabezado Cache-Control fácilmente:
|
|
997
1006
|
"cachealo!"
|
998
1007
|
end
|
999
1008
|
|
1000
|
-
Pro tip: configurar el cacheo en un filtro +before
|
1009
|
+
Pro tip: configurar el cacheo en un filtro +before+:
|
1001
1010
|
|
1002
1011
|
before do
|
1003
1012
|
cache_control :public, :must_revalidate, :max_age => 60
|
@@ -1013,7 +1022,7 @@ Si estás usando el helper +expires+ para definir el encabezado correspondiente,
|
|
1013
1022
|
Para usar cachés adecuadamente, deberías considerar usar +etag+ y
|
1014
1023
|
+last_modified+. Es recomendable que llames a estos helpers *antes* de hacer
|
1015
1024
|
cualquier trabajo pesado, ya que van a enviar la respuesta inmediatamente si
|
1016
|
-
el cliente ya tiene la versión actual en su cach
|
1025
|
+
el cliente ya tiene la versión actual en su caché:
|
1017
1026
|
|
1018
1027
|
get '/articulo/:id' do
|
1019
1028
|
@articulo = Articulo.find params[:id]
|
@@ -1131,7 +1140,7 @@ El objeto <tt>request.body</tt> es una instancia de IO o StringIO:
|
|
1131
1140
|
=== Archivos Adjuntos
|
1132
1141
|
|
1133
1142
|
Podés usar el método helper +attachment+ para indicarle al navegador que
|
1134
|
-
almacene la respuesta en el disco en lugar de mostrarla en pantalla
|
1143
|
+
almacene la respuesta en el disco en lugar de mostrarla en pantalla:
|
1135
1144
|
|
1136
1145
|
get '/' do
|
1137
1146
|
attachment
|
@@ -1589,7 +1598,7 @@ iniciarla con <tt>config.ru</tt>.</b>
|
|
1589
1598
|
Sinatra no solo es capaz de usar otro Rack middleware, sino que a su vez,
|
1590
1599
|
cualquier aplicación Sinatra puede ser agregada delante de un endpoint Rack
|
1591
1600
|
como middleware. Este endpoint puede ser otra aplicación Sinatra, o cualquier
|
1592
|
-
aplicación basada en Rack (Rails/Ramaze/Camping/...)
|
1601
|
+
aplicación basada en Rack (Rails/Ramaze/Camping/...):
|
1593
1602
|
|
1594
1603
|
require 'sinatra/base'
|
1595
1604
|
|
@@ -1838,6 +1847,11 @@ Si instalás tus gems como root, el último paso debería ser
|
|
1838
1847
|
|
1839
1848
|
sudo rake install
|
1840
1849
|
|
1850
|
+
== Versionado
|
1851
|
+
|
1852
|
+
Sinatra utiliza el {Versionado Semántico}[http://semver.org/],
|
1853
|
+
siguiendo las especificaciones SemVer y SemVerTag.
|
1854
|
+
|
1841
1855
|
== Lecturas Recomendadas
|
1842
1856
|
|
1843
1857
|
* {Sito web del proyecto}[http://www.sinatrarb.com/] - Documentación
|
data/README.fr.rdoc
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
= Sinatra
|
2
|
-
<i>Attention: Ce document correspond à la traduction de la version anglaise et
|
2
|
+
<i>Attention: Ce document correspond à la traduction de la version anglaise et
|
3
|
+
il n'est peut être plus à jour.</i>
|
3
4
|
|
4
5
|
Sinatra est un DSL pour créer rapidement des applications web en Ruby et sans
|
5
6
|
effort:
|
@@ -17,9 +18,13 @@ Installez le gem et lancez avec:
|
|
17
18
|
|
18
19
|
Le résultat est visible sur: http://localhost:4567
|
19
20
|
|
21
|
+
Il est également recommandé d'exécuter <tt>gem install thin</tt>, que Sinatra
|
22
|
+
utilisera si disponible.
|
23
|
+
|
20
24
|
== Routes
|
21
25
|
|
22
|
-
Dans Sinatra, une route est une méthode HTTP couplée à un masque (pattern)
|
26
|
+
Dans Sinatra, une route est une méthode HTTP couplée à un masque (pattern)
|
27
|
+
URL.
|
23
28
|
Chaque route est associée à un bloc:
|
24
29
|
|
25
30
|
get '/' do
|
@@ -38,11 +43,15 @@ Chaque route est associée à un bloc:
|
|
38
43
|
.. effacer quelque chose ..
|
39
44
|
end
|
40
45
|
|
41
|
-
|
42
|
-
|
46
|
+
options '/' do
|
47
|
+
.. apaiser quelquechose ..
|
48
|
+
end
|
49
|
+
|
50
|
+
Les routes sont comparées dans l'ordre où elles ont été définies. La première
|
51
|
+
route qui correspond à la requête est invoquée.
|
43
52
|
|
44
|
-
Les masques peuvent inclure des paramètres, accessibles par
|
45
|
-
hash <tt>params</tt>:
|
53
|
+
Les masques peuvent inclure des paramètres nommés, accessibles par
|
54
|
+
l'intermédiaire du hash <tt>params</tt>:
|
46
55
|
|
47
56
|
get '/bonjour/:nom' do
|
48
57
|
# répond aux requêtes "GET /bonjour/foo" et "GET /bonjour/bar"
|
@@ -50,14 +59,15 @@ hash <tt>params</tt>:
|
|
50
59
|
"Bonjour #{params[:nom]}!"
|
51
60
|
end
|
52
61
|
|
53
|
-
Vous pouvez aussi les nommer directement dans les paramètres du bloc comme
|
62
|
+
Vous pouvez aussi les nommer directement dans les paramètres du bloc comme
|
63
|
+
ceci:
|
54
64
|
|
55
65
|
get '/bonjour/:nom' do |n|
|
56
66
|
"Bonjour #{n}!"
|
57
67
|
end
|
58
68
|
|
59
|
-
Une route peut contenir un splat (caractère joker), accessible par
|
60
|
-
la liste <tt>params[:splat]</tt
|
69
|
+
Une route peut contenir un splat (caractère joker), accessible par
|
70
|
+
l'intermédiaire de la liste <tt>params[:splat]</tt>:
|
61
71
|
|
62
72
|
get '/dire/*/a/*' do
|
63
73
|
# répondrait à /dire/bonjour/a/monde
|
@@ -83,7 +93,8 @@ Là aussi on peut utiliser les paramètres de bloc:
|
|
83
93
|
|
84
94
|
=== Conditions
|
85
95
|
|
86
|
-
Les routes peuvent définir toutes sortes de conditions, comme par exemple le
|
96
|
+
Les routes peuvent définir toutes sortes de conditions, comme par exemple le
|
97
|
+
"user agent":
|
87
98
|
|
88
99
|
get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
|
89
100
|
"Vous utilisez Songbird version #{params[:agent][0]}"
|
@@ -121,20 +132,24 @@ Vous pouvez facilement définir vos propres conditions:
|
|
121
132
|
|
122
133
|
=== Valeurs de retour
|
123
134
|
|
124
|
-
La valeur de retour d'un bloc définissant une route détermine le corps de la
|
125
|
-
qui sera transmise au client HTTP ou du moins au prochain middleware
|
126
|
-
Le plus généralement, il s'agit d'une chaîne de caractères,
|
127
|
-
précédents. Cependant, d'autres valeurs sont
|
128
|
-
|
129
|
-
|
130
|
-
réponse Rack
|
131
|
-
|
132
|
-
|
133
|
-
* Un tableau de
|
134
|
-
|
135
|
+
La valeur de retour d'un bloc définissant une route détermine le corps de la
|
136
|
+
réponse qui sera transmise au client HTTP ou du moins au prochain middleware
|
137
|
+
dans la pile Rack. Le plus généralement, il s'agit d'une chaîne de caractères,
|
138
|
+
comme dans les exemples précédents. Cependant, d'autres valeurs sont
|
139
|
+
acceptées.
|
140
|
+
|
141
|
+
Vous pouvez renvoyer n'importe quel objet qui soit une réponse Rack valide, un
|
142
|
+
corps de réponse Rack ou un code retour HTTP:
|
143
|
+
|
144
|
+
* Un tableau de 3 éléments: <tt>[code retour (Fixnum), entêtes (Hash), corps
|
145
|
+
de réponse (répondant à #each)]</tt>
|
146
|
+
* Un tableau de 2 élements: <tt>[code retour (Fixnum), corps de réponse
|
147
|
+
(répondant à #each)]</tt>
|
148
|
+
* Un objet qui répond à <tt>#each</tt> et qui ne transmet que des chaînes de
|
149
|
+
caractères au bloc fourni
|
135
150
|
* Un Fixnum représentant le code retour
|
136
151
|
|
137
|
-
Ainsi, on peut facilement implémenter un streaming par exemple:
|
152
|
+
Ainsi, on peut facilement implémenter un streaming par exemple :
|
138
153
|
|
139
154
|
class Stream
|
140
155
|
def each
|
@@ -144,15 +159,59 @@ Ainsi, on peut facilement implémenter un streaming par exemple:
|
|
144
159
|
|
145
160
|
get('/') { Stream.new }
|
146
161
|
|
162
|
+
=== Masques de route spécifiques
|
163
|
+
|
164
|
+
Comme montré plus haut, Sinatra embarque le support pour l'utilisation de
|
165
|
+
masques utilisant des chaînes de caractères ou des expressions régulières
|
166
|
+
pour définir les routes. Toutefois, cela ne s'arrête pas là. Vous pouvez
|
167
|
+
facilement définir vos propres masques :
|
168
|
+
|
169
|
+
class MasqueToutSauf
|
170
|
+
Masque = Struct.new(:captures)
|
171
|
+
|
172
|
+
def initialize(except)
|
173
|
+
@except = except
|
174
|
+
@captures = Masque.new([])
|
175
|
+
end
|
176
|
+
|
177
|
+
def match(str)
|
178
|
+
@caputres unless @except === str
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def tout_sauf(masque)
|
183
|
+
MasqueToutSauf.new(masque)
|
184
|
+
end
|
185
|
+
|
186
|
+
get tout_sauf("/index") do
|
187
|
+
# ...
|
188
|
+
end
|
189
|
+
|
190
|
+
Notez que l'exemple ci-dessus est bien trop compliqué et le même résultat
|
191
|
+
peut être obtenu avec :
|
192
|
+
|
193
|
+
get // do
|
194
|
+
pass if request.path_info == "/index"
|
195
|
+
# ...
|
196
|
+
end
|
197
|
+
|
198
|
+
Ou bien en utilisant la forme négative :
|
199
|
+
|
200
|
+
get %r{^(?!/index$)} do
|
201
|
+
# ...
|
202
|
+
end
|
203
|
+
|
147
204
|
== Fichiers statiques
|
148
205
|
|
149
|
-
Par défaut, le dossier <tt>./public</tt> est utilisé pour servir les fichiers
|
150
|
-
Vous pouvez changer ce dossier pour un autre nom grâce
|
206
|
+
Par défaut, le dossier <tt>./public</tt> est utilisé pour servir les fichiers
|
207
|
+
statiques. Vous pouvez changer ce dossier pour un autre nom grâce au paramètre
|
208
|
+
<tt>:public</tt>:
|
151
209
|
|
152
210
|
set :public, File.dirname(__FILE__) + '/statique'
|
153
211
|
|
154
|
-
Notez que le nom du dossier public n'est pas inclus dans l'URL. Un fichier
|
155
|
-
<tt>./public/css/style.css</tt> est appelé avec l'URL:
|
212
|
+
Notez que le nom du dossier public n'est pas inclus dans l'URL. Un fichier
|
213
|
+
sous <tt>./public/css/style.css</tt> est appelé avec l'URL :
|
214
|
+
<tt>http://exemple.com/css/style.css</tt>.
|
156
215
|
|
157
216
|
== Vues / Templates
|
158
217
|
|
@@ -163,13 +222,13 @@ Pour utiliser un autre dossier, il faut le déclarer:
|
|
163
222
|
|
164
223
|
Il est important de noter que les templates sont toujours référencés
|
165
224
|
sous forme de symboles, même s'il s'agit d'un sous-répertoire (dans ce
|
166
|
-
cas, utilisez <tt>:'sous_repertoire/template'</tt>). Vous devez utiliser un
|
167
|
-
car les méthodes de rendu évalueront le contenu des chaînes de
|
168
|
-
au lieu de les considérer comme un chemin vers un fichier.
|
225
|
+
cas, utilisez <tt>:'sous_repertoire/template'</tt>). Vous devez utiliser un
|
226
|
+
symbole car les méthodes de rendu évalueront le contenu des chaînes de
|
227
|
+
caractères au lieu de les considérer comme un chemin vers un fichier.
|
169
228
|
|
170
229
|
=== Templates Haml
|
171
230
|
|
172
|
-
Le gem haml est nécessaire pour utiliser la fonction de rendu Haml:
|
231
|
+
Le gem <tt>haml</tt> est nécessaire pour utiliser la fonction de rendu Haml:
|
173
232
|
|
174
233
|
# Chargez la bibliothèque haml dans votre application
|
175
234
|
require 'haml'
|
@@ -201,11 +260,12 @@ et supportent aussi la réécriture (surcharge) comme dans cet exemple.
|
|
201
260
|
erb :index
|
202
261
|
end
|
203
262
|
|
204
|
-
Utilisera le template: <tt>./views/index.erb</tt
|
263
|
+
Utilisera le template: <tt>./views/index.erb</tt>.
|
205
264
|
|
206
|
-
=== Erubis
|
265
|
+
=== Templates Erubis
|
207
266
|
|
208
|
-
Le gem erubis est nécessaire pour utiliser la fonction de rendu
|
267
|
+
Le gem <tt>erubis</tt> est nécessaire pour utiliser la fonction de rendu
|
268
|
+
erubis:
|
209
269
|
|
210
270
|
# Chargez la bibliothèque erubis dans votre application
|
211
271
|
require 'erubis'
|
@@ -216,9 +276,21 @@ Le gem erubis est nécessaire pour utiliser la fonction de rendu erubis:
|
|
216
276
|
|
217
277
|
Utilisera le template: <tt>./views/index.erubis</tt>
|
218
278
|
|
279
|
+
Il est également possible de remplacer Erb par Erubis:
|
280
|
+
|
281
|
+
require 'erubis'
|
282
|
+
Tilt.register :erb, Tilt[:erubis]
|
283
|
+
|
284
|
+
get '/' do
|
285
|
+
erb :index
|
286
|
+
end
|
287
|
+
|
288
|
+
Utilisera le template <tt>./views/index.erb</tt> avec Erubis.
|
289
|
+
|
219
290
|
=== Templates Builder
|
220
291
|
|
221
|
-
Le gem builder est nécessaire pour utiliser la fonction de rendu
|
292
|
+
Le gem <tt>builder</tt> est nécessaire pour utiliser la fonction de rendu
|
293
|
+
builder:
|
222
294
|
|
223
295
|
# Chargez la bibliothèque builder dans votre application
|
224
296
|
require 'builder'
|
@@ -231,7 +303,8 @@ Utilisera le template: <tt>./views/index.builder</tt>.
|
|
231
303
|
|
232
304
|
=== Templates Nokogiri
|
233
305
|
|
234
|
-
Le gem nokogiri est nécessaire pour utiliser la fonction de rendu
|
306
|
+
Le gem <tt>nokogiri</tt> est nécessaire pour utiliser la fonction de rendu
|
307
|
+
nokogiri:
|
235
308
|
|
236
309
|
# Chargez la bibliothèque nokogiri dans votre application
|
237
310
|
require 'nokogiri'
|
@@ -244,7 +317,8 @@ Utilisera le template: <tt>./views/index.nokogiri</tt>.
|
|
244
317
|
|
245
318
|
=== Templates Sass
|
246
319
|
|
247
|
-
Le gem haml est nécessaire pour utiliser la fonction
|
320
|
+
Le gem <tt>haml</tt> ou <tt>sass</tt> est nécessaire pour utiliser la fonction
|
321
|
+
de rendu Sass:
|
248
322
|
|
249
323
|
# Chargez la bibliothèque haml ou sass dans votre application
|
250
324
|
require 'sass'
|
@@ -268,7 +342,8 @@ et supportent aussi la réécriture (surcharge) comme dans cet exemple.
|
|
268
342
|
|
269
343
|
=== Scss Templates
|
270
344
|
|
271
|
-
Le gem haml est nécessaire pour utiliser la fonction
|
345
|
+
Le gem <tt>haml</tt> ou <tt>sass</tt> est nécessaire pour utiliser la fonction
|
346
|
+
de rendu Scss:
|
272
347
|
|
273
348
|
# Chargez la bibliothèque haml ou sass dans votre application
|
274
349
|
require 'sass'
|
@@ -292,7 +367,7 @@ et supportent aussi la réécriture (surcharge) comme dans cet exemple.
|
|
292
367
|
|
293
368
|
=== Templates Less
|
294
369
|
|
295
|
-
Le gem less est nécessaire pour utiliser la fonction de rendu Less:
|
370
|
+
Le gem <tt>less</tt> est nécessaire pour utiliser la fonction de rendu Less:
|
296
371
|
|
297
372
|
# Chargez la bibliothèque less dans votre application
|
298
373
|
require 'less'
|
@@ -305,7 +380,8 @@ Utilisera le template: <tt>./views/stylesheet.less</tt>.
|
|
305
380
|
|
306
381
|
=== Templates Liquid
|
307
382
|
|
308
|
-
Le gem liquid est nécessaire pour utiliser la fonction de rendu
|
383
|
+
Le gem <tt>liquid</tt> est nécessaire pour utiliser la fonction de rendu
|
384
|
+
Liquid:
|
309
385
|
|
310
386
|
# Chargez la bibliothèque liquid dans votre application
|
311
387
|
require 'liquid'
|
@@ -317,13 +393,15 @@ Le gem liquid est nécessaire pour utiliser la fonction de rendu Liquid:
|
|
317
393
|
Utilisera <tt>./views/index.liquid</tt>.
|
318
394
|
|
319
395
|
Comme vous ne pouvez pas appeler des méthodes Ruby (excepté +yield+) dans un
|
320
|
-
template Liquid, il sera toujours nécessaire de lui passer des variables
|
396
|
+
template Liquid, il sera toujours nécessaire de lui passer des variables
|
397
|
+
locales:
|
321
398
|
|
322
399
|
liquid :index, :locals => { :key => 'value' }
|
323
400
|
|
324
401
|
=== Templates Markdown
|
325
402
|
|
326
|
-
Le gem rdiscount est nécessaire pour utiliser la fonction de rendu
|
403
|
+
Le gem <tt>rdiscount</tt> est nécessaire pour utiliser la fonction de rendu
|
404
|
+
Markdown:
|
327
405
|
|
328
406
|
# Chargez la bibliothèque rdiscount dans votre application
|
329
407
|
require "rdiscount"
|
@@ -332,23 +410,64 @@ Le gem rdiscount est nécessaire pour utiliser la fonction de rendu Markdown:
|
|
332
410
|
markdown :index
|
333
411
|
end
|
334
412
|
|
335
|
-
Utilisera <tt>./views/index.markdown</tt> (les extensions de fichier +md+ et
|
336
|
-
sont également acceptées).
|
413
|
+
Utilisera <tt>./views/index.markdown</tt> (les extensions de fichier +md+ et
|
414
|
+
+mkd+ sont également acceptées).
|
337
415
|
|
338
|
-
Il n'est pas possible d'appeler des méthodes depuis markdown, ni même de lui
|
339
|
-
locales. Par conséquent, il sera le plus souvent utilisé
|
340
|
-
de rendu:
|
416
|
+
Il n'est pas possible d'appeler des méthodes depuis markdown, ni même de lui
|
417
|
+
passer des variables locales. Par conséquent, il sera le plus souvent utilisé
|
418
|
+
en combinaison avec un autre moteur de rendu:
|
341
419
|
|
342
420
|
erb :vuedensemble, :locals => { :texte => markdown(:introduction) }
|
343
421
|
|
344
|
-
Notez que vous pouvez également appeler la méthode markdown au sein d'autres
|
422
|
+
Notez que vous pouvez également appeler la méthode +markdown+ au sein d'autres
|
423
|
+
templates:
|
345
424
|
|
346
425
|
%h1 Bonjour Depuis Haml!
|
347
426
|
%p= markdown(:salutations)
|
348
427
|
|
428
|
+
Comme vous ne pouvez pas faire d'appels Ruby au sein de Markdown, vous ne
|
429
|
+
pouvez pas utiliser des layouts écrits en Markdown. Il est toutefois possible
|
430
|
+
d'utiliser un autre moteur de rendu pour le layout en passant l'option
|
431
|
+
<tt>:layout_engine</tt> :
|
432
|
+
|
433
|
+
get '/' do
|
434
|
+
markdown :index, :layout_engine => :erb
|
435
|
+
end
|
436
|
+
|
437
|
+
Ceci utilisera <tt>./views/index.md</tt> avec <tt>./views/layout.erb</tt> pour
|
438
|
+
layout.
|
439
|
+
|
440
|
+
Souvenez vous que vous pouvez spécifier de telles options de rendu
|
441
|
+
globalement :
|
442
|
+
|
443
|
+
set :markdown, :layout_engine => :haml, :layout => :post
|
444
|
+
|
445
|
+
get '/' do
|
446
|
+
markdown :index
|
447
|
+
end
|
448
|
+
|
449
|
+
Ceci utilisera <tt>./views/index.md</tt> (et tout autre template Markdown)
|
450
|
+
avec <tt>./views/post.haml</tt> pour layout.
|
451
|
+
|
452
|
+
Il est également possible de traduire le Markdown avec BlueCloth plutôt que
|
453
|
+
RDiscount :
|
454
|
+
|
455
|
+
require 'bluecloth'
|
456
|
+
|
457
|
+
Tilt.register 'markdown', BlueClothTemplate
|
458
|
+
Tilt.register 'mkd', BlueClothTemplate
|
459
|
+
Tilt.register 'md', BlueClothTemplate
|
460
|
+
|
461
|
+
get '/' do
|
462
|
+
markdown :index
|
463
|
+
end
|
464
|
+
|
465
|
+
Utilisera <tt>./views/index.md</tt> avec BlueCloth.
|
466
|
+
|
349
467
|
=== Templates Textile
|
350
468
|
|
351
|
-
Le gem RedCloth est nécessaire pour utiliser la fonction de rendu
|
469
|
+
Le gem <tt>RedCloth</tt> est nécessaire pour utiliser la fonction de rendu
|
470
|
+
Textile:
|
352
471
|
|
353
472
|
# Chargez la bibliothèqye redcloth dans votre application
|
354
473
|
require "redcloth"
|
@@ -359,20 +478,45 @@ Le gem RedCloth est nécessaire pour utiliser la fonction de rendu Textile:
|
|
359
478
|
|
360
479
|
Utilisera <tt>./views/index.textile</tt>.
|
361
480
|
|
362
|
-
Il n'est pas possible d'appeler des méthodes depuis textile, ni même de lui
|
363
|
-
locales. Par conséquent, il sera le plus souvent utilisé
|
364
|
-
de rendu:
|
481
|
+
Il n'est pas possible d'appeler des méthodes depuis textile, ni même de lui
|
482
|
+
passer des variables locales. Par conséquent, il sera le plus souvent utilisé
|
483
|
+
en combinaison avec un autre moteur de rendu:
|
365
484
|
|
366
485
|
erb :vuedensemble, :locals => { :texte => textile(:introduction) }
|
367
486
|
|
368
|
-
Notez que vous pouvez également appeler la méthode textile au sein d'autres
|
487
|
+
Notez que vous pouvez également appeler la méthode +textile+ au sein d'autres
|
488
|
+
templates:
|
369
489
|
|
370
490
|
%h1 Bonjour Depuis Haml!
|
371
491
|
%p= textile(:salutations)
|
372
492
|
|
493
|
+
Comme vous ne pouvez pas faire d'appels Ruby au sein de Textile, vous ne
|
494
|
+
pouvez pas utiliser des layouts écrits en Textile. Il est toutefois possible
|
495
|
+
d'utiliser un autre moteur de rendu pour le layout en passant l'option
|
496
|
+
<tt>:layout_engine</tt> :
|
497
|
+
|
498
|
+
get '/' do
|
499
|
+
textile :index, :layout_engine => :erb
|
500
|
+
end
|
501
|
+
|
502
|
+
Ceci utilisera <tt>./views/index.textile</tt> avec <tt>./views/layout.erb</tt>
|
503
|
+
pour layout.
|
504
|
+
|
505
|
+
Souvenez vous que vous pouvez spécifier de telles options de rendu
|
506
|
+
globalement :
|
507
|
+
|
508
|
+
set :textile, :layout_engine => :haml, :layout => :post
|
509
|
+
|
510
|
+
get '/' do
|
511
|
+
textile :index
|
512
|
+
end
|
513
|
+
|
514
|
+
Ceci utilisera <tt>./views/index.textile</tt> (et tout autre template Textile)
|
515
|
+
avec <tt>./views/post.haml</tt> pour layout.
|
516
|
+
|
373
517
|
=== Templates RDoc
|
374
518
|
|
375
|
-
Le gem
|
519
|
+
Le gem <tt>rdoc</tt> est nécessaire pour utiliser la fonction de rendu RDoc:
|
376
520
|
|
377
521
|
# Chargez la bibliothèque rdoc/markup/to_html dans votre application
|
378
522
|
require "rdoc/markup/to_html"
|
@@ -383,22 +527,47 @@ Le gem RDoc est nécessaire pour utiliser la fonction de rendu RDoc:
|
|
383
527
|
|
384
528
|
Utilisera <tt>./views/index.rdoc</tt>.
|
385
529
|
|
386
|
-
Il n'est pas possible d'appeler des méthodes depuis rdoc, ni même de lui
|
387
|
-
locales. Par conséquent, il sera le plus souvent utilisé
|
388
|
-
de rendu:
|
530
|
+
Il n'est pas possible d'appeler des méthodes depuis rdoc, ni même de lui
|
531
|
+
passer des variables locales. Par conséquent, il sera le plus souvent utilisé
|
532
|
+
en combinaison avec un autre moteur de rendu:
|
389
533
|
|
390
534
|
erb :vuedensemble, :locals => { :texte => rdoc(:introduction) }
|
391
535
|
|
392
|
-
Notez que vous pouvez également appeler la méthode rdoc au sein d'autres
|
536
|
+
Notez que vous pouvez également appeler la méthode +rdoc+ au sein d'autres
|
537
|
+
templates:
|
393
538
|
|
394
539
|
%h1 Bonjour Depuis Haml!
|
395
540
|
%p= rdoc(:salutations)
|
396
541
|
|
542
|
+
Comme vous ne pouvez pas faire d'appels Ruby au sein de RDoc, vous ne
|
543
|
+
pouvez pas utiliser des layouts écrits en RDoc. Il est toutefois possible
|
544
|
+
d'utiliser un autre moteur de rendu pour le layout en passant l'option
|
545
|
+
<tt>:layout_engine</tt> :
|
546
|
+
|
547
|
+
get '/' do
|
548
|
+
rdoc :index, :layout_engine => :erb
|
549
|
+
end
|
550
|
+
|
551
|
+
Ceci utilisera <tt>./views/index.rdoc</tt> avec <tt>./views/layout.erb</tt>
|
552
|
+
pour layout.
|
553
|
+
|
554
|
+
Souvenez vous que vous pouvez spécifier de telles options de rendu
|
555
|
+
globalement :
|
556
|
+
|
557
|
+
set :rdoc, :layout_engine => :haml, :layout => :post
|
558
|
+
|
559
|
+
get '/' do
|
560
|
+
rdoc :index
|
561
|
+
end
|
562
|
+
|
563
|
+
Ceci utilisera <tt>./views/index.rdoc</tt> (et tout autre template RDoc)
|
564
|
+
avec <tt>./views/post.haml</tt> pour layout.
|
565
|
+
|
397
566
|
=== Templates Radius
|
398
567
|
|
399
568
|
Le gem radius est nécessaire pour utiliser la fonction de rendu Radius:
|
400
569
|
|
401
|
-
# Chargez la
|
570
|
+
# Chargez la bibliothèque radius dans votre application
|
402
571
|
require 'radius'
|
403
572
|
|
404
573
|
get '/' do
|
@@ -408,7 +577,8 @@ Le gem radius est nécessaire pour utiliser la fonction de rendu Radius:
|
|
408
577
|
Utilisera <tt>./views/index.radius</tt>.
|
409
578
|
|
410
579
|
Comme vous ne pouvez pas appeler des méthodes Ruby (excepté +yield+) dans un
|
411
|
-
template Radius, il sera toujours nécessaire de lui passer des variables
|
580
|
+
template Radius, il sera toujours nécessaire de lui passer des variables
|
581
|
+
locales:
|
412
582
|
|
413
583
|
radius :index, :locals => { :key => 'value' }
|
414
584
|
|
@@ -425,6 +595,12 @@ Le gem markaby est nécessaire pour utiliser la fonction de rendu Markaby:
|
|
425
595
|
|
426
596
|
Utilisera <tt>./views/index.mab</tt>.
|
427
597
|
|
598
|
+
Vous pouvez également utiliser Markaby en ligne :
|
599
|
+
|
600
|
+
get '/' do
|
601
|
+
markaby { h1 "Salut !" }
|
602
|
+
end
|
603
|
+
|
428
604
|
=== Templates Slim
|
429
605
|
|
430
606
|
Le gem slim est nécessaire pour utiliser la fonction de rendu Slim:
|
@@ -440,8 +616,17 @@ Utilisera <tt>./views/index.slim</tt>.
|
|
440
616
|
|
441
617
|
=== Templates CoffeeScript
|
442
618
|
|
443
|
-
Le gem coffee-script
|
444
|
-
|
619
|
+
Le gem <tt>coffee-script</tt> est nécessaire ainsi que l'<b>une</b> des
|
620
|
+
options suivantes permettant l'exécution de Java script :
|
621
|
+
|
622
|
+
* +node+ (de Node.js) dans votre path
|
623
|
+
* vous êtes sous OSX
|
624
|
+
* le gem +therubyracer+
|
625
|
+
|
626
|
+
Voir http://github.com/josh/ruby-coffee-script pour une liste à jour d'options
|
627
|
+
possibles.
|
628
|
+
|
629
|
+
Maintenant vous pouvez générer des templates CoffeeScript :
|
445
630
|
|
446
631
|
# Chargez la bibliothèque coffee-script dans votre application
|
447
632
|
require 'coffee-script'
|
@@ -452,14 +637,13 @@ fonction de rendu CoffeeScript:
|
|
452
637
|
|
453
638
|
Utilisera <tt>./views/application.coffee</tt>.
|
454
639
|
|
455
|
-
=== Templates
|
640
|
+
=== Templates embarqués
|
456
641
|
|
457
642
|
get '/' do
|
458
643
|
haml '%div.title Bonjour Monde'
|
459
644
|
end
|
460
645
|
|
461
|
-
|
462
|
-
chercher le texte dans un fichier.
|
646
|
+
Générera le template embarqué spécifié dans la chaîne de caractères.
|
463
647
|
|
464
648
|
=== Accéder aux variables dans un Template
|
465
649
|
|
@@ -479,14 +663,14 @@ Alternativement, on peut passer un hash contenant des variables locales:
|
|
479
663
|
haml '%h1= foo.nom', :locals => { :foo => foo }
|
480
664
|
end
|
481
665
|
|
482
|
-
Ceci est généralement utilisé lorsque l'on veut utiliser un template comme
|
483
|
-
(depuis un autre template) et qu'il est donc nécessaire d'adapter les
|
666
|
+
Ceci est généralement utilisé lorsque l'on veut utiliser un template comme
|
667
|
+
partiel (depuis un autre template) et qu'il est donc nécessaire d'adapter les
|
668
|
+
noms de variables.
|
484
669
|
|
485
670
|
=== Templates dans le fichier source
|
486
671
|
|
487
672
|
Des templates peuvent être définis dans le fichier source comme ceci:
|
488
673
|
|
489
|
-
require 'rubygems'
|
490
674
|
require 'sinatra'
|
491
675
|
|
492
676
|
get '/' do
|
@@ -503,12 +687,14 @@ Des templates peuvent être définis dans le fichier source comme ceci:
|
|
503
687
|
%div.title Bonjour Monde!!!!!
|
504
688
|
|
505
689
|
NOTE: Les templates du fichier source qui contient <tt>require 'sinatra'</tt>
|
506
|
-
sont automatiquement chargés. Si vous avez des templates dans d'autres
|
507
|
-
il faut explicitement les déclarer via:
|
690
|
+
sont automatiquement chargés. Si vous avez des templates dans d'autres
|
691
|
+
fichiers source, il faut explicitement les déclarer via:
|
692
|
+
<tt>enable :inline_templates</tt>.
|
508
693
|
|
509
694
|
=== Templates nommés
|
510
695
|
|
511
|
-
Les templates peuvent aussi être définis grâce à la méthode de haut niveau
|
696
|
+
Les templates peuvent aussi être définis grâce à la méthode de haut niveau
|
697
|
+
<tt>template</tt>:
|
512
698
|
|
513
699
|
template :layout do
|
514
700
|
"%html\n =yield\n"
|
@@ -522,29 +708,41 @@ Les templates peuvent aussi être définis grâce à la méthode de haut niveau
|
|
522
708
|
haml :index
|
523
709
|
end
|
524
710
|
|
525
|
-
Si un template nommé "layout" existe, il sera utilisé à chaque fois qu'un
|
526
|
-
sera affiché. Vous pouvez désactivez
|
527
|
-
<tt>:layout => false</tt
|
711
|
+
Si un template nommé "layout" existe, il sera utilisé à chaque fois qu'un
|
712
|
+
template sera affiché. Vous pouvez désactivez les layouts au cas par cas en
|
713
|
+
passant <tt>:layout => false</tt> ou bien les désactiver par défaut au moyen
|
714
|
+
de <tt>set :haml, :layout => false</tt>:
|
528
715
|
|
529
716
|
get '/' do
|
530
717
|
haml :index, :layout => !request.xhr?
|
531
718
|
end
|
532
719
|
|
533
|
-
|
720
|
+
=== Associer des extensions de fichier
|
721
|
+
|
722
|
+
Pour associer une extension de fichier avec un moteur de rendu, utilisez
|
723
|
+
<tt>Tilt.register</tt>. Par exemple, si vous désirez utiliser l'extension
|
724
|
+
de fichier +tt+ pour les templates Textile, vous pouvez faire comme suit :
|
534
725
|
|
535
|
-
|
536
|
-
|
726
|
+
Tilt.register :tt, Tilt[:textile]
|
727
|
+
|
728
|
+
=== Ajouter son propre moteur de rendu
|
729
|
+
|
730
|
+
En premier lieu, déclarez votre moteur de rendu avec Tilt, ensuite créez
|
731
|
+
votre méthode de rendu :
|
732
|
+
|
733
|
+
Tilt.register :monmoteur, MonMerveilleurMoteurDeRendu
|
537
734
|
|
538
735
|
helpers do
|
539
|
-
def
|
540
|
-
"#{nom}bar"
|
541
|
-
end
|
736
|
+
def monmoteur(*args) render(:monmoteur, *args) end
|
542
737
|
end
|
543
738
|
|
544
|
-
get '
|
545
|
-
|
739
|
+
get '/' do
|
740
|
+
monmoteur :index
|
546
741
|
end
|
547
742
|
|
743
|
+
Utilisera <tt>./views/index.monmoteur</tt>. Voir
|
744
|
+
https://github.com/rtomayko/tilt pour en savoir plus sur Tilt.
|
745
|
+
|
548
746
|
== Filtres
|
549
747
|
|
550
748
|
Un filtre <tt>before</tt> est évalué avant n'importe quelle requête, dans le
|
@@ -564,13 +762,18 @@ et au template:
|
|
564
762
|
|
565
763
|
Un filtre <tt>after</tt> est évalué après chaque requête, dans le contexte
|
566
764
|
de celle-ci et peut également modifier la requête et/ou la réponse. Toutes les
|
567
|
-
variables d'instance déclarées dans un filtre <tt>before</tt> et dans le
|
568
|
-
de route sont accessibles dans le filtre <tt>after</tt>:
|
765
|
+
variables d'instance déclarées dans un filtre <tt>before</tt> et dans le
|
766
|
+
gestionnaire de route sont accessibles dans le filtre <tt>after</tt>:
|
569
767
|
|
570
768
|
after do
|
571
769
|
puts response.status
|
572
770
|
end
|
573
771
|
|
772
|
+
Note : Sauf si vous utilisez la méthode +body+ au lieu de renvoyer une chaîne
|
773
|
+
de caractères dans vos gestionnaires de routes, le corps de la réponse ne sera
|
774
|
+
pas disponible dans le filtre <tt>after</tt>, étant donné qu'il est généré
|
775
|
+
plus tard.
|
776
|
+
|
574
777
|
En option, on peut passer un masque au filtre, ce qui le rend actif uniquement
|
575
778
|
si la requête correspond au masque en question:
|
576
779
|
|
@@ -582,9 +785,67 @@ si la requête correspond au masque en question:
|
|
582
785
|
session[:dernier_travail] = travail
|
583
786
|
end
|
584
787
|
|
788
|
+
Tout comme les routes, les filtres acceptent également les conditions :
|
789
|
+
|
790
|
+
before :agent => /Songbird/ do
|
791
|
+
# ...
|
792
|
+
end
|
793
|
+
|
794
|
+
after '/blog/*', :host_name => 'example.com' do
|
795
|
+
# ...
|
796
|
+
end
|
797
|
+
|
798
|
+
== Helpers
|
799
|
+
|
800
|
+
Utilisez la méthode de haut niveau <tt>helpers</tt> pour définir des routines
|
801
|
+
qui seront accessibles dans vos gestionnaires de route et dans vos templates :
|
802
|
+
|
803
|
+
helpers do
|
804
|
+
def bar(nom)
|
805
|
+
"#{nom}bar"
|
806
|
+
end
|
807
|
+
end
|
808
|
+
|
809
|
+
get '/:nom' do
|
810
|
+
bar(params[:nom])
|
811
|
+
end
|
812
|
+
|
813
|
+
=== Utiliser les sessions
|
814
|
+
|
815
|
+
Une session est utilisé pour conserver un état entre les requêtes. Une fois
|
816
|
+
activées, vous avez un +hash+ de session par session utilisateur :
|
817
|
+
|
818
|
+
enable :sessions
|
819
|
+
|
820
|
+
get '/' do
|
821
|
+
"valeur = " << session[:valeur].inspect
|
822
|
+
end
|
823
|
+
|
824
|
+
get '/:value' do
|
825
|
+
session[:valeur] = params[:valeur]
|
826
|
+
end
|
827
|
+
|
828
|
+
Notez que <tt>enable :sessions</tt> enregistre en fait toutes les données dans
|
829
|
+
un +cookie+. Ce n'est pas toujours ce que vous voulez (enregistrer beaucoup de
|
830
|
+
données va augmenter le traffic par exemple). Vous pouvez utiliser n'importe
|
831
|
+
quel +middleware+ Rack de session afin d'éviter cela. N'utiliser *pas*
|
832
|
+
<tt>enable :sessions</tt> dans ce cas mais charger le +middleware+ de votre
|
833
|
+
choix comme vous le feriez pour n'importe quel autre +middleware+ :
|
834
|
+
|
835
|
+
use Rack::Session::Pool, :expire_after => 2592000
|
836
|
+
|
837
|
+
get '/' do
|
838
|
+
"valeur = " << session[:valeur].inspect
|
839
|
+
end
|
840
|
+
|
841
|
+
get '/:value' do
|
842
|
+
session[:valeur] = params[:valeur]
|
843
|
+
end
|
844
|
+
|
585
845
|
== Halt
|
586
846
|
|
587
|
-
Pour arrêter immédiatement la requête dans un filtre ou un gestionnaire de
|
847
|
+
Pour arrêter immédiatement la requête dans un filtre ou un gestionnaire de
|
848
|
+
route:
|
588
849
|
|
589
850
|
halt
|
590
851
|
|
@@ -604,6 +865,10 @@ Ainsi que les entêtes ...
|
|
604
865
|
|
605
866
|
halt 402, {'Content-Type' => 'text/plain'}, 'revanche'
|
606
867
|
|
868
|
+
Bien sûr il est possible de cominer un template avec +halt+:
|
869
|
+
|
870
|
+
halt erb(:erreur)
|
871
|
+
|
607
872
|
== Passer
|
608
873
|
|
609
874
|
Une route peut passer le relais aux autres routes qui correspondent également
|
@@ -622,13 +887,242 @@ On sort donc immédiatement de ce gestionnaire et on continue à chercher,
|
|
622
887
|
dans les masques suivants, le prochain qui correspond à la requête.
|
623
888
|
Si aucun des masques suivants ne correspond, un code 404 est retourné.
|
624
889
|
|
890
|
+
=== Déclencher une autre route
|
891
|
+
|
892
|
+
Parfois, +pass+ n'est pas ce que vous recherchez, au lieu de cela vous
|
893
|
+
souhaitez obtenir le résultat d'une autre route. Pour cela, utilisez
|
894
|
+
simplement +call+ :
|
895
|
+
|
896
|
+
get '/foo' do
|
897
|
+
status, headers, body = call request.env.merge("PATH_INFO" => '/bar')
|
898
|
+
[status, body.upcase]
|
899
|
+
end
|
900
|
+
|
901
|
+
get '/bar' do
|
902
|
+
"bar"
|
903
|
+
end
|
904
|
+
|
905
|
+
Notez que dans l'exemple ci-dessus, vous faciliterez les tests et améliorerez
|
906
|
+
la performance en déplaçant simplement <tt>"bar"</tt> dans un +helper+
|
907
|
+
utilisé à la fois par <tt>/foo</tt> et <tt>/bar</tt>.
|
908
|
+
|
909
|
+
Si vous souhiatez que la requête soit envoyée à la même instance de
|
910
|
+
l'application plutôt qu'à une copie, utilisez <tt>call!</tt> au lieu de
|
911
|
+
<tt>call</tt>.
|
912
|
+
|
913
|
+
Lisez la spécification Rack si vous souhaitez en savoir plus sur
|
914
|
+
<tt>call</tt>.
|
915
|
+
|
916
|
+
=== Définir le corps, le code retour et les entêtes
|
917
|
+
|
918
|
+
Il est possible et recommandé de définir le code retour et le corps de la
|
919
|
+
réponse au moyen de la valeur de retour d'un bloc définissant une route.
|
920
|
+
Quoiqu'il en soit, dans certains cas vous pourriez avoir besoin de définir
|
921
|
+
le coprs de la réponse à un moment arbitraire de l'exécution. Vous pouvez le
|
922
|
+
faire au moyen de la méthode +body+. Si vous faites ainsi, vous pouvez alors
|
923
|
+
utiliser cette même méthode pour accéder au corps de la réponse :
|
924
|
+
|
925
|
+
get '/foo' do
|
926
|
+
body "bar"
|
927
|
+
end
|
928
|
+
|
929
|
+
after do
|
930
|
+
puts body
|
931
|
+
end
|
932
|
+
|
933
|
+
Il est également possible de passer un bloc à +body+, qui sera exécuté par le
|
934
|
+
gestionnaire Rack (ceci peut être utilisé pour implémenter un +streaming+,
|
935
|
+
voir "Valeurs de retour").
|
936
|
+
|
937
|
+
Pareillement au corps de la réponse, vous pouvez également définir le code
|
938
|
+
retour et les entêtes :
|
939
|
+
|
940
|
+
get '/foo' do
|
941
|
+
status 418
|
942
|
+
headers \
|
943
|
+
"Allow" => "BREW, POST, GET, PROPFIND, WHEN"
|
944
|
+
"Refresh" => "Refresh: 20; http://www.ietf.org/rfc/rfc2324.txt"
|
945
|
+
body "I'm a tea pot!"
|
946
|
+
end
|
947
|
+
|
948
|
+
Comme +body+, +headers+ et +status+ peuvent être utilisés sans arguments
|
949
|
+
pour accéder à leurs valeurs.
|
950
|
+
|
951
|
+
=== Types Mime
|
952
|
+
|
953
|
+
Quand vous utilisez <tt>send_file</tt> ou des fichiers statiques, vous
|
954
|
+
pouvez rencontrer des types mime que Sinatra ne connaît pas. Utilisez
|
955
|
+
+mime_type+ pour les déclarer par extension de fichier :
|
956
|
+
|
957
|
+
mime_type :foo, 'text/foo'
|
958
|
+
|
959
|
+
Vous pouvez également les utiliser avec la méthode +content_type+ :
|
960
|
+
|
961
|
+
get '/' do
|
962
|
+
content_type :foo
|
963
|
+
"foo foo foo"
|
964
|
+
end
|
965
|
+
|
966
|
+
=== Former des URLs
|
967
|
+
|
968
|
+
Pour former des URLs, vous devriez utiliser la méthode +url+, par exemple en
|
969
|
+
Haml :
|
970
|
+
|
971
|
+
%a{:href => url('/foo')} foo
|
972
|
+
|
973
|
+
Cela prend en compte les proxy inverse et les routeurs Rack, s'ils existent.
|
974
|
+
|
975
|
+
Cette méthode est également disponible sous l'alias +to+ (voir ci-dessous
|
976
|
+
pour un exemple).
|
977
|
+
|
978
|
+
=== Redirection du navigateur
|
979
|
+
|
980
|
+
Vous pouvez déclencher une redirection du navigateur avec la méthode
|
981
|
+
+redirect+ :
|
982
|
+
|
983
|
+
get '/foo' do
|
984
|
+
redirect to('/bar')
|
985
|
+
end
|
986
|
+
|
987
|
+
Tout paramètre additionnel est géré comme des arguments pour la méthode
|
988
|
+
+halt+ :
|
989
|
+
|
990
|
+
redirect to('/bar'), 303
|
991
|
+
redirect 'http://google.com', 'mauvais endroit mon pote'
|
992
|
+
|
993
|
+
Vous pouvez aussi rediriger vers la page dont l'utilisateur venait au moyen de
|
994
|
+
<tt>redirect back</tt>:
|
995
|
+
|
996
|
+
get '/foo' do
|
997
|
+
"<a href='/bar'>faire quelque chose</a>"
|
998
|
+
end
|
999
|
+
|
1000
|
+
get '/bar' do
|
1001
|
+
faire_quelque_chose
|
1002
|
+
redirect back
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
Pour passer des arguments à une redirection, ajoutez-les soit à la requête :
|
1006
|
+
|
1007
|
+
redirect to('/bar?sum=42')
|
1008
|
+
|
1009
|
+
Ou bien utilisez une session :
|
1010
|
+
|
1011
|
+
enable :session
|
1012
|
+
|
1013
|
+
get '/foo' do
|
1014
|
+
session[:secret] = 'foo'
|
1015
|
+
redirect to('/bar')
|
1016
|
+
end
|
1017
|
+
|
1018
|
+
get '/bar' do
|
1019
|
+
session[:secret]
|
1020
|
+
end
|
1021
|
+
|
1022
|
+
=== Contrôle du cache
|
1023
|
+
|
1024
|
+
Définir correctement vos entêtes à la base pour un bon cahce HTTP.
|
1025
|
+
|
1026
|
+
Vous pouvez facilement définir l'entête Cache-Control de la manière suivante :
|
1027
|
+
|
1028
|
+
get '/' do
|
1029
|
+
cache_control :public
|
1030
|
+
"met le en cache !"
|
1031
|
+
end
|
1032
|
+
|
1033
|
+
Conseil de pro : définir le cache dans un filtre +before+:
|
1034
|
+
|
1035
|
+
before do
|
1036
|
+
cache_control :public, :must_revalidate, :max_age => 60
|
1037
|
+
end
|
1038
|
+
|
1039
|
+
Si vous utilisez la méthode +expires+ pour définir l'entête correspondant,
|
1040
|
+
<tt>Cache-Control</tt> sera alors défini automatiquement :
|
1041
|
+
|
1042
|
+
before do
|
1043
|
+
expires 500, :public, :must_revalidate
|
1044
|
+
end
|
1045
|
+
|
1046
|
+
Pour utiliser correctement les caches, vous devriez utiliser +etag+ et
|
1047
|
+
+last_modified+. Il est recommandé d'utiliser ces méthodes *avant* de faire
|
1048
|
+
d'important modifications, car elles vont immédiatement déclencher la réponse
|
1049
|
+
si le client a déjà la version courante dans son cache:
|
1050
|
+
|
1051
|
+
get '/article/:id' do
|
1052
|
+
@article = Article.find params[:id]
|
1053
|
+
last_modified @article.updated_at
|
1054
|
+
etag @article.sha1
|
1055
|
+
erb :article
|
1056
|
+
end
|
1057
|
+
|
1058
|
+
Il est également possible d'utiliser un
|
1059
|
+
{weak ETag}[http://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation]:
|
1060
|
+
|
1061
|
+
etag @article.sha1, :weak
|
1062
|
+
|
1063
|
+
Ces méthodes ne sont pas chargées de mettre des données en cache, mais elles
|
1064
|
+
fournissent les informations nécessaires pour votre cache. Si vous êtes à la
|
1065
|
+
recherche de solutions rapides de cache, essayez
|
1066
|
+
{rack-cache}[http://rtomayko.github.com/rack-cache/]:
|
1067
|
+
|
1068
|
+
require "rack/cache"
|
1069
|
+
require "sinatra"
|
1070
|
+
|
1071
|
+
use Rack::Cache
|
1072
|
+
|
1073
|
+
get '/' do
|
1074
|
+
cache_control :public, :max_age => 36000
|
1075
|
+
sleep 5
|
1076
|
+
"hello"
|
1077
|
+
end
|
1078
|
+
|
1079
|
+
=== Envoyer des fichiers
|
1080
|
+
|
1081
|
+
Pour envoyer des fichiers, vous pouvez utiliser la méthode
|
1082
|
+
<tt>send_file</tt> :
|
1083
|
+
|
1084
|
+
get '/' do
|
1085
|
+
send_file 'foo.png'
|
1086
|
+
end
|
1087
|
+
|
1088
|
+
Quelques options sont également acceptées :
|
1089
|
+
|
1090
|
+
send_file 'foo.png', :type => :jpg
|
1091
|
+
|
1092
|
+
Les options sont :
|
1093
|
+
|
1094
|
+
[filename]
|
1095
|
+
le nom du fichier dans la réponse, par défaut le nom du fichier envoyé.
|
1096
|
+
|
1097
|
+
[last_modified]
|
1098
|
+
valeur pour l'entête Last-Modified, par défaut la date de modification du
|
1099
|
+
fichier
|
1100
|
+
|
1101
|
+
[type]
|
1102
|
+
type de contenu à utiliser, deviné à partir de l'extension de fichier si
|
1103
|
+
absent
|
1104
|
+
|
1105
|
+
[disposition]
|
1106
|
+
utilisé pour Content-Disposition, les valuers possibles étant : +nil+ (par
|
1107
|
+
défaut), <tt>:attachment</tt> et <tt>:inline</tt>
|
1108
|
+
|
1109
|
+
[length]
|
1110
|
+
entête Content-Length, par défaut la taille du fichier
|
1111
|
+
|
1112
|
+
Si le gestionnaire Rack le supporte, d'autres moyens que le +streaming+ via le
|
1113
|
+
processus Ruby seront utilisés. Si vous utilisez cette méthode, Sinatra gérera
|
1114
|
+
automatiquement les requêtes de type +range+.
|
1115
|
+
|
625
1116
|
== Accéder à l'objet requête
|
626
1117
|
|
627
|
-
L'objet correspondant à la requête envoyée peut être récupéré dans le contexte
|
1118
|
+
L'objet correspondant à la requête envoyée peut être récupéré dans le contexte
|
1119
|
+
de la requête (filtres, routes, gestionnaires d'erreur) au moyen de la méthode
|
1120
|
+
`request`:
|
628
1121
|
|
629
1122
|
# application tournant à l'adresse http://exemple.com/exemple
|
630
1123
|
get '/foo' do
|
631
|
-
request.body # corps de la requête envoyée par le client
|
1124
|
+
request.body # corps de la requête envoyée par le client
|
1125
|
+
# (voir ci-dessous)
|
632
1126
|
request.scheme # "http"
|
633
1127
|
request.script_name # "/exemple"
|
634
1128
|
request.path_info # "/foo"
|
@@ -638,7 +1132,8 @@ L'objet correspondant à la requête envoyée peut être récupéré dans le con
|
|
638
1132
|
request.content_length # taille de request.body
|
639
1133
|
request.media_type # type de média pour request.body
|
640
1134
|
request.host # "exemple.com"
|
641
|
-
request.get? # true (méthodes similaires pour les autres
|
1135
|
+
request.get? # true (méthodes similaires pour les autres
|
1136
|
+
# verbes HTTP)
|
642
1137
|
request.form_data? # false
|
643
1138
|
request["UN_ENTETE"] # valeur de l'entête UN_ENTETE
|
644
1139
|
request.referer # référant du client ou '/'
|
@@ -649,11 +1144,13 @@ L'objet correspondant à la requête envoyée peut être récupéré dans le con
|
|
649
1144
|
request.path # "/exemple/foo"
|
650
1145
|
request.ip # adresse IP du client
|
651
1146
|
request.secure? # false
|
652
|
-
request.
|
1147
|
+
request.forwarded? # vrai (si on est derrière un proxy inverse)
|
1148
|
+
request.env # tableau brut de l'environnement fourni par
|
1149
|
+
# Rack
|
653
1150
|
end
|
654
1151
|
|
655
|
-
Certaines options, telles que <tt>script_name</tt> ou <tt>path_info</tt>
|
656
|
-
également être modifiées:
|
1152
|
+
Certaines options, telles que <tt>script_name</tt> ou <tt>path_info</tt>
|
1153
|
+
peuvent également être modifiées:
|
657
1154
|
|
658
1155
|
before { request.path_info = "/" }
|
659
1156
|
|
@@ -669,12 +1166,86 @@ Certaines options, telles que <tt>script_name</tt> ou <tt>path_info</tt> peuvent
|
|
669
1166
|
"Bonjour #{donnees['nom']}!"
|
670
1167
|
end
|
671
1168
|
|
1169
|
+
=== Fichiers joints
|
1170
|
+
|
1171
|
+
Vous pouvez utiliser la méthode +attachment+ pour indiquer au navigateur que
|
1172
|
+
la réponse devrait être stockée sur le disque plutôt qu'affichée:
|
1173
|
+
|
1174
|
+
get '/' do
|
1175
|
+
attachment
|
1176
|
+
"enregistre-le !"
|
1177
|
+
end
|
1178
|
+
|
1179
|
+
Vous pouvez également lui passer un nom de fichier :
|
1180
|
+
|
1181
|
+
get '/' do
|
1182
|
+
attachment "info.txt"
|
1183
|
+
"enregistre-le !"
|
1184
|
+
end
|
1185
|
+
|
1186
|
+
=== Chercher les fichiers de templates
|
1187
|
+
|
1188
|
+
La méthode <tt>find_template</tt> est utilisée pour trouver les fichiers de
|
1189
|
+
templates à générer :
|
1190
|
+
|
1191
|
+
find_template settings.views, 'foo', Tilt[:haml] do |file|
|
1192
|
+
puts "pourrait être #{file}"
|
1193
|
+
end
|
1194
|
+
|
1195
|
+
Ce n'est pas très utilise. En revanche, il est utile de pouvoir surcharger
|
1196
|
+
cette méthode afin de définir son propre mécanisme de recherche. Par exemple,
|
1197
|
+
vous pouvez utiliser plus d'un répertoire de vues :
|
1198
|
+
|
1199
|
+
set :views, ['views', 'templates']
|
1200
|
+
|
1201
|
+
helpers do
|
1202
|
+
def find_template(views, name, engine, &block)
|
1203
|
+
Array(views).each { |v| super(v, name, engine, &block) }
|
1204
|
+
end
|
1205
|
+
end
|
1206
|
+
|
1207
|
+
Un autre exemple est d'utiliser des répertoires différents pour des moteurs
|
1208
|
+
de rendu différents :
|
1209
|
+
|
1210
|
+
set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views'
|
1211
|
+
|
1212
|
+
helpers do
|
1213
|
+
def find_template(views, name, engine, &block)
|
1214
|
+
_, folder = views.detect { |k,v| engine == Tilt[k] }
|
1215
|
+
folder ||= views[:default]
|
1216
|
+
super(folder, name, engine, &block)
|
1217
|
+
end
|
1218
|
+
end
|
1219
|
+
|
1220
|
+
Vous pouvez également écrire cela dans une extension et la partager avec
|
1221
|
+
d'autres !
|
1222
|
+
|
1223
|
+
Notez que <tt>find_template</tt> ne vérifie pas que le fichier existe mais
|
1224
|
+
va plutôt exécuter le bloc pour tous les chemins possibles. Cela n'induit pas
|
1225
|
+
un problème de performance dans le sens où +render+ va utiliser +break+ dès
|
1226
|
+
qu'un fichier est trouvé. De plus, l'emplacement des templates (et leur
|
1227
|
+
contenu) est mis en cache si vous n'êtes pas en mode développement. Vous
|
1228
|
+
devriez garder cela en tête si vous écrivez une méthode vraiment dingue.
|
1229
|
+
|
672
1230
|
== Configuration
|
673
1231
|
|
674
1232
|
Lancé une seule fois au démarrage de tous les environnements:
|
675
1233
|
|
676
1234
|
configure do
|
677
|
-
|
1235
|
+
# définir un paramètre
|
1236
|
+
set :option, 'value'
|
1237
|
+
|
1238
|
+
# définir plusieurs paramètre
|
1239
|
+
set :a => 1, :b => 2
|
1240
|
+
|
1241
|
+
# identique à `set :option, true`
|
1242
|
+
enable :option
|
1243
|
+
|
1244
|
+
# identique à `set :option, false`
|
1245
|
+
disable :option
|
1246
|
+
|
1247
|
+
# vous pouvez également avoir des paramètres dynamiques avec des blocs
|
1248
|
+
set(:css_dir) { File.join(views, 'css') }
|
678
1249
|
end
|
679
1250
|
|
680
1251
|
Lancé si l'environnement (variable d'environnement RACK_ENV) est défini comme
|
@@ -691,16 +1262,125 @@ Lancé si l'environnement est <tt>:production</tt> ou
|
|
691
1262
|
...
|
692
1263
|
end
|
693
1264
|
|
1265
|
+
Vous pouvez accéder à ces paramètres via <tt>settings</tt> :
|
1266
|
+
|
1267
|
+
configure do
|
1268
|
+
set :foo, 'bar'
|
1269
|
+
end
|
1270
|
+
|
1271
|
+
get '/' do
|
1272
|
+
settings.foo? # => true
|
1273
|
+
settings.foo # => 'bar'
|
1274
|
+
...
|
1275
|
+
end
|
1276
|
+
|
1277
|
+
=== Paramètres disponibles
|
1278
|
+
|
1279
|
+
[absolute_redirects] Si désactivé, Sinatra permettra les redirections
|
1280
|
+
relatives. Toutefois, Sinatra ne sera plus conforme à la
|
1281
|
+
RFC 2616 (HTTP 1.1), qui n'autorise que les redirections
|
1282
|
+
absolues.
|
1283
|
+
|
1284
|
+
Activez si votre application tourne derrière un proxy
|
1285
|
+
inverse qui n'a pas été correctement configuré. Notez
|
1286
|
+
que la méthode +url+ continuera de produire des URLs
|
1287
|
+
absolues, sauf si vous lui passez +false+ comme second
|
1288
|
+
argument.
|
1289
|
+
|
1290
|
+
Désactivé par défaut.
|
1291
|
+
|
1292
|
+
[add_charsets] types mime pour lesquels la méthode
|
1293
|
+
<tt>content_type</tt> va automatiquement ajouter
|
1294
|
+
l'information du +charset+.
|
1295
|
+
|
1296
|
+
Vous devriez lui ajouter des valeurs plutôt que de
|
1297
|
+
l'écraser :
|
1298
|
+
|
1299
|
+
settings.add_charsets << "application/foobar"
|
1300
|
+
|
1301
|
+
[app_file] fichier de l'application principale, utilisé pour
|
1302
|
+
détecterla racine du projet, le dossier public et le
|
1303
|
+
dossier de vues ainsi que pour les templates en ligne.
|
1304
|
+
|
1305
|
+
[bind] adresse IP sur laquelle se brancher
|
1306
|
+
(par défaut: 0.0.0.0).
|
1307
|
+
Utiliser seulement pour le serveur intégré.
|
1308
|
+
|
1309
|
+
[default_encoding] encodage à utiliser si inconnu (par défaut
|
1310
|
+
<tt>"utf-8"</tt>).
|
1311
|
+
|
1312
|
+
[dump_errors] afficher les erreurs dans le +log+.
|
1313
|
+
|
1314
|
+
[environment] environnement courant, par défaut
|
1315
|
+
<tt>ENV['RACK_ENV']</tt>, ou
|
1316
|
+
<tt>"development"</tt> si absent.
|
1317
|
+
|
1318
|
+
[logging] utiliser le +logger+.
|
1319
|
+
|
1320
|
+
[lock] Place un +lock+ autour de chaque requête, n'exécutant
|
1321
|
+
donc qu'une seule requête par processus Ruby.
|
1322
|
+
|
1323
|
+
Activé si votre application n'est pas +thread-safe+.
|
1324
|
+
Désactivé par défaut.
|
1325
|
+
|
1326
|
+
[method_override] utilise la magie de <tt>_method</tt> afin de permettre
|
1327
|
+
des formulaires put/delete dans des navigateurs qui ne
|
1328
|
+
le permettent pas.
|
1329
|
+
|
1330
|
+
[port] port à écouter. Utiliser seulement pour le serveur
|
1331
|
+
intégré.
|
1332
|
+
|
1333
|
+
[prefixed_redirects] si oui ou non <tt>request.script_name</tt> doit être
|
1334
|
+
inséré dans les redirections si un chemin non absolu
|
1335
|
+
est utilisé. Ainsi, <tt>redirect '/foo'</tt> se
|
1336
|
+
comportera comme <tt>redirect to('/foo')</tt>.
|
1337
|
+
Désactivé par défaut.
|
1338
|
+
|
1339
|
+
[public] dossier duquel les fichiers publics sont servis
|
1340
|
+
|
1341
|
+
[reload_templates] si oui ou non les templates doivent être rechargés
|
1342
|
+
entre les requêtes. Activé en mode développement
|
1343
|
+
et sur Ruby 1.8.6 (pour compenser un bug Ruby
|
1344
|
+
occasionnant une fuite de mémoire).
|
1345
|
+
|
1346
|
+
[root] dossier racine du projet.
|
1347
|
+
|
1348
|
+
[raise_errors] soulever les erreurs (ce qui arrêtera l'application).
|
1349
|
+
|
1350
|
+
[run] si activé, Sinatra s'occupera de démarrer le serveur,
|
1351
|
+
ne pas activer si vous utiliser rackup ou autres.
|
1352
|
+
|
1353
|
+
[running] est-ce que le serveur intégré est en marche ?
|
1354
|
+
ne changez pas ce paramètre !
|
1355
|
+
|
1356
|
+
[server] serveur ou liste de serveurs à utiliser pour le serveur
|
1357
|
+
intégré.
|
1358
|
+
Par défaut ['thin', 'mongrel', 'webrick'], l'ordre
|
1359
|
+
indiquant la priorité.
|
1360
|
+
|
1361
|
+
[sessions] active l'enregistrement des sessions en utilisant les
|
1362
|
+
cookies.
|
1363
|
+
|
1364
|
+
[show_exceptions] affiche la trace de l'erreur dans le navigateur.
|
1365
|
+
|
1366
|
+
[static] Si oui ou non Sinatra doit s'occuper de servir les
|
1367
|
+
fichiers statiques.
|
1368
|
+
Désactivez si vous utilisez un serveur capable de le
|
1369
|
+
gérer lui même. Le désactiver augmentera la performance.
|
1370
|
+
Activé par défaut.
|
1371
|
+
|
1372
|
+
[views] dossier des vues.
|
1373
|
+
|
694
1374
|
== Gérer les erreurs
|
695
1375
|
|
696
|
-
Les gestionnaires d'erreur s'exécutent dans le même contexte que les routes ou
|
697
|
-
filtres, ce qui veut dire que vous avez accès (entre autres) aux bons
|
698
|
-
<tt>haml</tt>, <tt>erb</tt>, <tt>halt</tt>, etc.
|
1376
|
+
Les gestionnaires d'erreur s'exécutent dans le même contexte que les routes ou
|
1377
|
+
les filtres, ce qui veut dire que vous avez accès (entre autres) aux bons
|
1378
|
+
vieux <tt>haml</tt>, <tt>erb</tt>, <tt>halt</tt>, etc.
|
699
1379
|
|
700
1380
|
=== Pas Trouvé
|
701
1381
|
|
702
|
-
Quand une exception <tt>Sinatra::NotFound</tt> est soulevée, ou que le code
|
703
|
-
est 404, le gestionnaire <tt>not_found</tt> est invoqué:
|
1382
|
+
Quand une exception <tt>Sinatra::NotFound</tt> est soulevée, ou que le code
|
1383
|
+
retour est 404, le gestionnaire <tt>not_found</tt> est invoqué:
|
704
1384
|
|
705
1385
|
not_found do
|
706
1386
|
'Pas moyen de trouver ce que vous cherchez'
|
@@ -708,8 +1388,9 @@ est 404, le gestionnaire <tt>not_found</tt> est invoqué:
|
|
708
1388
|
|
709
1389
|
=== Erreur
|
710
1390
|
|
711
|
-
Le gestionnaire +error+ est invoqué à chaque fois qu'une exception est
|
712
|
-
ou un filtre. L'objet exception est accessible via la
|
1391
|
+
Le gestionnaire +error+ est invoqué à chaque fois qu'une exception est
|
1392
|
+
soulevée dans une route ou un filtre. L'objet exception est accessible via la
|
1393
|
+
variable Rack <tt>sinatra.error</tt>:
|
713
1394
|
|
714
1395
|
error do
|
715
1396
|
'Désolé mais une méchante erreur est survenue - ' + env['sinatra.error'].name
|
@@ -731,7 +1412,8 @@ Vous obtenez ça:
|
|
731
1412
|
|
732
1413
|
Donc il est arrivé ceci... quelque chose de mal
|
733
1414
|
|
734
|
-
Alternativement, vous pouvez avoir un gestionnaire d'erreur associé à un code
|
1415
|
+
Alternativement, vous pouvez avoir un gestionnaire d'erreur associé à un code
|
1416
|
+
particulier:
|
735
1417
|
|
736
1418
|
error 403 do
|
737
1419
|
'Accès interdit'
|
@@ -747,27 +1429,18 @@ Ou un intervalle:
|
|
747
1429
|
'Boom'
|
748
1430
|
end
|
749
1431
|
|
750
|
-
Sinatra installe pour vous quelques gestionnaires <tt>not_found</tt> et
|
751
|
-
génériques lorsque vous êtes en environnement
|
752
|
-
|
753
|
-
== Types Mime
|
754
|
-
|
755
|
-
Quand vous utilisez <tt>send_file</tt> et que le fichier possède une extension que Sinatra
|
756
|
-
ne reconnaît pas, utilisez +mime_type+ pour la déclarer:
|
757
|
-
|
758
|
-
mime_type :foo, 'text/foo'
|
759
|
-
|
760
|
-
Vous pouvez aussi l'utiliser avec +content_type+:
|
761
|
-
|
762
|
-
content_type :foo
|
1432
|
+
Sinatra installe pour vous quelques gestionnaires <tt>not_found</tt> et
|
1433
|
+
<tt>error</tt> génériques lorsque vous êtes en environnement
|
1434
|
+
<tt>development</tt>.
|
763
1435
|
|
764
1436
|
== Les Middlewares Rack
|
765
1437
|
|
766
1438
|
Sinatra tourne avec Rack[http://rack.rubyforge.org/], une interface standard
|
767
1439
|
et minimale pour les web frameworks Ruby. Un des points forts de Rack est le
|
768
|
-
support de ce que l'on appelle des "middlewares" -- composant qui vient se
|
769
|
-
entre le serveur et votre application, et dont le but est de
|
770
|
-
requête/réponse HTTP, et d'offrir diverses
|
1440
|
+
support de ce que l'on appelle des "middlewares" -- composant qui vient se
|
1441
|
+
situer entre le serveur et votre application, et dont le but est de
|
1442
|
+
visualiser/manipuler la requête/réponse HTTP, et d'offrir diverses
|
1443
|
+
fonctionnalités classiques.
|
771
1444
|
|
772
1445
|
Sinatra permet de construire facilement des middlewares Rack via la méthode de
|
773
1446
|
haut niveau +use+:
|
@@ -784,17 +1457,17 @@ haut niveau +use+:
|
|
784
1457
|
|
785
1458
|
La sémantique de +use+ est identique à celle définie dans le DSL de
|
786
1459
|
Rack::Builder[http://rack.rubyforge.org/doc/classes/Rack/Builder.html]
|
787
|
-
(le plus souvent utilisé dans un fichier rackup). Par exemple, la méthode
|
788
|
-
accepte divers arguments ainsi que des blocs:
|
1460
|
+
(le plus souvent utilisé dans un fichier rackup). Par exemple, la méthode
|
1461
|
+
+use+ accepte divers arguments ainsi que des blocs:
|
789
1462
|
|
790
1463
|
use Rack::Auth::Basic do |login, password|
|
791
1464
|
login == 'admin' && password == 'secret'
|
792
1465
|
end
|
793
1466
|
|
794
|
-
Rack est distribué avec une bonne variété de middlewares standards pour les
|
795
|
-
débuguer, faire du routage URL, de l'authentification, gérer des
|
796
|
-
Sinatra utilise beaucoup de ces composants automatiquement via la
|
797
|
-
donc pour ceux-ci vous n'aurez pas à utiliser la méthode +use+.
|
1467
|
+
Rack est distribué avec une bonne variété de middlewares standards pour les
|
1468
|
+
logs, débuguer, faire du routage URL, de l'authentification, gérer des
|
1469
|
+
sessions. Sinatra utilise beaucoup de ces composants automatiquement via la
|
1470
|
+
configuration, donc pour ceux-ci vous n'aurez pas à utiliser la méthode +use+.
|
798
1471
|
|
799
1472
|
== Tester
|
800
1473
|
|
@@ -803,6 +1476,7 @@ basée sur Rack. {Rack::Test}[http://gitrdoc.com/brynary/rack-test] est
|
|
803
1476
|
recommandé:
|
804
1477
|
|
805
1478
|
require 'mon_application_sinatra'
|
1479
|
+
require 'test/unit'
|
806
1480
|
require 'rack/test'
|
807
1481
|
|
808
1482
|
class MonTest < Test::Unit::TestCase
|
@@ -839,8 +1513,8 @@ de créer des composants réutilisables comme des middlewares Rack, faire
|
|
839
1513
|
du Rails metal, ou de simples bibliothèques avec un composant serveur, ou
|
840
1514
|
même une extension pour Sinatra. Le DSL de haut niveau pollue l'espace de noms
|
841
1515
|
et est une configuration adaptée à une micro-application (un fichier unique
|
842
|
-
pour l'application, les dossiers ./public et ./views, les logs, pages
|
843
|
-
C'est là que Sinatra::Base entre en jeu:
|
1516
|
+
pour l'application, les dossiers ./public et ./views, les logs, pages
|
1517
|
+
d'erreur, etc.). C'est là que Sinatra::Base entre en jeu:
|
844
1518
|
|
845
1519
|
require 'sinatra/base'
|
846
1520
|
|
@@ -853,13 +1527,6 @@ C'est là que Sinatra::Base entre en jeu:
|
|
853
1527
|
end
|
854
1528
|
end
|
855
1529
|
|
856
|
-
La classe MonApplication est un composant Rack indépendant qui peut agir
|
857
|
-
comme un middleware Rack, une application Rack, ou Rails metal. vous pouvez
|
858
|
-
donc le lancer avec +run+ ou l'utiliser avec +use+ dans un fichier rackup;
|
859
|
-
ou contrôler un composant de serveur sous forme de bibliothèque:
|
860
|
-
|
861
|
-
MonApplication.run! :host => 'localhost', :port => 9090
|
862
|
-
|
863
1530
|
Les méthodes disponibles dans Sinatra::Base sont exactement identiques à
|
864
1531
|
celles disponibles dans le DSL de haut niveau. La plupart des applications
|
865
1532
|
de haut niveau peuvent être converties en composant Sinatra::Base avec
|
@@ -871,16 +1538,107 @@ deux modifications:
|
|
871
1538
|
* Mettre vos gestionnaires de route, vos gestionnaires d'erreur, vos filtres
|
872
1539
|
et options dans une sous-classe de Sinatra::Base.
|
873
1540
|
|
874
|
-
<tt>Sinatra::Base</tt> est plutôt épuré. La plupart des options sont
|
875
|
-
ceci inclus le serveur. Voir {Options et
|
1541
|
+
<tt>Sinatra::Base</tt> est plutôt épuré. La plupart des options sont
|
1542
|
+
désactivées par défaut, ceci inclus le serveur. Voir {Options et
|
1543
|
+
Configuration}[http://sinatra.github.com/configuration.html]
|
876
1544
|
pour plus de détails sur les options et leur comportement.
|
877
1545
|
|
1546
|
+
=== Style modulaire vs. style classique
|
1547
|
+
|
1548
|
+
Contrairement aux croyanaces, le style classique n'a rien de mauvais. Si cela
|
1549
|
+
convient à votre application, vous n'avez pas à changer pour une application
|
1550
|
+
modulaire.
|
1551
|
+
|
1552
|
+
Il n'y a que deux inconvénient au style classique comparé au style modulaire :
|
1553
|
+
|
1554
|
+
* Vous ne pouvez avoir qu'une seule application Sinatra par processus Ruby. Si
|
1555
|
+
vous envisagez d'en utiliser plus, passez au style modulaire
|
1556
|
+
|
1557
|
+
* Le style classique pollue la classe Object avec des méthodes déléguantes.
|
1558
|
+
Si vous prévoyez de diffuser votre application dans une bibliothèque/gem,
|
1559
|
+
passez au style modulaire.
|
1560
|
+
|
1561
|
+
Il n'y pas d'empêchement à mélanger style classic et style modulaire.
|
1562
|
+
|
1563
|
+
Si vous passez d'un style à l'autre, vous devriez être vigilant à quelques
|
1564
|
+
légères différences dans les paramètres :
|
1565
|
+
|
1566
|
+
Paramètre Classique Modulaire
|
1567
|
+
|
1568
|
+
app_file fichier chargeant sinatra nil
|
1569
|
+
run $0 == app_file false
|
1570
|
+
logging true false
|
1571
|
+
method_override true false
|
1572
|
+
inline_templates true false
|
1573
|
+
|
1574
|
+
|
1575
|
+
=== Servir une application modulaire
|
1576
|
+
|
1577
|
+
Il y a deux façons de faire pour démarrer une application modulaire, démarrez
|
1578
|
+
avec <tt>run!</tt> :
|
1579
|
+
|
1580
|
+
# my_app.rb
|
1581
|
+
require 'sinatra/base'
|
1582
|
+
|
1583
|
+
class MyApp < Sinatra::Base
|
1584
|
+
# ... code de l'application ici ...
|
1585
|
+
|
1586
|
+
# démarre le serveur si ce fichier est directement exécuté
|
1587
|
+
run! if app_file == $0
|
1588
|
+
end
|
1589
|
+
|
1590
|
+
Démarrez ensuite avec :
|
1591
|
+
|
1592
|
+
ruby my_app.rb
|
1593
|
+
|
1594
|
+
Ou alors avec un fichier <tt>config.ru</tt>, qui permet d'utiliser n'importe
|
1595
|
+
quel gestionnaire Rack :
|
1596
|
+
|
1597
|
+
# config.ru
|
1598
|
+
require 'my_app'
|
1599
|
+
run MyApp
|
1600
|
+
|
1601
|
+
Exécutez :
|
1602
|
+
|
1603
|
+
rackup -p 4567
|
1604
|
+
|
1605
|
+
=== Utiliser une application de style classique avec un fichier config.ru
|
1606
|
+
|
1607
|
+
Ecrivez votre application :
|
1608
|
+
|
1609
|
+
# app.rb
|
1610
|
+
require 'sinatra'
|
1611
|
+
|
1612
|
+
get '/' do
|
1613
|
+
'Hello world!'
|
1614
|
+
end
|
1615
|
+
|
1616
|
+
Et un fichier <tt>config.ru</tt> correspondant :
|
1617
|
+
|
1618
|
+
require 'app'
|
1619
|
+
run Sinatra::Application
|
1620
|
+
|
1621
|
+
=== Quand utiliser un fichier config.ru ?
|
1622
|
+
|
1623
|
+
Quelques cas où vous devriez utiliser un fichier <tt>config.ru</tt> :
|
1624
|
+
|
1625
|
+
* Vous souhaitez déployer avec un autre gestionnaire Rack (Passenger, Unicorn,
|
1626
|
+
Heroku, ...).
|
1627
|
+
* Vous souhaitez utiliser plus d'une sous-classe de <tt>Sinatra::Base</tt>.
|
1628
|
+
* Vous voulez utiliser Sinatra comme un +middleware+, non en tant que
|
1629
|
+
+endpoint+.
|
1630
|
+
|
1631
|
+
<b>Il n'est pas nécessaire de passer par un fichier <tt>config.ru</tt> pour la
|
1632
|
+
seule raison que vous êtes passé au style modulaire, et vous n'avez pas besoin
|
1633
|
+
de passer au style modulaire pour utiliser un fichier <tt>config.ru</tt>.</b>
|
1634
|
+
|
878
1635
|
=== Utiliser Sinatra comme Middleware
|
879
1636
|
|
880
|
-
Non seulement Sinatra peut utiliser d'autres middlewares Rack, il peut
|
881
|
-
à son tour utilisé au-dessus de n'importe quel +endpoint+ Rack
|
882
|
-
Ce +endpoint+ peut très bien être une autre
|
883
|
-
application basée sur Rack
|
1637
|
+
Non seulement Sinatra peut utiliser d'autres middlewares Rack, il peut
|
1638
|
+
également être à son tour utilisé au-dessus de n'importe quel +endpoint+ Rack
|
1639
|
+
en tant que middleware. Ce +endpoint+ peut très bien être une autre
|
1640
|
+
application Sinatra, ou n'importe quelle application basée sur Rack
|
1641
|
+
(Rails/Ramaze/Camping/...):
|
884
1642
|
|
885
1643
|
require 'sinatra/base'
|
886
1644
|
|
@@ -919,11 +1677,12 @@ disponibles.
|
|
919
1677
|
=== Contexte de l'application/classe
|
920
1678
|
|
921
1679
|
Toute application Sinatra correspond à une sous-classe de Sinatra::Base. Si
|
922
|
-
vous utilisez le DSL haut niveau (<tt>require 'sinatra'</tt>), alors cette
|
923
|
-
est Sinatra::Application, sinon il s'agit de la sous-classe que vous
|
924
|
-
Dans le contexte de la classe, vous avez accès aux méthodes
|
925
|
-
`before`, mais vous n'avez pas accès aux objets `request`
|
926
|
-
même classe d'application qui traitera toutes les
|
1680
|
+
vous utilisez le DSL haut niveau (<tt>require 'sinatra'</tt>), alors cette
|
1681
|
+
classe est Sinatra::Application, sinon il s'agit de la sous-classe que vous
|
1682
|
+
avez définie. Dans le contexte de la classe, vous avez accès aux méthodes
|
1683
|
+
telles que `get` ou `before`, mais vous n'avez pas accès aux objets `request`
|
1684
|
+
ou `session` car c'est la même classe d'application qui traitera toutes les
|
1685
|
+
requêtes.
|
927
1686
|
|
928
1687
|
Les options définies au moyen de `set` deviennent des méthodes de classe:
|
929
1688
|
|
@@ -951,11 +1710,12 @@ Vous pouvez atteindre ce contexte (donc la classe) de la façon suivante:
|
|
951
1710
|
|
952
1711
|
=== Contexte de la requête/instance
|
953
1712
|
|
954
|
-
Pour tout traitement d'une requête, une nouvelle instance de votre classe
|
955
|
-
est créée et tous vos gestionnaires sont exécutés dans ce
|
956
|
-
vous pouvez accéder aux objets `request` et
|
957
|
-
de rendu telles que `erb` ou `haml`.
|
958
|
-
|
1713
|
+
Pour tout traitement d'une requête, une nouvelle instance de votre classe
|
1714
|
+
d'application est créée et tous vos gestionnaires sont exécutés dans ce
|
1715
|
+
contexte. Dans ce dernier, vous pouvez accéder aux objets `request` et
|
1716
|
+
`session` et faire appel aux fonctions de rendu telles que `erb` ou `haml`.
|
1717
|
+
Vous pouvez accéder au contexte de l'application depuis le contexte de la
|
1718
|
+
requête au moyen de `settings`:
|
959
1719
|
|
960
1720
|
class MonApp < Sinatra::Base
|
961
1721
|
# Eh, je suis dans le contexte de l'application!
|
@@ -974,7 +1734,7 @@ depuis le contexte de la requête au moyen de `settings`:
|
|
974
1734
|
|
975
1735
|
Vous avez le binding du contexte de la requête dans:
|
976
1736
|
|
977
|
-
* les blocs get/head/post/put/delete
|
1737
|
+
* les blocs get/head/post/put/delete/options
|
978
1738
|
* les filtres before/after
|
979
1739
|
* les méthodes utilitaires (définies au moyen de `helpers`)
|
980
1740
|
* les vues/templates
|
@@ -982,12 +1742,12 @@ Vous avez le binding du contexte de la requête dans:
|
|
982
1742
|
=== Le contexte de délégation
|
983
1743
|
|
984
1744
|
Le contexte de délégation se contente de transmettre les appels de méthodes au
|
985
|
-
contexte de classe. Toutefois, il ne se comporte pas à 100% comme le contexte
|
986
|
-
classe car vous n'avez pas le binding de la classe: seules les méthodes
|
987
|
-
spécifiquement déclarées pour délégation sont disponibles et il n'est pas
|
988
|
-
de partager des variables/états avec le contexte de classe
|
989
|
-
pas le même). Vous pouvez ajouter des délégation de
|
990
|
-
<tt>Sinatra::Delegator.delegate :method_name</tt>.
|
1745
|
+
contexte de classe. Toutefois, il ne se comporte pas à 100% comme le contexte
|
1746
|
+
de classe car vous n'avez pas le binding de la classe: seules les méthodes
|
1747
|
+
spécifiquement déclarées pour délégation sont disponibles et il n'est pas
|
1748
|
+
possible de partager des variables/états avec le contexte de classe
|
1749
|
+
(comprenez: `self` n'est pas le même). Vous pouvez ajouter des délégation de
|
1750
|
+
méthodes en appelant <tt>Sinatra::Delegator.delegate :method_name</tt>.
|
991
1751
|
|
992
1752
|
Vous avez le binding du contexte de délégation dans:
|
993
1753
|
|
@@ -995,7 +1755,8 @@ Vous avez le binding du contexte de délégation dans:
|
|
995
1755
|
* Un objet qui inclut le module `Sinatra::Delegator`
|
996
1756
|
|
997
1757
|
Jetez un oeil
|
998
|
-
pour vous faire une idée: voici le mixin
|
1758
|
+
pour vous faire une idée: voici le mixin
|
1759
|
+
{Sinatra::Delegator}[http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/base.rb#L1128]
|
999
1760
|
qui est {inclus dans l'espace de noms principal}[http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/main.rb#L28]
|
1000
1761
|
|
1001
1762
|
== Ligne de commande
|
@@ -1013,38 +1774,138 @@ Les options sont:
|
|
1013
1774
|
-s # déclare le serveur/gestionnaire à utiliser (thin par défaut)
|
1014
1775
|
-x # active le mutex lock (off par défaut)
|
1015
1776
|
|
1777
|
+
== Configuration nécessaire
|
1778
|
+
|
1779
|
+
Il est recommandé d'installer Sinatra sur Ruby 1.8.7, 1.9.2, JRuby ou
|
1780
|
+
Rubinius.
|
1781
|
+
|
1782
|
+
Les versions suivantes de Ruby sont officiellement supportées :
|
1783
|
+
|
1784
|
+
[ Ruby 1.8.6 ]
|
1785
|
+
Il n'est pas recommandé d'utiliser 1.8.6 pour Sinatra. Toutefois, ce sera
|
1786
|
+
officiellement supporté jusqu'à l'arrivée Sinatra 1.3.0. Les templates RDoc
|
1787
|
+
et CoffeeScript ne sont pas supportés par cette version de Ruby. 1.8.6
|
1788
|
+
contient un défaut majeur de fuite de mémoire dans l'implémentation de Hash,
|
1789
|
+
qui est déclenché par les versions de Sinatra antérieure à 1.1.1. La version
|
1790
|
+
actuelle prévient explicitement ce risque au prix de la performance. Vous
|
1791
|
+
devrez utiliser Rack 1.1.x dans la mesure où Rack >= 1.2 ne supporte plus
|
1792
|
+
1.8.6.
|
1793
|
+
|
1794
|
+
[ Ruby 1.8.7 ]
|
1795
|
+
1.8.7 est complètement supporté, toutefois si rien ne vous y retient, nous
|
1796
|
+
vous recommandons de passer à 1.9.2 ou bien de passer à JRuby ou Rubinius.
|
1797
|
+
|
1798
|
+
[ Ruby 1.9.2 ]
|
1799
|
+
1.9.2 est supporté et recommandé. Notez que Radius et Markaby ne sont
|
1800
|
+
actuellement pas compatible avec 1.9. N'utilisez pas 1.9.2p0 qui est
|
1801
|
+
réputé causer des erreurs de segmentation lorque Sinatra est utilisé.
|
1802
|
+
|
1803
|
+
[ Rubinius ]
|
1804
|
+
Rubinius est officiellement supporté (Rubinius >= 1.2.2), à l'exception
|
1805
|
+
des templates Textile.
|
1806
|
+
|
1807
|
+
[ JRuby ]
|
1808
|
+
JRuby est officiellement supporté (JRuby >= 1.5.6). Aucune anomalie avec
|
1809
|
+
des bibliothèques de templates tierces ne sont connues. Toutefois, si vous
|
1810
|
+
choisissez JRuby, alors tournez vous vers des gestionnaires Rack JRuby car
|
1811
|
+
le serveur Thin n'est pas (encore) supporté par JRuby.
|
1812
|
+
|
1813
|
+
Nous gardons également un oeil sur les versions Ruby à venir.
|
1814
|
+
|
1815
|
+
Les implémentations Ruby suivantes ne sont pas officiellement supportées mais
|
1816
|
+
sont toujours connues comme permettant à Sinatra de fonctionner :
|
1817
|
+
|
1818
|
+
* Plus anciennes versions de JRuby et Rubinius
|
1819
|
+
* MacRuby
|
1820
|
+
* Maglev
|
1821
|
+
* IronRuby
|
1822
|
+
* Ruby 1.9.0 et 1.9.1
|
1823
|
+
|
1824
|
+
Ne pas être officiellement supporté signifie que si les choses se passent mal
|
1825
|
+
sur ces plateformes et non sur celles supportées, nous considérons que
|
1826
|
+
l'anomalie est de le ressort, pas du nôtre.
|
1827
|
+
|
1828
|
+
Sinatra devrait fonctionner sur n'importe quel système d'exploitation
|
1829
|
+
supportant l'implémentation Ruby choisie.
|
1830
|
+
|
1016
1831
|
== Essuyer les plâtres
|
1017
1832
|
|
1018
|
-
Si vous voulez utiliser la toute dernière version de Sinatra,
|
1019
|
-
|
1020
|
-
|
1833
|
+
Si vous voulez utiliser la toute dernière version de Sinatra, n'ayez pas peur
|
1834
|
+
de faire tourner votre application sur la branche master, cela devrait être
|
1835
|
+
stable.
|
1021
1836
|
|
1022
|
-
|
1023
|
-
|
1024
|
-
ruby -Isinatra/lib mon_application.rb
|
1837
|
+
Nous publions également une gem de +prerelease+ de temps en temps donc vous
|
1838
|
+
pouvez faire la chose suivante :
|
1025
1839
|
|
1026
|
-
|
1027
|
-
<tt>LOAD_PATH</tt> à l'intérieur de votre application:
|
1840
|
+
gem install sinatra --pre
|
1028
1841
|
|
1029
|
-
|
1030
|
-
require 'rubygems'
|
1031
|
-
require 'sinatra'
|
1842
|
+
afin d'avoir certaines des toutes dernières fonctionnalités.
|
1032
1843
|
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1844
|
+
=== Avec Bundler
|
1845
|
+
|
1846
|
+
Si vous voulez faire tourner votre application avec le tout dernier
|
1847
|
+
Sinatra, {Bundler}[http://gembundler.com/] est recommandé.
|
1848
|
+
|
1849
|
+
Tout d'abord, installer bundler si vous ne l'avez pas :
|
1850
|
+
|
1851
|
+
gem install bundler
|
1852
|
+
|
1853
|
+
Ensuite, dans le dossier de votre projet, créez un fichier +Gemfile+ :
|
1854
|
+
|
1855
|
+
source :rubygems
|
1856
|
+
gem 'sinatra', :git => "git://github.com/sinatra/sinatra.git"
|
1857
|
+
|
1858
|
+
# autres dépendances
|
1859
|
+
gem 'haml' # par exemple, si vous utilisez haml
|
1860
|
+
gem 'activerecord', '~> 3.0' # peut-être que vous avez également besoin
|
1861
|
+
# de ActiveRecord 3.x
|
1862
|
+
|
1863
|
+
Notez que vous aurez à lister toutes les dépendances de votre application dans
|
1864
|
+
ce fichier. Les dépendances directes de Sinatra (Rack et Tilt) seront
|
1865
|
+
automatiquement téléchargées et ajoutées par Bundler.
|
1866
|
+
|
1867
|
+
Maintenant, vous pouvez faire tourner votre application de la façon suivante :
|
1868
|
+
|
1869
|
+
bundle exec ruby myapp.rb
|
1870
|
+
|
1871
|
+
=== Faites le vous-même
|
1036
1872
|
|
1037
|
-
|
1873
|
+
Créez un clone local et démarrez votre application avec le dossier
|
1874
|
+
<tt>sinatra/lib</tt> dans le <tt>$LOAD_PATH</tt> :
|
1038
1875
|
|
1039
|
-
cd
|
1876
|
+
cd myapp
|
1877
|
+
git clone git://github.com/sinatra/sinatra.git
|
1878
|
+
ruby -Isinatra/lib myapp.rb
|
1879
|
+
|
1880
|
+
A l'avenir, pour mettre à jour le code source de Sinatra :
|
1881
|
+
|
1882
|
+
cd myapp/sinatra
|
1040
1883
|
git pull
|
1041
1884
|
|
1885
|
+
=== Installez globalement
|
1886
|
+
|
1887
|
+
Vous pouvez construire la gem vous-même :
|
1888
|
+
|
1889
|
+
git clone git://github.com/sinatra/sinatra.git
|
1890
|
+
cd sinatra
|
1891
|
+
rake sinatra.gemspec
|
1892
|
+
rake install
|
1893
|
+
|
1894
|
+
Si vous installez les gems en tant que +root+, la dernière étape sera :
|
1895
|
+
|
1896
|
+
sudo rake install
|
1897
|
+
|
1898
|
+
== Versions
|
1899
|
+
|
1900
|
+
Sinatra se conforme aux {versions sémantiques}[http://semver.org/], aussi bien
|
1901
|
+
SemVer que SemVerTag.
|
1902
|
+
|
1042
1903
|
== Mais encore
|
1043
1904
|
|
1044
1905
|
* {Site internet}[http://www.sinatrarb.com/] - Plus de documentation,
|
1045
1906
|
de news, et des liens vers d'autres ressources.
|
1046
|
-
* {Contribuer}[http://www.sinatrarb.com/contributing] - Vous avez trouvé un
|
1047
|
-
d'aide? Vous avez un patch?
|
1907
|
+
* {Contribuer}[http://www.sinatrarb.com/contributing] - Vous avez trouvé un
|
1908
|
+
bug? Besoin d'aide? Vous avez un patch?
|
1048
1909
|
* {Suivi des problèmes}[http://github.com/sinatra/sinatra/issues]
|
1049
1910
|
* {Twitter}[http://twitter.com/sinatra]
|
1050
1911
|
* {Mailing List}[http://groups.google.com/group/sinatrarb/topics]
|