sinatra 1.2.0.c → 1.2.0.d

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.

@@ -18,6 +18,9 @@ Instalá la gem y ejecutá la aplicación con:
18
18
 
19
19
  Podés verla en: http://localhost:4567
20
20
 
21
+ Es recomendable además ejecutar <tt>gem install thin</tt>, ya que Sinatra lo va
22
+ a utilizar cuando esté disponible.
23
+
21
24
  == Rutas
22
25
 
23
26
  En Sinatra, una ruta está compuesta por un método HTTP y un patrón de una URL.
@@ -126,7 +129,7 @@ Podés definir tus propias condiciones fácilmente:
126
129
  "Lo siento, perdiste."
127
130
  end
128
131
 
129
- === Valores de retorno
132
+ === Valores de Retorno
130
133
 
131
134
  El valor de retorno de un bloque de ruta determina al menos el cuerpo de la
132
135
  respuesta que se le pasa al cliente HTTP o al siguiente middleware en la pila
@@ -151,6 +154,47 @@ De esa manera podemos, por ejemplo, implementar fácilmente un streaming:
151
154
 
152
155
  get('/') { Stream.new }
153
156
 
157
+ === Comparadores de Rutas Personalizados
158
+
159
+ Como se mostró anteriormente, Sinatra permite utilizar Strings y expresiones
160
+ regulares para definir las rutas. Sin embargo, la cosa no termina ahí. Podés
161
+ definir tus propios comparadores muy fácilmente:
162
+
163
+ class PattronCualquieraMenos
164
+ Match = Struct.new(:captures)
165
+
166
+ def initialize(excepto)
167
+ @excepto = excepto
168
+ @caputras = Match.new([])
169
+ end
170
+
171
+ def match(str)
172
+ @caputras unless @excepto === str
173
+ end
174
+ end
175
+
176
+ def cualquiera_menos(patron)
177
+ PatronCualquieraMenos.new(patron)
178
+ end
179
+
180
+ get cualquiera_menos("/index") do
181
+ # ...
182
+ end
183
+
184
+ Tené en cuenta que el ejemplo anterior es un poco rebuscado. Un resultado
185
+ similar puede conseguirse más sencillamente:
186
+
187
+ get // do
188
+ pass if request.path_info == "/index"
189
+ # ...
190
+ end
191
+
192
+ O, usando un lookahead negativo:
193
+
194
+ get %r{^(?!/index$)} do
195
+ # ...
196
+ end
197
+
154
198
  == Archivos Estáticos
155
199
 
156
200
  Los archivos estáticos son servidos desde el directorio público
@@ -372,7 +416,7 @@ plantillas:
372
416
 
373
417
  Como no podés utilizar Ruby desde Markdown, no podés usar layouts escritos en
374
418
  Markdown. De todos modos, es posible usar un motor de renderizado para el
375
- layout distinto al de la plantilla pasando la opción `:layout_engine`:
419
+ layout distinto al de la plantilla pasando la opción <tt>:layout_engine</tt>:
376
420
 
377
421
  get '/' do
378
422
  markdown :index, :layout_engine => :erb
@@ -432,7 +476,7 @@ plantillas:
432
476
 
433
477
  Como no podés utilizar Ruby desde Textile, no podés usar layouts escritos en
434
478
  Textile. De todos modos, es posible usar un motor de renderizado para el
435
- layout distinto al de la plantilla pasando la opción `:layout_engine`:
479
+ layout distinto al de la plantilla pasando la opción <tt>:layout_engine</tt>:
436
480
 
437
481
  get '/' do
438
482
  textile :index, :layout_engine => :erb
@@ -456,8 +500,8 @@ con el layout <tt>./views/post.haml</tt>.
456
500
 
457
501
  La gem/librería <tt>rdoc</tt> es necesaria para renderizar plantillas RDoc:
458
502
 
459
- # Vas a necesitar requerir rdoc en tu app
460
- require "rdoc"
503
+ # Vas a necesitar requerir rdoc/markup/to_html en tu app
504
+ require "rdoc/markup/to_html"
461
505
 
462
506
  get '/' do
463
507
  rdoc :index
@@ -478,7 +522,7 @@ plantillas:
478
522
 
479
523
  Como no podés utilizar Ruby desde RDoc, no podés usar layouts escritos en RDoc.
480
524
  De todos modos, es posible usar un motor de renderizado para el layout distinto
481
- al de la plantilla pasando la opción `:layout_engine`:
525
+ al de la plantilla pasando la opción <tt>:layout_engine</tt>:
482
526
 
483
527
  get '/' do
484
528
  rdoc :index, :layout_engine => :erb
@@ -676,10 +720,10 @@ para aprender más de Tilt.
676
720
 
677
721
  == Filtros
678
722
 
679
- Los filtros before son evaluados antes de cada petición dentro del mismo
680
- contexto que las rutas serán evaluadas y pueden modificar la petición y la
681
- respuesta. Las variables de instancia asignadas en los filtros son accesibles
682
- por las rutas y las plantillas:
723
+ Los filtros +before+ son evaluados antes de cada petición dentro del mismo
724
+ contexto que las rutas. Pueden modificar la petición y la respuesta. Las
725
+ variables de instancia asignadas en los filtros son accesibles por las rutas y
726
+ las plantillas:
683
727
 
684
728
  before do
685
729
  @nota = 'Hey!'
@@ -691,16 +735,16 @@ por las rutas y las plantillas:
691
735
  params[:splat] #=> 'bar/baz'
692
736
  end
693
737
 
694
- Los filtros after son evaluados después de cada petición dentro del mismo
695
- contexto y también pueden modificar la petición y la respuesta. Las variables
696
- de instancia asignadas en los filtros before y rutas son accesibles por los
697
- filtros after:
738
+ Los filtros +after+ son evaluados después de cada petición dentro del mismo
739
+ contexto y también pueden modificar la petición y la respuesta. Las variables
740
+ de instancia asignadas en los filtros +before+ y en las rutas son accesibles por
741
+ los filtros +after+:
698
742
 
699
743
  after do
700
744
  puts response.status
701
745
  end
702
746
 
703
- Nota: A menos que usés el método `body` en lugar de simplemente devolver un
747
+ Nota: A menos que usés el método +body+ en lugar de simplemente devolver un
704
748
  string desde una ruta, el cuerpo de la respuesta no va a estar disponible en
705
749
  un filtro after, debido a que todavía no se ha generado.
706
750
 
@@ -716,7 +760,7 @@ patrón:
716
760
  session[:ultimo_slug] = slug
717
761
  end
718
762
 
719
- Al igual que las rutas, los filtros también aceptan condiciones:
763
+ Al igual que las rutas, los filtros también pueden aceptar condiciones:
720
764
 
721
765
  before :agent => /Songbird/ do
722
766
  # ...
@@ -741,6 +785,37 @@ pueden ser utilizados dentro de los manejadores de rutas y las plantillas:
741
785
  bar(params[:nombre])
742
786
  end
743
787
 
788
+ === Usando Sesiones
789
+
790
+ Una sesión es usada para mantener el estado a través de distintas peticiones.
791
+ Cuando están activadas, tenés un hash de sesión para cada sesión de usuario:
792
+
793
+ enable :sessions
794
+
795
+ get '/' do
796
+ "valor = " << session[:valor].inspect
797
+ end
798
+
799
+ get '/:valor' do
800
+ session[:valor] = params[:valor]
801
+ end
802
+
803
+ Tené en cuenta que <tt>enable :sessions</tt> guarda todos los datos en una
804
+ cookie, lo que no es siempre deseable (guardar muchos datos va a incrementar
805
+ tu tráfico, por citar un ejemplo). Podés usar cualquier middleware Rack para
806
+ manejar sesiones, de la misma manera que usarías cualquier otro middleware,
807
+ pero con la salvedad de que *no* tenés que llamar a <tt>enable :sessions</tt>:
808
+
809
+ use Rack::Session::Pool, :expire_after => 2592000
810
+
811
+ get '/' do
812
+ "valor = " << session[:valor].inspect
813
+ end
814
+
815
+ get '/:valor' do
816
+ session[:valor] = params[:valor]
817
+ end
818
+
744
819
  === Interrupción
745
820
 
746
821
  Para detener inmediatamente una petición dentro de un filtro o una ruta usá:
@@ -780,12 +855,36 @@ la petición usando <tt>pass</tt>:
780
855
  Se sale inmediatamente del bloque de la ruta y se le pasa el control a la
781
856
  siguiente ruta que coincida. Si no coincide ninguna ruta, se devuelve un 404.
782
857
 
783
- === Asignando el cuerpo y el código de estado de una respuesta
858
+ === Ejecutando Otra Ruta
859
+
860
+ Cuando querés obtener el resultado de la llamada a una ruta, +pass+ no te va a
861
+ servir. Para lograr esto, podés usar +call+:
862
+
863
+ get '/foo' do
864
+ status, headers, body = call request.env.merge("PATH_INFO" => '/bar')
865
+ [status, body.upcase]
866
+ end
867
+
868
+ get '/bar' do
869
+ "bar"
870
+ end
871
+
872
+ Notá que en el ejemplo anterior, es conveniente mover <tt>"bar"</tt> a un
873
+ helper, y llamarlo desde <tt>/foo</tt> y <tt>/bar</tt>. Así, vas a simplificar
874
+ las pruebas y a mejorar el rendimiento.
875
+
876
+ Si querés que la petición se envíe a la misma instancia de la aplicación en
877
+ lugar de a otra, usá <tt>call!</tt> en lugar de <tt>call</tt>.
878
+
879
+ En la especificación de Rack podés encontrar más información sobre
880
+ <tt>call</tt>.
881
+
882
+ === Asignando el Código de Estado, los Encabezados y el Cuerpo de una Respuesta
784
883
 
785
884
  Es posible, y se recomienda, asignar el código de estado y el cuerpo de una
786
885
  respuesta con el valor de retorno de una ruta. De cualquier manera, en varios
787
886
  escenarios, puede que sea conveniente asignar el cuerpo en un punto arbitrario
788
- del flujo de ejecución con el método `body`. A partir de ahí, podés usar ese
887
+ del flujo de ejecución con el método +body+. A partir de ahí, podés usar ese
789
888
  mismo método para acceder al cuerpo de la respuesta:
790
889
 
791
890
  get '/foo' do
@@ -796,35 +895,78 @@ mismo método para acceder al cuerpo de la respuesta:
796
895
  puts body
797
896
  end
798
897
 
799
- También es posible pasarle un bloque a body, que será ejecutado por el rack
800
- handler (podés usar esto para implementar streaming, mirá
801
- [Valores de retorno](#Valores%20de%20retorno)).
898
+ También es posible pasarle un bloque a +body+, que será ejecutado por el Rack
899
+ handler (podés usar esto para implementar streaming, mirá "Valores de retorno").
802
900
 
803
- De manera similar, también podés asignar el código de estado:
901
+ De manera similar, también podés asignar el código de estado y encabezados:
804
902
 
805
903
  get '/foo' do
806
904
  status 418
807
- halt "I'm a teapot"
905
+ headers \
906
+ "Allow" => "BREW, POST, GET, PROPFIND, WHEN"
907
+ "Refresh" => "Refresh: 20; http://www.ietf.org/rfc/rfc2324.txt"
908
+ body "I'm a tea pot!"
909
+ end
910
+
911
+ También, al igual que +body+, tanto +status+ como +headers+ pueden utilizarse
912
+ para obtener sus valores cuando no se les pasa argumentos.
913
+
914
+ === Tipos Mime
915
+
916
+ Cuando usás <tt>send_file</tt> o archivos estáticos tal vez tengas tipos mime
917
+ que Sinatra no entiende. Usá +mime_type+ para registrarlos a través de la
918
+ extensión de archivo:
919
+
920
+ mime_type :foo, 'text/foo'
921
+
922
+ También lo podés usar con el ayudante +content_type+:
923
+
924
+ get '/' do
925
+ content_type :foo
926
+ "foo foo foo"
808
927
  end
809
928
 
929
+ === Generando URLs
930
+
931
+ Para generar URLs deberías usar el método +url+. Por ejemplo, en Haml:
932
+
933
+ %a{:href => url('/foo')} foo
934
+
935
+ Tiene en cuenta proxies inversos y encaminadores de Rack, si están presentes.
936
+
937
+ Este método también puede invocarse mediante su alias +to+ (mirá un ejemplo
938
+ a continuación).
939
+
810
940
  === Redirección del Navegador
811
941
 
812
- Podés redireccionar al navegador con el método `redirect`:
942
+ Podés redireccionar al navegador con el método +redirect+:
813
943
 
814
944
  get '/foo' do
815
- redirect '/bar'
945
+ redirect to('/bar')
816
946
  end
817
947
 
818
948
  Cualquier parámetro adicional se utiliza de la misma manera que los argumentos
819
- pasados a `halt`:
949
+ pasados a +halt+:
950
+
951
+ redirect to('/bar'), 303
952
+ redirect 'http://google.com', 'te confundiste de lugar, compañero'
820
953
 
821
- redirect '/bar', 303
822
- redirect '/bar', 'te confundiste de lugar, compañero'
954
+ También podés redireccionar fácilmente de vuelta hacia la página desde donde
955
+ vino el usuario con +redirect back+:
823
956
 
824
- Para pasar argumetnos con una redirección, podés agregarlo a la cadena de
957
+ get '/foo' do
958
+ "<a href='/bar'>hacer algo</a>"
959
+ end
960
+
961
+ get '/bar' do
962
+ hacer_algo
963
+ redirect back
964
+ end
965
+
966
+ Para pasar argumentos con una redirección, podés agregarlos a la cadena de
825
967
  búsqueda:
826
968
 
827
- redirect '/bar?suma=42'
969
+ redirect to('/bar?suma=42')
828
970
 
829
971
  O usar una sesión:
830
972
 
@@ -832,18 +974,111 @@ O usar una sesión:
832
974
 
833
975
  get '/foo' do
834
976
  session[:secreto] = 'foo'
835
- redirect '/bar'
977
+ redirect to('/bar')
836
978
  end
837
979
 
838
980
  get '/bar' do
839
981
  session[:secreto]
840
982
  end
841
983
 
984
+ === Cache Control
985
+
986
+ Asignar tus encabezados correctamente es el cimiento para realizar un cacheo
987
+ HTTP correcto.
988
+
989
+ Podés asignar el encabezado Cache-Control fácilmente:
990
+
991
+ get '/' do
992
+ cache_control :public
993
+ "cachealo!"
994
+ end
995
+
996
+ Pro tip: configurar el cacheo en un filtro +before+.
997
+
998
+ before do
999
+ cache_control :public, :must_revalidate, :max_age => 60
1000
+ end
1001
+
1002
+ Si estás usando el helper +expires+ para definir el encabezado correspondiente,
1003
+ <tt>Cache-Control</tt> se va a definir automáticamente:
1004
+
1005
+ before do
1006
+ expires 500, :public, :must_revalidate
1007
+ end
1008
+
1009
+ Para usar cachés adecuadamente, deberías considerar usar +etag+ y
1010
+ +last_modified+. Es recomendable que llames a estos helpers *antes* de hacer
1011
+ cualquier trabajo pesado, ya que van a enviar la respuesta inmediatamente si
1012
+ el cliente ya tiene la versión actual en su caché.
1013
+
1014
+ get '/articulo/:id' do
1015
+ @articulo = Articulo.find params[:id]
1016
+ last_modified @articulo.updated_at
1017
+ etag @articulo.sha1
1018
+ erb :articulo
1019
+ end
1020
+
1021
+ También es posible usar una
1022
+ {weak ETag}[http://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation]:
1023
+
1024
+ etag @articulo.sha1, :weak
1025
+
1026
+ Estos helpers no van a cachear nada por vos, sino que van a facilitar la
1027
+ información necesaria para poder hacerlo. Si estás buscando soluciones rápidas
1028
+ de cacheo, mirá {rack-cache}[http://rtomayko.github.com/rack-cache/]:
1029
+
1030
+ require "rack/cache"
1031
+ require "sinatra"
1032
+
1033
+ use Rack::Cache
1034
+
1035
+ get '/' do
1036
+ cache_control :public, :max_age => 36000
1037
+ sleep 5
1038
+ "hola"
1039
+ end
1040
+
1041
+ === Enviando Archivos
1042
+
1043
+ Para enviar archivos, podés usar el método <tt>send_file</tt>:
1044
+
1045
+ get '/' do
1046
+ send_file 'foo.png'
1047
+ end
1048
+
1049
+ Además acepta un par de opciones:
1050
+
1051
+ send_file 'foo.png', :type => :jpg
1052
+
1053
+ Estas opciones son:
1054
+
1055
+ [filename]
1056
+ nombre del archivo respondido, por defecto es el nombre real del archivo.
1057
+
1058
+ [last_modified]
1059
+ valor para el encabezado Last-Modified, por defecto toma el mtime del archivo.
1060
+
1061
+ [type]
1062
+ el content type que se va a utilizar, si no está presente se intenta adivinar
1063
+ a partir de la extensión del archivo.
1064
+
1065
+ [disposition]
1066
+ se utiliza para el encabezado Content-Disposition, y puede tomar alguno de los
1067
+ siguientes valores: +nil+ (por defecto), <tt>:attachment</tt> e
1068
+ <tt>:inline</tt>
1069
+
1070
+ [length]
1071
+ encabezado Content-Length, por defecto toma el tamaño del archivo.
1072
+
1073
+ Si el Rack handler lo soporta, se intentará no transmitir directamente desde el
1074
+ proceso de Ruby. Si usás este método, Sinatra se va a encargar automáticamente
1075
+ peticiones de rango.
1076
+
842
1077
  === Accediendo al objeto de la petición
843
1078
 
844
1079
  El objeto de la petición entrante puede ser accedido desde el nivel de la
845
1080
  petición (filtros, rutas y manejadores de errores) a través del método
846
- `request`:
1081
+ <tt>request</tt>:
847
1082
 
848
1083
  # app corriendo en http://ejemplo.com/ejemplo
849
1084
  get '/foo' do
@@ -860,14 +1095,15 @@ petición (filtros, rutas y manejadores de errores) a través del método
860
1095
  request.get? # verdadero (hay métodos análogos para los otros verbos)
861
1096
  request.form_data? # falso
862
1097
  request["UNA_CABECERA"] # valor de la cabecera UNA_CABECERA
863
- request.referer # la referencia del cliente o '/'
1098
+ request.referrer # la referencia del cliente o '/'
864
1099
  request.user_agent # user agent (usado por la condición :agent)
865
1100
  request.cookies # hash de las cookies del browser
866
1101
  request.xhr? # es una petición ajax?
867
1102
  request.url # "http://ejemplo.com/ejemplo/foo"
868
1103
  request.path # "/ejemplo/foo"
869
1104
  request.ip # dirección IP del cliente
870
- request.secure? # falso
1105
+ request.secure? # falso (sería verdadero sobre ssl)
1106
+ request.forwarded? # verdadero (si se está corriendo atrás de un proxy inverso)
871
1107
  requuest.env # hash de entorno directamente entregado por Rack
872
1108
  end
873
1109
 
@@ -888,12 +1124,85 @@ El objeto <tt>request.body</tt> es una instancia de IO o StringIO:
888
1124
  "Hola #{datos['nombre']}!"
889
1125
  end
890
1126
 
1127
+ === Archivos Adjuntos
1128
+
1129
+ Podés usar el método helper +attachment+ para indicarle al navegador que
1130
+ almacene la respuesta en el disco en lugar de mostrarla en pantalla.
1131
+
1132
+ get '/' do
1133
+ attachment
1134
+ "guardalo!"
1135
+ end
1136
+
1137
+ También podés pasarle un nombre de archivo:
1138
+
1139
+ get '/' do
1140
+ attachment "info.txt"
1141
+ "guardalo!"
1142
+ end
1143
+
1144
+ === Buscando los Archivos de las Plantillas
1145
+
1146
+ El helper <tt>find_template</tt> se utiliza para encontrar los archivos de las
1147
+ plantillas que se van a renderizar:
1148
+
1149
+ find_template settings.views, 'foo', Tilt[:haml] do |archivo|
1150
+ puts "podría ser #{archivo}"
1151
+ end
1152
+
1153
+ Si bien esto no es muy útil, lo interesante es que podés sobreescribir este
1154
+ método, y así enganchar tu propio mecanismo de búsqueda. Por ejemplo, para
1155
+ poder utilizar más de un directorio de vistas:
1156
+
1157
+ set :views, ['vistas', 'plantillas']
1158
+
1159
+ helpers do
1160
+ def find_template(views, name, engine, &block)
1161
+ Array(views).each { |v| super(v, name, engine, &block) }
1162
+ end
1163
+ end
1164
+
1165
+ Otro ejemplo consiste en usar directorios diferentes para los distintos motores
1166
+ de renderizado:
1167
+
1168
+ set :views, :sass => 'vistas/sass', :haml => 'plantillas', :defecto => 'vistas'
1169
+
1170
+ helpers do
1171
+ def find_template(views, name, engine, &block)
1172
+ _, folder = views.detect { |k,v| engine == Tilt[k] }
1173
+ folder ||= views[:defecto]
1174
+ super(folder, name, engine, &block)
1175
+ end
1176
+ end
1177
+
1178
+ ¡Es muy fácil convertir estos ejemplos en una extensión y compartirla!.
1179
+
1180
+ Notá que <tt>find_template</tt> no verifica si un archivo existe realmente, sino
1181
+ que llama al bloque que recibe para cada path posible. Esto no representa un
1182
+ problema de rendimiento debido a que +render+ va a usar +break+ ni bien
1183
+ encuentre un archivo que exista. Además, las ubicaciones de las plantillas (y
1184
+ su contenido) se cachean cuando no estás en el modo de desarrollo. Es bueno
1185
+ tener en cuenta lo anteiror si escribís un método medio loco.
1186
+
891
1187
  == Configuración
892
1188
 
893
1189
  Ejecutar una vez, en el inicio, en cualquier entorno:
894
1190
 
895
1191
  configure do
896
- ...
1192
+ # asignando una opción
1193
+ set :opcion, 'valor'
1194
+
1195
+ # asignando varias opciones
1196
+ set :a => 1, :b => 2
1197
+
1198
+ # atajo para `set :opcion, true`
1199
+ enable :opcion
1200
+
1201
+ # atajo para `set :opcion, false`
1202
+ disable :opcion
1203
+
1204
+ # también podés tener configuraciones dinámicas usando bloques
1205
+ set(:css_dir) { File.join(views, 'css') }
897
1206
  end
898
1207
 
899
1208
  Ejecutar únicamente cuando el entorno (la variable de entorno RACK_ENV) es
@@ -909,10 +1218,116 @@ Ejecutar cuando el entorno es <tt>:production</tt> o <tt>:test</tt>:
909
1218
  ...
910
1219
  end
911
1220
 
1221
+ Podés acceder a estas opciones utilizando el método <tt>settings</tt>:
1222
+
1223
+ configure do
1224
+ set :foo, 'bar'
1225
+ end
1226
+
1227
+ get '/' do
1228
+ settings.foo? # => true
1229
+ settings.foo # => 'bar'
1230
+ ...
1231
+ end
1232
+
1233
+ === Configuraciones Disponibles
1234
+
1235
+ [absolute_redirects] si está deshabilitada, Sinatra va a permitir redirecciones
1236
+ relativas, sin embargo, como consecuencia de esto, va a
1237
+ dejar de cumplir con el RFC 2616 (HTTP 1.1), que solamente
1238
+ permite redirecciones absolutas.
1239
+
1240
+ Activalo si tu apliación está corriendo atrás de un proxy
1241
+ inverso que no se ha configurado adecuadamente. Notá que
1242
+ el helper +url+ va a seguir produciendo URLs absolutas, a
1243
+ menos que le pasés +false+ como segundo parámetro.
1244
+
1245
+ Deshabilitada por defecto.
1246
+
1247
+ [add_charsets] tipos mime a los que el helper <tt>content_type</tt> les
1248
+ añade automáticamente el charset.
1249
+
1250
+ En general, no deberías asignar directamente esta opción,
1251
+ sino añadirle los charsets que quieras:
1252
+
1253
+ settings.add_charsets << "application/foobar"
1254
+
1255
+ [app_file] archivo principal de la aplicación, se utiliza para
1256
+ detectar la raíz del proyecto, el directorio de las vistas
1257
+ y el público así como las plantillas inline.
1258
+
1259
+ [bind] dirección IP que utilizará el servidor integrado (por
1260
+ defecto: 0.0.0.0).
1261
+
1262
+ [default_encoding] encoding utilizado cuando el mismo se desconoce (por
1263
+ defecto <tt>"utf-8"</tt>).
1264
+
1265
+ [dump_errors] mostrar errores en el log.
1266
+
1267
+ [environment] entorno actual, por defecto toma el valor de
1268
+ <tt>ENV['RACK_ENV']</tt>, o <tt>"development"</tt> si no
1269
+ está disponible.
1270
+
1271
+ [logging] define si se utiliza el logger.
1272
+
1273
+ [lock] coloca un lock alrededor de cada petición, procesando
1274
+ solamente una por proceso.
1275
+
1276
+ Habilitá esta opción si tu aplicación no es thread-safe.
1277
+ Se encuentra deshabilitada por defecto.
1278
+
1279
+ [method_override] utiliza el parámetro <tt>_method</tt> para permtir
1280
+ formularios put/delete en navegadores que no los soportan.
1281
+
1282
+ [port] puerto en el que escuchará el servidor integrado.
1283
+
1284
+ [prefixed_redirects] define si inserta <tt>request.script_name</tt> en las
1285
+ redirecciones cuando no se proporciona un path absoluto.
1286
+ De esta manera, cuando está habilitada,
1287
+ <tt>redirect '/foo'</tt> se comporta de la misma manera
1288
+ que <tt>redirect to('/foo')</tt>. Se encuentra
1289
+ deshabilitada por defecto.
1290
+
1291
+ [public] directorio desde donde se sirven los archivos públicos.
1292
+
1293
+ [reload_templates] define si se recargan las plantillas entre peticiones.
1294
+
1295
+ Se encuentra activado en el entorno de desarrollo y en
1296
+ Ruby 1.8.6 (para compoensar un bug en Ruby que provoca una
1297
+ pérdida de memoria).
1298
+
1299
+ [root] directorio raíz del proyecto.
1300
+
1301
+ [raise_errors] elevar excepciones (detiene la aplicación).
1302
+
1303
+ [run] cuando está habilitada, Sinatra se va a encargar de
1304
+ iniciar el servidor web, no la habilités cuando estés
1305
+ usando rackup o algún otro medio.
1306
+
1307
+ [running] indica si el servidor integrado está ejecutandose, ¡no
1308
+ cambiés esta configuración!.
1309
+
1310
+ [server] servidor, o lista de servidores, para usar como servidor
1311
+ integrado. Por defecto: ['thin', 'mongrel', 'webrick'],
1312
+ el orden establece la prioridad.
1313
+
1314
+ [sessions] habilita sesiones basadas en cookies.
1315
+
1316
+ [show_exceptions] muestra un stack trace en el navegador.
1317
+
1318
+ [static] define si Sinatra debe encargarse de servir archivos
1319
+ estáticos.
1320
+
1321
+ Deshabilitala cuando usés un servidor capaz de hacerlo
1322
+ por sí solo, porque mejorará el rendimiento. Se encuentra
1323
+ habilitada por defecto.
1324
+
1325
+ [views] directorio de las vistas.
1326
+
912
1327
  == Manejo de Errores
913
1328
 
914
1329
  Los manejadores de errores se ejecutan dentro del mismo contexto que las rutas
915
- y los filtros before, lo que significa que podés usar, por ejemplo,
1330
+ y los filtros +before+, lo que significa que podés usar, por ejemplo,
916
1331
  <tt>haml</tt>, <tt>erb</tt>, <tt>halt</tt>, etc.
917
1332
 
918
1333
  === No encontrado <em>(Not Found)</em>
@@ -969,18 +1384,6 @@ O un rango:
969
1384
  Sinatra instala manejadores <tt>not_found</tt> y <tt>error</ttt> especiales
970
1385
  cuando se ejecuta dentro del entorno de desarrollo "development".
971
1386
 
972
- == Tipos Mime
973
-
974
- Cuando usás <tt>send_file</tt> o archivos estáticos tal vez tengas tipos mime
975
- que Sinatra no entiende. Usá +mime_type+ para registrarlos a través de la
976
- extensión de archivo:
977
-
978
- mime_type :foo, 'text/foo'
979
-
980
- También lo podés usar con el ayudante +content_type+:
981
-
982
- content_type :foo
983
-
984
1387
  == Rack Middleware
985
1388
 
986
1389
  Sinatra corre sobre Rack[http://rack.rubyforge.org/], una interfaz minimalista
@@ -1080,7 +1483,7 @@ métodos que los provistos por el DSL de top-level. La mayoría de las
1080
1483
  aplicaciones top-level se pueden convertir en componentes Sinatra::Base con
1081
1484
  dos modificaciones:
1082
1485
 
1083
- * Tu archivo debe requerir +sinatra/base+ en lugar de +sinatra+; de otra
1486
+ * Tu archivo debe requerir <tt>sinatra/base</tt> en lugar de +sinatra+; de otra
1084
1487
  manera, todos los métodos del DSL de sinatra son importados dentro del
1085
1488
  espacio de nombres principal.
1086
1489
  * Poné las rutas, manejadores de errores, filtros y opciones de tu aplicación
@@ -1091,6 +1494,34 @@ desactivadas por defecto, incluyendo el servidor incorporado. Mirá
1091
1494
  {Opciones y Configuraciones}[http://sinatra.github.com/configuration.html]
1092
1495
  para detalles sobre las opciones disponibles y su comportamiento.
1093
1496
 
1497
+ === Estilo Modular vs. Clásico
1498
+
1499
+ Contrariamente a la creencia popular, no hay nada de malo con el estilo clásico.
1500
+ Si se ajusta a tu aplicación, no es necesario que la cambies a una modular.
1501
+
1502
+ Existen tan solo dos desventajas en comparación con el estilo modular:
1503
+
1504
+ * Solamente podés tener una aplicación Sinatra por proceso Ruby - si tenés
1505
+ planificado usar más, cambiá al estilo modular.
1506
+
1507
+ * El estilo clásico contamina Object con métodos delegadores - si tenés
1508
+ planificado empaquetar tu aplicación en una librería/gem, cambiá al estilo
1509
+ modular.
1510
+
1511
+ No hay ninguna razón por la cuál no puedas mezclar los estilos modular y
1512
+ clásico.
1513
+
1514
+ Cuando cambiés de un estilo al otro, tené en cuenta las sutiles diferencias
1515
+ entre sus configuraciones:
1516
+
1517
+ Configuración Clásica Modular
1518
+
1519
+ app_file archivo que carga sinatra nil
1520
+ run $0 == app_file false
1521
+ logging true false
1522
+ method_override true false
1523
+ inline_templates true false
1524
+
1094
1525
  === Sirviendo una Aplicación Modular
1095
1526
 
1096
1527
  Las dos opciones más comunes para iniciar una aplicación modular son, iniciarla
@@ -1195,11 +1626,11 @@ disponibles.
1195
1626
  Cada aplicación Sinatra es una subclase de Sinatra::Base. Si estás usando el
1196
1627
  DSL de top-level (<tt>require 'sinatra'</tt>), entonces esta clase es
1197
1628
  Sinatra::Application, de otra manera es la subclase que creaste explícitamente.
1198
- Al nivel de la clase tenés métodos como `get` o `before`, pero no podés acceder
1199
- a los objetos `request` o `session`, ya que hay una única clase de la
1629
+ Al nivel de la clase tenés métodos como +get+ o +before+, pero no podés acceder
1630
+ a los objetos +request+ o +session+, ya que hay una única clase de la
1200
1631
  aplicación para todas las peticiones.
1201
1632
 
1202
- Las opciones creadas utilizando `set` son métodos al nivel de la clase:
1633
+ Las opciones creadas utilizando +set+ son métodos al nivel de la clase:
1203
1634
 
1204
1635
  class MiApp < Sinatra::Base
1205
1636
  # Ey, estoy en el ámbito de la aplicación!
@@ -1215,21 +1646,21 @@ Tenés la ligadura al ámbito de la aplicación dentro de:
1215
1646
 
1216
1647
  * El cuerpo de la clase de tu aplicación
1217
1648
  * Métodos definidos por extensiones
1218
- * El bloque pasado a `helpers`
1219
- * Procs/bloques usados como el valor para `set`
1649
+ * El bloque pasado a +helpers+
1650
+ * Procs/bloques usados como el valor para +set+
1220
1651
 
1221
1652
  Este ámbito puede alcanzarse de las siguientes maneras:
1222
1653
 
1223
1654
  * A través del objeto pasado a los bloques de configuración (<tt>configure { |c| ...}</tt>)
1224
- * Llamando a `settings` desde dentro del ámbito de la petición
1655
+ * Llamando a +settings+ desde dentro del ámbito de la petición
1225
1656
 
1226
1657
  === Ámbito de Petición/Instancia
1227
1658
 
1228
1659
  Para cada petición entrante, una nueva instancia de la clase de tu aplicación
1229
1660
  es creada y todos los bloques de rutas son ejecutados en ese ámbito. Desde este
1230
- ámbito podés acceder a los objetos `request` y `session` o llamar a los métodos
1231
- de renderización como `erb` o `haml`. Podés acceder al ámbito de la aplicación
1232
- desde el ámbito de la petición utilizando `settings`:
1661
+ ámbito podés acceder a los objetos +request+ y +session+ o llamar a los métodos
1662
+ de renderización como +erb+ o +haml+. Podés acceder al ámbito de la aplicación
1663
+ desde el ámbito de la petición utilizando +settings+:
1233
1664
 
1234
1665
  class MiApp < Sinatra::Base
1235
1666
  # Ey, estoy en el ámbito de la aplicación!
@@ -1259,13 +1690,13 @@ El ámbito de delegación solo reenvía métodos al ámbito de clase. De cualqui
1259
1690
  manera, no se comporta 100% como el ámbito de clase porque no tenés la ligadura
1260
1691
  de la clase: únicamente métodos marcados explícitamente para delegación están
1261
1692
  disponibles y no compartís variables/estado con el ámbito de clase (léase:
1262
- tenés un `self` diferente). Podés agregar delegaciones de método llamando a
1693
+ tenés un +self+ diferente). Podés agregar delegaciones de método llamando a
1263
1694
  <tt>Sinatra::Delegator.delegate :nombre_del_metodo</tt>.
1264
1695
 
1265
1696
  Tenés la ligadura al ámbito de delegación dentro de:
1266
1697
 
1267
1698
  * La ligadura del top-level, si hiciste <tt>require "sinatra"</tt>
1268
- * Un objeto extendido con el mixin `Sinatra::Delegator`
1699
+ * Un objeto extendido con el mixin <tt>Sinatra::Delegator</tt>
1269
1700
 
1270
1701
  Pegale una mirada al código: acá está el
1271
1702
  {Sinatra::Delegator mixin}[http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/base.rb#L1128]
@@ -1286,6 +1717,59 @@ Las opciones son:
1286
1717
  -s # especifica el servidor/manejador rack (thin es usado por defecto)
1287
1718
  -x # activa el mutex lock (está desactivado por defecto)
1288
1719
 
1720
+ == Requerimientos
1721
+
1722
+ Se recomienda instalar Sinatra en Ruby 1.8.7, 1.9.2, JRuby o Rubinius.
1723
+
1724
+ Las siguientes versiones de Ruby son soportadas oficialmente:
1725
+
1726
+ [ Ruby 1.8.6 ]
1727
+ No se recomienda utilizar Sinatra en 1.8.6. Sin embargo, esta versión será
1728
+ soportada oficialmente hasta que se libere Sinatra 1.3.0. RDoc y CoffeeScript
1729
+ no son soportadas por esta versión de Ruby. 1.8.6 contiene una falla
1730
+ importante de pérdida de memoria en su implementación de Hash, que afecta a
1731
+ las versiones de Sinatra anteriores a 1.1.1. La versión actual evita
1732
+ explícitamente esta falla a expensas de una disminución del rendimiento. Por
1733
+ último, Rack >= 1.2 dejó de soportar 1.8.6, por lo que vas a tener que usar
1734
+ alguna versión 1.1.x.
1735
+
1736
+ [ Ruby 1.8.7 ]
1737
+ 1.8.7 es soportado completamente. Sin embargo, si no hay nada que te lo
1738
+ prohíba, te recomendamos que usés 1.9.2 o cambies a JRuby o Rubinius.
1739
+
1740
+ [ Ruby 1.9.2 ]
1741
+ 1.9.2 es soportado y recomendado. Tené en cuenta que Radius y Markaby no
1742
+ son compatibles con 1.9 actualmente. Además, no usés 1.9.2p0, porque produce
1743
+ fallos de segmentación cuando se utiliza Sinatra.
1744
+
1745
+ [ Rubinius ]
1746
+ Rubinius es soportado oficialmente (Rubinius >= 1.2.2), con la excepción de
1747
+ las plantillas Textile.
1748
+
1749
+ [ JRuby ]
1750
+ JRuby es soportado oficialmente (JRuby >= 1.5.6). No se conocen problemas con
1751
+ librerías de plantillas de terceras partes. Sin embargo, si elegís usar
1752
+ JRuby, deberías examinar sus Rack handlers porque el servidor web Thin no es
1753
+ soportado actualmente.
1754
+
1755
+ Siempre le prestamos atención a las nuevas versiones de Ruby.
1756
+
1757
+ Las siguientes implementaciones de Ruby no se encuentran soportadas
1758
+ oficialmente. De cualquier manera, pueden ejecutar Sinatra:
1759
+
1760
+ * Versiones anteriores de JRuby y Rubinius
1761
+ * MacRuby
1762
+ * Maglev
1763
+ * IronRuby
1764
+ * Ruby 1.9.0 y 1.9.1
1765
+
1766
+ No estar soportada oficialmente, significa que si las cosas solamente se rompen
1767
+ ahí y no en una plataforma soportada, asumimos que no es nuestro problema sino
1768
+ el suyo.
1769
+
1770
+ Sinatra debería funcionar en cualquier sistema operativo soportado por la
1771
+ implementación de Ruby elegida.
1772
+
1289
1773
  == A la Vanguardia
1290
1774
 
1291
1775
  Si querés usar el código de Sinatra más reciente, sentite libre de ejecutar
@@ -1326,7 +1810,7 @@ Ahora podés arrancar tu aplicación así:
1326
1810
  === Con Git
1327
1811
 
1328
1812
  Cloná el repositorio localmente y ejecutá tu aplicación, asegurándote que el
1329
- directorio <tt>sinatra/lib</tt> esté en el <tt>LOAD_PATH</tt>:
1813
+ directorio <tt>sinatra/lib</tt> esté en el <tt>$LOAD_PATH</tt>:
1330
1814
 
1331
1815
  cd miapp
1332
1816
  git clone git://github.com/sinatra/sinatra.git