sinatra 1.4.6 → 1.4.7

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.

@@ -3,10 +3,10 @@
3
3
  *Atención: Este documento es una traducción de la versión en inglés y puede estar desactualizado.*
4
4
 
5
5
  Sinatra es un
6
- [DSL](http://es.wikipedia.org/wiki/Lenguaje_específico_del_dominio) para
6
+ [DSL](https://es.wikipedia.org/wiki/Lenguaje_específico_del_dominio) para
7
7
  crear aplicaciones web rápidamente en Ruby con un mínimo esfuerzo:
8
8
 
9
- ``` ruby
9
+ ```ruby
10
10
  # miapp.rb
11
11
  require 'sinatra'
12
12
 
@@ -17,12 +17,12 @@ end
17
17
 
18
18
  Instalar la gema y correr la aplicación con:
19
19
 
20
- ``` shell
20
+ ```shell
21
21
  gem install sinatra
22
22
  ruby miapp.rb
23
23
  ```
24
24
 
25
- Ver en <http://localhost:4567>.
25
+ Ver en [http://localhost:4567](http://localhost:4567).
26
26
 
27
27
  Se recomienda ejecutar `gem install thin`, porque Sinatra lo utilizará si está disponible.
28
28
 
@@ -31,7 +31,7 @@ Se recomienda ejecutar `gem install thin`, porque Sinatra lo utilizará si está
31
31
  En Sinatra, una ruta es un método HTTP junto a un patrón de un URL.
32
32
  Cada ruta está asociada a un bloque:
33
33
 
34
- ``` ruby
34
+ ```ruby
35
35
  get '/' do
36
36
  .. mostrar algo ..
37
37
  end
@@ -72,7 +72,7 @@ que coincide con la petición es escogida.
72
72
  Los patrones de las rutas pueden incluir parámetros nombrados, accesibles a
73
73
  través del hash `params`:
74
74
 
75
- ``` ruby
75
+ ```ruby
76
76
  get '/hola/:nombre' do
77
77
  # coincide con "GET /hola/foo" y "GET /hola/bar"
78
78
  # params['nombre'] es 'foo' o 'bar'
@@ -82,7 +82,7 @@ end
82
82
 
83
83
  También puede acceder a los parámetros nombrados usando parámetros de bloque:
84
84
 
85
- ``` ruby
85
+ ```ruby
86
86
  get '/hola/:nombre' do |n|
87
87
  # coincide con "GET /hola/foo" y "GET /hola/bar"
88
88
  # params['nombre'] es 'foo' o 'bar'
@@ -94,7 +94,7 @@ end
94
94
  Los patrones de ruta también pueden incluir parámetros splat (o wildcard),
95
95
  accesibles a través del arreglo `params['splat']`:
96
96
 
97
- ``` ruby
97
+ ```ruby
98
98
  get '/decir/*/al/*' do
99
99
  # coincide con /decir/hola/al/mundo
100
100
  params['splat'] # => ["hola", "mundo"]
@@ -108,7 +108,7 @@ end
108
108
 
109
109
  O, con parámetros de bloque:
110
110
 
111
- ``` ruby
111
+ ```ruby
112
112
  get '/descargar/*.*' do |path, ext|
113
113
  [path, ext] # => ["path/al/archivo", "xml"]
114
114
  end
@@ -116,7 +116,7 @@ end
116
116
 
117
117
  Rutas con Expresiones Regulares:
118
118
 
119
- ``` ruby
119
+ ```ruby
120
120
  get /\A\/hola\/([\w]+)\z/ do
121
121
  "Hola, #{params['captures'].first}!"
122
122
  end
@@ -124,7 +124,7 @@ end
124
124
 
125
125
  O con un parámetro de bloque:
126
126
 
127
- ``` ruby
127
+ ```ruby
128
128
  get %r{/hola/([\w]+)} do |c|
129
129
  "Hola, #{c}!"
130
130
  end
@@ -132,10 +132,10 @@ end
132
132
 
133
133
  Los patrones de ruta pueden contener parámetros opcionales:
134
134
 
135
- ``` ruby
136
- get '/posts.?:formato?' do
137
- # coincide con "GET /posts" y además admite cualquier extensión, por
138
- # ejemplo, "GET /posts.json", "GET /posts.xml", etc.
135
+ ```ruby
136
+ get '/posts/:formato?' do
137
+ # coincide con "GET /posts/" y además admite cualquier extensión, por
138
+ # ejemplo, "GET /posts/json", "GET /posts/xml", etc.
139
139
  end
140
140
  ```
141
141
 
@@ -148,7 +148,7 @@ antes de que se compare con los de tus rutas.
148
148
  Las rutas pueden incluir una variedad de condiciones de selección, como por
149
149
  ejemplo el user agent:
150
150
 
151
- ``` ruby
151
+ ```ruby
152
152
  get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
153
153
  "Estás usando la versión de Songbird #{params['agent'][0]}"
154
154
  end
@@ -160,7 +160,7 @@ end
160
160
 
161
161
  Otras condiciones disponibles son `host_name` y `provides`:
162
162
 
163
- ``` ruby
163
+ ```ruby
164
164
  get '/', :host_name => /^admin\./ do
165
165
  "Área de Administración, Acceso denegado!"
166
166
  end
@@ -176,7 +176,7 @@ end
176
176
 
177
177
  Puede definir sus propias condiciones fácilmente:
178
178
 
179
- ``` ruby
179
+ ```ruby
180
180
  set(:probabilidad) { |valor| condition { rand <= valor } }
181
181
 
182
182
  get '/gana_un_auto', :probabilidad => 0.1 do
@@ -192,7 +192,7 @@ Si su condición acepta más de un argumento, puede pasarle un arreglo. Al
192
192
  definir la condición, se puede utilizar el operador splat en
193
193
  la lista de parámetros:
194
194
 
195
- ``` ruby
195
+ ```ruby
196
196
  set(:autorizar) do |*roles| # <- mirá el splat
197
197
  condition do
198
198
  unless sesion_iniciada? && roles.any? {|rol| usuario_actual.tiene_rol? rol }
@@ -230,7 +230,7 @@ que represente el cuerpo de una respuesta Rack o un código de estado HTTP:
230
230
 
231
231
  De esa manera, podemos fácilmente implementar un ejemplo de streaming:
232
232
 
233
- ``` ruby
233
+ ```ruby
234
234
  class Stream
235
235
  def each
236
236
  100.times { |i| yield "#{i}\n" }
@@ -246,7 +246,7 @@ Como se mostró anteriormente, Sinatra permite utilizar strings y expresiones
246
246
  regulares para definir las rutas. Sin embargo, la cosa no termina ahí. Podés
247
247
  definir tus propios comparadores muy fácilmente:
248
248
 
249
- ``` ruby
249
+ ```ruby
250
250
  class PatronCualquieraMenos
251
251
  Match = Struct.new(:captures)
252
252
 
@@ -272,7 +272,7 @@ end
272
272
  Tenga en cuenta que el ejemplo anterior es un poco rebuscado. Un resultado
273
273
  similar puede conseguirse más sencillamente:
274
274
 
275
- ``` ruby
275
+ ```ruby
276
276
  get // do
277
277
  pass if request.path_info == "/index"
278
278
  # ...
@@ -281,7 +281,7 @@ end
281
281
 
282
282
  O, usando un lookahead negativo:
283
283
 
284
- ``` ruby
284
+ ```ruby
285
285
  get %r{^(?!/index$)} do
286
286
  # ...
287
287
  end
@@ -293,7 +293,7 @@ Los archivos estáticos son servidos desde el directorio público
293
293
  `./public`. Puede especificar una ubicación diferente ajustando la
294
294
  opción `:public_folder`:
295
295
 
296
- ``` ruby
296
+ ```ruby
297
297
  set :public_folder, File.dirname(__FILE__) + '/estaticos'
298
298
  ```
299
299
 
@@ -309,7 +309,7 @@ Use la configuración `:static_cache_control` para agregar el encabezado
309
309
  Cada lenguaje de plantilla se expone a través de un método de renderizado que
310
310
  lleva su nombre. Estos métodos simplemente devuelven un string:
311
311
 
312
- ``` ruby
312
+ ```ruby
313
313
  get '/' do
314
314
  erb :index
315
315
  end
@@ -320,7 +320,7 @@ Renderiza `views/index.erb`.
320
320
  En lugar del nombre de la plantilla podés proporcionar directamente el
321
321
  contenido de la misma:
322
322
 
323
- ``` ruby
323
+ ```ruby
324
324
  get '/' do
325
325
  codigo = "<%= Time.now %>"
326
326
  erb codigo
@@ -330,7 +330,7 @@ end
330
330
  Los métodos de renderizado, aceptan además un segundo argumento, el hash de
331
331
  opciones:
332
332
 
333
- ``` ruby
333
+ ```ruby
334
334
  get '/' do
335
335
  erb :index, :layout => :post
336
336
  end
@@ -343,7 +343,7 @@ cuando este último archivo exista).
343
343
  Cualquier opción que Sinatra no entienda le será pasada al motor de renderizado
344
344
  de la plantilla:
345
345
 
346
- ``` ruby
346
+ ```ruby
347
347
  get '/' do
348
348
  haml :index, :format => :html5
349
349
  end
@@ -352,7 +352,7 @@ end
352
352
  Además, puede definir las opciones para un lenguaje de plantillas de forma
353
353
  general:
354
354
 
355
- ``` ruby
355
+ ```ruby
356
356
  set :haml, :format => :html5
357
357
 
358
358
  get '/' do
@@ -435,7 +435,7 @@ Algunos lenguajes tienen varias implementaciones. Para especificar que
435
435
  implementación usar (y para ser thread-safe), deberías requerirla antes de
436
436
  usarla:
437
437
 
438
- ``` ruby
438
+ ```ruby
439
439
  require 'rdiscount' # o require 'bluecloth'
440
440
  get('/') { markdown :index }
441
441
  ```
@@ -503,7 +503,7 @@ Además, acepta un bloque con la definición de la plantilla (ver ejemplo).
503
503
  <table>
504
504
  <tr>
505
505
  <td>Dependencias</td>
506
- <td><a href="http://nokogiri.org/" title="nokogiri">nokogiri</a></td>
506
+ <td><a href="http://www.nokogiri.org/" title="nokogiri">nokogiri</a></td>
507
507
  </tr>
508
508
  <tr>
509
509
  <td>Extensiones de Archivo</td>
@@ -556,7 +556,7 @@ Además, acepta un bloque con la definición de la plantilla (ver ejemplo).
556
556
  <table>
557
557
  <tr>
558
558
  <td>Dependencias</td>
559
- <td><a href="http://www.lesscss.org/" title="less">less</a></td>
559
+ <td><a href="http://lesscss.org/" title="less">less</a></td>
560
560
  </tr>
561
561
  <tr>
562
562
  <td>Extensiones de Archivo</td>
@@ -573,7 +573,7 @@ Además, acepta un bloque con la definición de la plantilla (ver ejemplo).
573
573
  <table>
574
574
  <tr>
575
575
  <td>Dependencias</td>
576
- <td><a href="http://www.liquidmarkup.org/" title="liquid">liquid</a></td>
576
+ <td><a href="http://liquidmarkup.org/" title="liquid">liquid</a></td>
577
577
  </tr>
578
578
  <tr>
579
579
  <td>Extensiones de Archivo</td>
@@ -594,7 +594,7 @@ plantilla Liquid, casi siempre va a querer pasarle locales.
594
594
  <tr>
595
595
  <td>Dependencias</td>
596
596
  <td>
597
- <a href="https://github.com/rtomayko/rdiscount" title="RDiscount">RDiscount</a>,
597
+ <a href="https://github.com/davidfstr/rdiscount" title="RDiscount">RDiscount</a>,
598
598
  <a href="https://github.com/vmg/redcarpet" title="RedCarpet">RedCarpet</a>,
599
599
  <a href="http://deveiate.org/projects/BlueCloth" title="BlueCloth">BlueCloth</a>,
600
600
  <a href="http://kramdown.gettalong.org/" title="kramdown">kramdown</a> o
@@ -614,14 +614,14 @@ plantilla Liquid, casi siempre va a querer pasarle locales.
614
614
  No es posible llamar métodos desde markdown, ni pasarle locales. Por lo tanto,
615
615
  generalmente va a usarlo en combinación con otro motor de renderizado:
616
616
 
617
- ``` ruby
617
+ ```ruby
618
618
  erb :resumen, :locals => { :texto => markdown(:introduccion) }
619
619
  ```
620
620
 
621
621
  Tenga en cuenta que también podés llamar al método `markdown` desde otras
622
622
  plantillas:
623
623
 
624
- ``` ruby
624
+ ```ruby
625
625
  %h1 Hola Desde Haml!
626
626
  %p= markdown(:saludos)
627
627
  ```
@@ -650,14 +650,14 @@ layout distinto al de la plantilla pasando la opción `:layout_engine`.
650
650
  No es posible llamar métodos desde textile, ni pasarle locales. Por lo tanto,
651
651
  generalmente vas a usarlo en combinación con otro motor de renderizado:
652
652
 
653
- ``` ruby
653
+ ```ruby
654
654
  erb :resumen, :locals => { :texto => textile(:introduccion) }
655
655
  ```
656
656
 
657
657
  Tené en cuenta que también podés llamar al método `textile` desde otras
658
658
  plantillas:
659
659
 
660
- ``` ruby
660
+ ```ruby
661
661
  %h1 Hola Desde Haml!
662
662
  %p= textile(:saludos)
663
663
  ```
@@ -686,14 +686,14 @@ layout distinto al de la plantilla pasando la opción `:layout_engine`.
686
686
  No es posible llamar métodos desde rdoc, ni pasarle locales. Por lo tanto,
687
687
  generalmente vas a usarlo en combinación con otro motor de renderizado:
688
688
 
689
- ``` ruby
689
+ ```ruby
690
690
  erb :resumen, :locals => { :texto => rdoc(:introduccion) }
691
691
  ```
692
692
 
693
693
  Tené en cuenta que también podés llamar al método `rdoc` desde otras
694
694
  plantillas:
695
695
 
696
- ``` ruby
696
+ ```ruby
697
697
  %h1 Hola Desde Haml!
698
698
  %p= rdoc(:saludos)
699
699
  ```
@@ -727,7 +727,7 @@ plantilla Radius, casi siempre se necesita pasar locales.
727
727
  <table>
728
728
  <tr>
729
729
  <td>Dependencias</td>
730
- <td><a href="http://markaby.github.com/" title="Markaby">Markaby</a></td>
730
+ <td><a href="http://markaby.github.io/" title="Markaby">Markaby</a></td>
731
731
  </tr>
732
732
  <tr>
733
733
  <td>Extensiones de Archivo</td>
@@ -795,14 +795,14 @@ Además, acepta un bloque con la definición de la plantilla (ver ejemplo).
795
795
  No es posible llamar métodos desde creole, ni pasarle locales. Por lo tanto,
796
796
  generalmente va a usarlo en combinación con otro motor de renderizado:
797
797
 
798
- ``` ruby
798
+ ```ruby
799
799
  erb :resumen, :locals => { :texto => cerole(:introduccion) }
800
800
  ```
801
801
 
802
802
  Debe tomar en cuenta que también puede llamar al método `creole` desde otras
803
803
  plantillas:
804
804
 
805
- ``` ruby
805
+ ```ruby
806
806
  %h1 Hola Desde Haml!
807
807
  %p= creole(:saludos)
808
808
  ```
@@ -841,7 +841,7 @@ distinto al de la plantilla pasando la opción `:layout_engine`.
841
841
  <tr>
842
842
  <td>Dependencias</td>
843
843
  <td>
844
- <a href="https://github.com/lucasmazza/ruby-stylus" title="Ruby Stylus">
844
+ <a href="https://github.com/forgecrafted/ruby-stylus" title="Ruby Stylus">
845
845
  Stylus
846
846
  </a> y un
847
847
  <a href="https://github.com/sstephenson/execjs/blob/master/README.md#readme" title="ExecJS">
@@ -885,14 +885,14 @@ distinto al de la plantilla pasando la opción `:layout_engine`.
885
885
 
886
886
  El contenido de la plantilla se evalúa como código Ruby, y la variable `json` es convertida a JSON mediante `#to_json`.
887
887
 
888
- ``` ruby
888
+ ```ruby
889
889
  json = { :foo => 'bar' }
890
890
  json[:baz] = key
891
891
  ```
892
892
 
893
893
  Las opciones `:callback` y `:variable` se pueden utilizar para decorar el objeto renderizado:
894
894
 
895
- ``` ruby
895
+ ```ruby
896
896
  var resource = {"foo":"bar","baz":"qux"}; present(resource);
897
897
  ```
898
898
 
@@ -918,7 +918,7 @@ plantilla WLang, casi siempre vas a querer pasarle locales.
918
918
 
919
919
  ### Plantillas Embebidas
920
920
 
921
- ``` ruby
921
+ ```ruby
922
922
  get '/' do
923
923
  haml '%div.titulo Hola Mundo'
924
924
  end
@@ -932,7 +932,7 @@ Las plantillas son evaluadas dentro del mismo contexto que los manejadores de
932
932
  ruta. Las variables de instancia asignadas en los manejadores de ruta son
933
933
  accesibles directamente por las plantillas:
934
934
 
935
- ``` ruby
935
+ ```ruby
936
936
  get '/:id' do
937
937
  @foo = Foo.find(params['id'])
938
938
  haml '%h1= @foo.nombre'
@@ -941,7 +941,7 @@ end
941
941
 
942
942
  O es posible especificar un Hash de variables locales explícitamente:
943
943
 
944
- ``` ruby
944
+ ```ruby
945
945
  get '/:id' do
946
946
  foo = Foo.find(params['id'])
947
947
  haml '%h1= bar.nombre', :locals => { :bar => foo }
@@ -955,7 +955,7 @@ adentro de otras plantillas.
955
955
 
956
956
  Las plantillas pueden ser definidas al final del archivo fuente:
957
957
 
958
- ``` ruby
958
+ ```ruby
959
959
  require 'rubygems'
960
960
  require 'sinatra'
961
961
 
@@ -983,7 +983,7 @@ archivos fuente.
983
983
  Las plantillas también pueden ser definidas usando el método top-level
984
984
  `template`:
985
985
 
986
- ``` ruby
986
+ ```ruby
987
987
  template :layout do
988
988
  "%html\n =yield\n"
989
989
  end
@@ -1002,7 +1002,7 @@ una plantilla es renderizada. Podés desactivar los layouts individualmente
1002
1002
  pasando `:layout => false` o globalmente con
1003
1003
  `set :haml, :layout => false`:
1004
1004
 
1005
- ``` ruby
1005
+ ```ruby
1006
1006
  get '/' do
1007
1007
  haml :index, :layout => !request.xhr?
1008
1008
  end
@@ -1014,7 +1014,7 @@ Para asociar una extensión de archivo con un motor de renderizado, usá
1014
1014
  `Tilt.register`. Por ejemplo, si querés usar la extensión `tt` para
1015
1015
  las plantillas Textile, podés hacer lo siguiente:
1016
1016
 
1017
- ``` ruby
1017
+ ```ruby
1018
1018
  Tilt.register :tt, Tilt[:textile]
1019
1019
  ```
1020
1020
 
@@ -1022,7 +1022,7 @@ Tilt.register :tt, Tilt[:textile]
1022
1022
 
1023
1023
  Primero, registrá tu motor con Tilt, y después, creá tu método de renderizado:
1024
1024
 
1025
- ``` ruby
1025
+ ```ruby
1026
1026
  Tilt.register :mipg, MiMotorParaPlantillaGenial
1027
1027
 
1028
1028
  helpers do
@@ -1044,7 +1044,7 @@ contexto que las rutas. Pueden modificar la petición y la respuesta. Las
1044
1044
  variables de instancia asignadas en los filtros son accesibles por las rutas y
1045
1045
  las plantillas:
1046
1046
 
1047
- ``` ruby
1047
+ ```ruby
1048
1048
  before do
1049
1049
  @nota = 'Hey!'
1050
1050
  request.path_info = '/foo/bar/baz'
@@ -1061,7 +1061,7 @@ contexto y también pueden modificar la petición y la respuesta. Las variables
1061
1061
  de instancia asignadas en los filtros `before` y en las rutas son accesibles por
1062
1062
  los filtros `after`:
1063
1063
 
1064
- ``` ruby
1064
+ ```ruby
1065
1065
  after do
1066
1066
  puts response.status
1067
1067
  end
@@ -1075,7 +1075,7 @@ Los filtros aceptan un patrón opcional, que cuando está presente causa que los
1075
1075
  mismos sean evaluados únicamente si el path de la petición coincide con ese
1076
1076
  patrón:
1077
1077
 
1078
- ``` ruby
1078
+ ```ruby
1079
1079
  before '/protegido/*' do
1080
1080
  autenticar!
1081
1081
  end
@@ -1087,7 +1087,7 @@ end
1087
1087
 
1088
1088
  Al igual que las rutas, los filtros también pueden aceptar condiciones:
1089
1089
 
1090
- ``` ruby
1090
+ ```ruby
1091
1091
  before :agent => /Songbird/ do
1092
1092
  # ...
1093
1093
  end
@@ -1102,7 +1102,7 @@ end
1102
1102
  Usá el método top-level *helpers* para definir métodos ayudantes que
1103
1103
  pueden ser utilizados dentro de los manejadores de rutas y las plantillas:
1104
1104
 
1105
- ``` ruby
1105
+ ```ruby
1106
1106
  helpers do
1107
1107
  def bar(nombre)
1108
1108
  "#{nombre}bar"
@@ -1117,7 +1117,7 @@ end
1117
1117
  Por cuestiones organizativas, puede resultar conveniente organizar los métodos
1118
1118
  ayudantes en distintos módulos:
1119
1119
 
1120
- ``` ruby
1120
+ ```ruby
1121
1121
  module FooUtils
1122
1122
  def foo(nombre) "#{nombre}foo" end
1123
1123
  end
@@ -1137,7 +1137,7 @@ incluir los módulos en la clase de la aplicación.
1137
1137
  Una sesión es usada para mantener el estado a través de distintas peticiones.
1138
1138
  Cuando están activadas, proporciona un hash de sesión para cada sesión de usuario:
1139
1139
 
1140
- ``` ruby
1140
+ ```ruby
1141
1141
  enable :sessions
1142
1142
 
1143
1143
  get '/' do
@@ -1155,7 +1155,7 @@ el tráfico, por citar un ejemplo). Podés usar cualquier middleware Rack para
1155
1155
  manejar sesiones, de la misma manera que usarías cualquier otro middleware,
1156
1156
  pero con la salvedad de que *no* tenés que llamar a `enable :sessions`:
1157
1157
 
1158
- ``` ruby
1158
+ ```ruby
1159
1159
  use Rack::Session::Pool, :expire_after => 2592000
1160
1160
 
1161
1161
  get '/' do
@@ -1174,14 +1174,14 @@ tener en cuenta que cada vez que inicies la aplicación se va a generar
1174
1174
  uno nuevo. Así, si querés que todas las instancias de tu aplicación
1175
1175
  compartan un único secreto, tenés que definirlo vos:
1176
1176
 
1177
- ``` ruby
1177
+ ```ruby
1178
1178
  set :session_secret, 'super secreto'
1179
1179
  ```
1180
1180
 
1181
1181
  Si necesitás una configuración más específica, `sessions` acepta un
1182
1182
  Hash con opciones:
1183
1183
 
1184
- ``` ruby
1184
+ ```ruby
1185
1185
  set :sessions, :domain => 'foo.com'
1186
1186
  ```
1187
1187
 
@@ -1189,37 +1189,37 @@ set :sessions, :domain => 'foo.com'
1189
1189
 
1190
1190
  Para detener inmediatamente una petición dentro de un filtro o una ruta usá:
1191
1191
 
1192
- ``` ruby
1192
+ ```ruby
1193
1193
  halt
1194
1194
  ```
1195
1195
 
1196
1196
  También podés especificar el estado:
1197
1197
 
1198
- ``` ruby
1198
+ ```ruby
1199
1199
  halt 410
1200
1200
  ```
1201
1201
 
1202
1202
  O el cuerpo:
1203
1203
 
1204
- ``` ruby
1204
+ ```ruby
1205
1205
  halt 'esto va a ser el cuerpo'
1206
1206
  ```
1207
1207
 
1208
1208
  O los dos:
1209
1209
 
1210
- ``` ruby
1210
+ ```ruby
1211
1211
  halt 401, 'salí de acá!'
1212
1212
  ```
1213
1213
 
1214
1214
  Con cabeceras:
1215
1215
 
1216
- ``` ruby
1216
+ ```ruby
1217
1217
  halt 402, { 'Content-Type' => 'text/plain' }, 'venganza'
1218
1218
  ```
1219
1219
 
1220
1220
  Obviamente, es posible utilizar `halt` con una plantilla:
1221
1221
 
1222
- ``` ruby
1222
+ ```ruby
1223
1223
  halt erb(:error)
1224
1224
  ```
1225
1225
 
@@ -1228,7 +1228,7 @@ halt erb(:error)
1228
1228
  Una ruta puede pasarle el procesamiento a la siguiente ruta que coincida con
1229
1229
  la petición usando `pass`:
1230
1230
 
1231
- ``` ruby
1231
+ ```ruby
1232
1232
  get '/adivina/:quien' do
1233
1233
  pass unless params['quien'] == 'Franco'
1234
1234
  'Adivinaste!'
@@ -1247,7 +1247,7 @@ siguiente ruta que coincida. Si no coincide ninguna ruta, se devuelve 404.
1247
1247
  Cuando querés obtener el resultado de la llamada a una ruta, `pass` no te va a
1248
1248
  servir. Para lograr esto, podés usar `call`:
1249
1249
 
1250
- ``` ruby
1250
+ ```ruby
1251
1251
  get '/foo' do
1252
1252
  status, headers, body = call env.merge("PATH_INFO" => '/bar')
1253
1253
  [status, headers, body.map(&:upcase)]
@@ -1276,7 +1276,7 @@ escenarios, puede que sea conveniente asignar el cuerpo en un punto arbitrario
1276
1276
  del flujo de ejecución con el método `body`. A partir de ahí, podés usar ese
1277
1277
  mismo método para acceder al cuerpo de la respuesta:
1278
1278
 
1279
- ``` ruby
1279
+ ```ruby
1280
1280
  get '/foo' do
1281
1281
  body "bar"
1282
1282
  end
@@ -1291,7 +1291,7 @@ handler (podés usar esto para implementar streaming, mirá "Valores de retorno"
1291
1291
 
1292
1292
  De manera similar, también podés asignar el código de estado y encabezados:
1293
1293
 
1294
- ``` ruby
1294
+ ```ruby
1295
1295
  get '/foo' do
1296
1296
  status 418
1297
1297
  headers \
@@ -1311,7 +1311,7 @@ terminaste de generar su cuerpo. También es posible que, en algunos casos,
1311
1311
  quieras seguir enviando información hasta que el cliente cierre la conexión.
1312
1312
  Cuando esto ocurra, el helper `stream` te va a ser de gran ayuda:
1313
1313
 
1314
- ``` ruby
1314
+ ```ruby
1315
1315
  get '/' do
1316
1316
  stream do |out|
1317
1317
  out << "Esto va a ser legen -\n"
@@ -1324,17 +1324,17 @@ end
1324
1324
  ```
1325
1325
 
1326
1326
  Podés implementar APIs de streaming,
1327
- [Server-Sent Events](http://dev.w3.org/html5/eventsource/) y puede ser usado
1328
- como base para [WebSockets](http://es.wikipedia.org/wiki/WebSockets). También
1327
+ [Server-Sent Events](https://w3c.github.io/eventsource/) y puede ser usado
1328
+ como base para [WebSockets](https://es.wikipedia.org/wiki/WebSockets). También
1329
1329
  puede ser usado para incrementar el throughput si solo una parte del contenido
1330
1330
  depende de un recurso lento.
1331
1331
 
1332
1332
  Hay que tener en cuenta que el comportamiento del streaming, especialmente el
1333
1333
  número de peticiones concurrentes, depende del servidor web utilizado para
1334
- alojar la aplicación. Puede que algunos servidores, como es el caso de
1335
- WEBRick, no soporten streaming directamente, así el cuerpo de la respuesta será
1336
- enviado completamente de una vez cuando el bloque pasado a `stream` finalice su
1337
- ejecución. Si estás usando Shotgun, el streaming no va a funcionar.
1334
+ alojar la aplicación. Puede que algunos servidores no soporten streaming
1335
+ directamente, así el cuerpo de la respuesta será enviado completamente de una
1336
+ vez cuando el bloque pasado a `stream` finalice su ejecución. Si estás usando
1337
+ Shotgun, el streaming no va a funcionar.
1338
1338
 
1339
1339
  Cuando se pasa `keep_open` como parámetro, no se va a enviar el mensaje
1340
1340
  `close` al objeto de stream. Queda en vos cerrarlo en el punto de ejecución
@@ -1342,7 +1342,7 @@ que quieras. Nuevamente, hay que tener en cuenta que este comportamiento es
1342
1342
  posible solo en servidores que soporten eventos, como Thin o Rainbows. El
1343
1343
  resto de los servidores van a cerrar el stream de todos modos:
1344
1344
 
1345
- ``` ruby
1345
+ ```ruby
1346
1346
  set :server, :thin
1347
1347
  conexiones = []
1348
1348
 
@@ -1363,7 +1363,7 @@ end
1363
1363
  En el ámbito de la petición, el helper `logger` (registrador) expone
1364
1364
  una instancia de `Logger`:
1365
1365
 
1366
- ``` ruby
1366
+ ```ruby
1367
1367
  get '/' do
1368
1368
  logger.info "cargando datos"
1369
1369
  # ...
@@ -1379,7 +1379,7 @@ Tené en cuenta que el logueo está habilitado por defecto únicamente
1379
1379
  para `Sinatra::Application`. Si heredaste de
1380
1380
  `Sinatra::Base`, probablemente quieras habilitarlo manualmente:
1381
1381
 
1382
- ``` ruby
1382
+ ```ruby
1383
1383
  class MiApp < Sinatra::Base
1384
1384
  configure :production, :development do
1385
1385
  enable :logging
@@ -1398,7 +1398,7 @@ Cuando usás `send_file` o archivos estáticos tal vez tengas tipos mime
1398
1398
  que Sinatra no entiende. Usá `mime_type` para registrarlos a través de la
1399
1399
  extensión de archivo:
1400
1400
 
1401
- ``` ruby
1401
+ ```ruby
1402
1402
  configure do
1403
1403
  mime_type :foo, 'text/foo'
1404
1404
  end
@@ -1406,7 +1406,7 @@ end
1406
1406
 
1407
1407
  También lo podés usar con el ayudante `content_type`:
1408
1408
 
1409
- ``` ruby
1409
+ ```ruby
1410
1410
  get '/' do
1411
1411
  content_type :foo
1412
1412
  "foo foo foo"
@@ -1417,7 +1417,7 @@ end
1417
1417
 
1418
1418
  Para generar URLs deberías usar el método `url`. Por ejemplo, en Haml:
1419
1419
 
1420
- ``` ruby
1420
+ ```ruby
1421
1421
  %a{:href => url('/foo')} foo
1422
1422
  ```
1423
1423
 
@@ -1430,7 +1430,7 @@ a continuación).
1430
1430
 
1431
1431
  Podés redireccionar al navegador con el método `redirect`:
1432
1432
 
1433
- ``` ruby
1433
+ ```ruby
1434
1434
  get '/foo' do
1435
1435
  redirect to('/bar')
1436
1436
  end
@@ -1439,15 +1439,15 @@ end
1439
1439
  Cualquier parámetro adicional se utiliza de la misma manera que los argumentos
1440
1440
  pasados a `halt`:
1441
1441
 
1442
- ``` ruby
1442
+ ```ruby
1443
1443
  redirect to('/bar'), 303
1444
- redirect 'http://google.com', 'te confundiste de lugar, compañero'
1444
+ redirect 'http://www.google.com/', 'te confundiste de lugar, compañero'
1445
1445
  ```
1446
1446
 
1447
1447
  También podés redireccionar fácilmente de vuelta hacia la página desde donde
1448
1448
  vino el usuario con `redirect back`:
1449
1449
 
1450
- ``` ruby
1450
+ ```ruby
1451
1451
  get '/foo' do
1452
1452
  "<a href='/bar'>hacer algo</a>"
1453
1453
  end
@@ -1461,13 +1461,13 @@ end
1461
1461
  Para pasar argumentos con una redirección, podés agregarlos a la cadena de
1462
1462
  búsqueda:
1463
1463
 
1464
- ``` ruby
1464
+ ```ruby
1465
1465
  redirect to('/bar?suma=42')
1466
1466
  ```
1467
1467
 
1468
1468
  O usar una sesión:
1469
1469
 
1470
- ``` ruby
1470
+ ```ruby
1471
1471
  enable :sessions
1472
1472
 
1473
1473
  get '/foo' do
@@ -1487,7 +1487,7 @@ HTTP correcto.
1487
1487
 
1488
1488
  Podés asignar el encabezado Cache-Control fácilmente:
1489
1489
 
1490
- ``` ruby
1490
+ ```ruby
1491
1491
  get '/' do
1492
1492
  cache_control :public
1493
1493
  "cachealo!"
@@ -1496,7 +1496,7 @@ end
1496
1496
 
1497
1497
  Pro tip: configurar el cacheo en un filtro `before`:
1498
1498
 
1499
- ``` ruby
1499
+ ```ruby
1500
1500
  before do
1501
1501
  cache_control :public, :must_revalidate, :max_age => 60
1502
1502
  end
@@ -1505,7 +1505,7 @@ end
1505
1505
  Si estás usando el helper `expires` para definir el encabezado correspondiente,
1506
1506
  `Cache-Control` se va a definir automáticamente:
1507
1507
 
1508
- ``` ruby
1508
+ ```ruby
1509
1509
  before do
1510
1510
  expires 500, :public, :must_revalidate
1511
1511
  end
@@ -1516,7 +1516,7 @@ Para usar cachés adecuadamente, deberías considerar usar `etag` o
1516
1516
  cualquier trabajo pesado, ya que van a enviar la respuesta inmediatamente si
1517
1517
  el cliente ya tiene la versión actual en su caché:
1518
1518
 
1519
- ``` ruby
1519
+ ```ruby
1520
1520
  get '/articulo/:id' do
1521
1521
  @articulo = Articulo.find params['id']
1522
1522
  last_modified @articulo.updated_at
@@ -1526,9 +1526,9 @@ end
1526
1526
  ```
1527
1527
 
1528
1528
  También es posible usar una
1529
- [weak ETag](http://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation):
1529
+ [weak ETag](https://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation):
1530
1530
 
1531
- ``` ruby
1531
+ ```ruby
1532
1532
  etag @articulo.sha1, :weak
1533
1533
  ```
1534
1534
 
@@ -1537,7 +1537,7 @@ información necesaria para poder hacerlo. Si estás buscando soluciones rápida
1537
1537
  de cacheo con proxys reversos, mirá
1538
1538
  [rack-cache](https://github.com/rtomayko/rack-cache):
1539
1539
 
1540
- ``` ruby
1540
+ ```ruby
1541
1541
  require "rack/cache"
1542
1542
  require "sinatra"
1543
1543
 
@@ -1561,7 +1561,7 @@ y potentes (como put) que el recurso existe, mientras que para el resto
1561
1561
  (como post) asume que no. Podés cambiar este comportamiento con la opción
1562
1562
  `:new_resource`:
1563
1563
 
1564
- ``` ruby
1564
+ ```ruby
1565
1565
  get '/crear' do
1566
1566
  etag '', :new_resource => true
1567
1567
  Articulo.create
@@ -1571,7 +1571,7 @@ end
1571
1571
 
1572
1572
  Si querés seguir usando una weak ETag, indicalo con la opción `:kind`:
1573
1573
 
1574
- ``` ruby
1574
+ ```ruby
1575
1575
  etag '', :new_resource => true, :kind => :weak
1576
1576
  ```
1577
1577
 
@@ -1579,7 +1579,7 @@ etag '', :new_resource => true, :kind => :weak
1579
1579
 
1580
1580
  Para enviar archivos, podés usar el método `send_file`:
1581
1581
 
1582
- ``` ruby
1582
+ ```ruby
1583
1583
  get '/' do
1584
1584
  send_file 'foo.png'
1585
1585
  end
@@ -1587,7 +1587,7 @@ end
1587
1587
 
1588
1588
  Además acepta un par de opciones:
1589
1589
 
1590
- ``` ruby
1590
+ ```ruby
1591
1591
  send_file 'foo.png', :type => :jpg
1592
1592
  ```
1593
1593
 
@@ -1625,7 +1625,7 @@ El objeto de la petición entrante puede ser accedido desde el nivel de la
1625
1625
  petición (filtros, rutas y manejadores de errores) a través del método
1626
1626
  `request`:
1627
1627
 
1628
- ``` ruby
1628
+ ```ruby
1629
1629
  # app corriendo en http://ejemplo.com/ejemplo
1630
1630
  get '/foo' do
1631
1631
  t = %w[text/css text/html application/javascript]
@@ -1661,7 +1661,7 @@ end
1661
1661
  Algunas opciones, como `script_name` o `path_info` pueden
1662
1662
  también ser escritas:
1663
1663
 
1664
- ``` ruby
1664
+ ```ruby
1665
1665
  before { request.path_info = "/" }
1666
1666
 
1667
1667
  get "/" do
@@ -1671,7 +1671,7 @@ end
1671
1671
 
1672
1672
  El objeto `request.body` es una instancia de IO o StringIO:
1673
1673
 
1674
- ``` ruby
1674
+ ```ruby
1675
1675
  post "/api" do
1676
1676
  request.body.rewind # en caso de que alguien ya lo haya leído
1677
1677
  datos = JSON.parse request.body.read
@@ -1684,7 +1684,7 @@ end
1684
1684
  Podés usar el helper `attachment` para indicarle al navegador que
1685
1685
  almacene la respuesta en el disco en lugar de mostrarla en pantalla:
1686
1686
 
1687
- ``` ruby
1687
+ ```ruby
1688
1688
  get '/' do
1689
1689
  attachment
1690
1690
  "guardalo!"
@@ -1693,7 +1693,7 @@ end
1693
1693
 
1694
1694
  También podés pasarle un nombre de archivo:
1695
1695
 
1696
- ``` ruby
1696
+ ```ruby
1697
1697
  get '/' do
1698
1698
  attachment "info.txt"
1699
1699
  "guardalo!"
@@ -1707,7 +1707,7 @@ a partir del valor que recibe como argumento. Este valor puede ser un
1707
1707
  `String`, pero también es capaz de convertir objetos `DateTime`, `Date` y de
1708
1708
  otras clases similares:
1709
1709
 
1710
- ``` ruby
1710
+ ```ruby
1711
1711
  get '/' do
1712
1712
  pass if Time.now > time_for('Dec 23, 2012')
1713
1713
  "todavía hay tiempo"
@@ -1718,7 +1718,7 @@ Este método es usado internamente por métodos como `expires` y `last_modified`
1718
1718
  entre otros. Por lo tanto, es posible extender el comportamiento de estos
1719
1719
  métodos sobreescribiendo `time_for` en tu aplicación:
1720
1720
 
1721
- ``` ruby
1721
+ ```ruby
1722
1722
  helpers do
1723
1723
  def time_for(value)
1724
1724
  case value
@@ -1741,7 +1741,7 @@ end
1741
1741
  El helper `find_template` se utiliza para encontrar los archivos de las
1742
1742
  plantillas que se van a renderizar:
1743
1743
 
1744
- ``` ruby
1744
+ ```ruby
1745
1745
  find_template settings.views, 'foo', Tilt[:haml] do |archivo|
1746
1746
  puts "podría ser #{archivo}"
1747
1747
  end
@@ -1751,7 +1751,7 @@ Si bien esto no es muy útil, lo interesante es que podés sobreescribir este
1751
1751
  método, y así enganchar tu propio mecanismo de búsqueda. Por ejemplo, para
1752
1752
  poder utilizar más de un directorio de vistas:
1753
1753
 
1754
- ``` ruby
1754
+ ```ruby
1755
1755
  set :views, ['vistas', 'plantillas']
1756
1756
 
1757
1757
  helpers do
@@ -1764,7 +1764,7 @@ end
1764
1764
  Otro ejemplo consiste en usar directorios diferentes para los distintos motores
1765
1765
  de renderizado:
1766
1766
 
1767
- ``` ruby
1767
+ ```ruby
1768
1768
  set :views, :sass => 'vistas/sass', :haml => 'plantillas', :defecto => 'vistas'
1769
1769
 
1770
1770
  helpers do
@@ -1789,7 +1789,7 @@ tener en cuenta lo anterior si escribís un método extraño.
1789
1789
 
1790
1790
  Ejecutar una vez, en el inicio, en cualquier entorno:
1791
1791
 
1792
- ``` ruby
1792
+ ```ruby
1793
1793
  configure do
1794
1794
  # asignando una opción
1795
1795
  set :opcion, 'valor'
@@ -1811,7 +1811,7 @@ end
1811
1811
  Ejecutar únicamente cuando el entorno (la variable de entorno RACK_ENV) es
1812
1812
  `:production`:
1813
1813
 
1814
- ``` ruby
1814
+ ```ruby
1815
1815
  configure :production do
1816
1816
  ...
1817
1817
  end
@@ -1819,7 +1819,7 @@ end
1819
1819
 
1820
1820
  Ejecutar cuando el entorno es `:production` o `:test`:
1821
1821
 
1822
- ``` ruby
1822
+ ```ruby
1823
1823
  configure :production, :test do
1824
1824
  ...
1825
1825
  end
@@ -1827,7 +1827,7 @@ end
1827
1827
 
1828
1828
  Podés acceder a estas opciones utilizando el método `settings`:
1829
1829
 
1830
- ``` ruby
1830
+ ```ruby
1831
1831
  configure do
1832
1832
  set :foo, 'bar'
1833
1833
  end
@@ -1841,25 +1841,25 @@ end
1841
1841
 
1842
1842
  ### Configurando la Protección de Ataques
1843
1843
 
1844
- Sinatra usa [Rack::Protection](https://github.com/rkh/rack-protection#readme)
1844
+ Sinatra usa [Rack::Protection](https://github.com/sinatra/rack-protection#readme)
1845
1845
  para defender a tu aplicación de los ataques más comunes. Si por algún motivo,
1846
1846
  querés desactivar esta funcionalidad, podés hacerlo como se indica a
1847
1847
  continuación (ten en cuenta que tu aplicación va a quedar expuesta a un
1848
1848
  montón de vulnerabilidades bien conocidas):
1849
1849
 
1850
- ``` ruby
1850
+ ```ruby
1851
1851
  disable :protection
1852
1852
  ```
1853
1853
 
1854
1854
  También es posible desactivar una única capa de defensa:
1855
1855
 
1856
- ``` ruby
1856
+ ```ruby
1857
1857
  set :protection, :except => :path_traversal
1858
1858
  ```
1859
1859
 
1860
1860
  O varias:
1861
1861
 
1862
- ``` ruby
1862
+ ```ruby
1863
1863
  set :protection, :except => [:path_traversal, :session_hijacking]
1864
1864
  ```
1865
1865
 
@@ -2083,7 +2083,7 @@ Para utilizar alguno de los otros entornos puede asignarse el valor
2083
2083
  correspondiente a la variable de entorno `RACK_ENV`, o bien utilizar la opción
2084
2084
  `-e` al ejecutar la aplicación:
2085
2085
 
2086
- ``` shell
2086
+ ```shell
2087
2087
  ruby mi_app.rb -e <ENTORNO>
2088
2088
  ```
2089
2089
 
@@ -2101,7 +2101,7 @@ y los filtros `before`, lo que significa que podés usar, por ejemplo,
2101
2101
  Cuando se eleva una excepción `Sinatra::NotFound`, o el código de
2102
2102
  estado de la respuesta es 404, el manejador `not_found` es invocado:
2103
2103
 
2104
- ``` ruby
2104
+ ```ruby
2105
2105
  not_found do
2106
2106
  'No existo'
2107
2107
  end
@@ -2113,7 +2113,7 @@ El manejador `error` es invocado cada vez que una excepción es elevada
2113
2113
  desde un bloque de ruta o un filtro. El objeto de la excepción se puede
2114
2114
  obtener de la variable Rack `sinatra.error`:
2115
2115
 
2116
- ``` ruby
2116
+ ```ruby
2117
2117
  error do
2118
2118
  'Disculpá, ocurrió un error horrible - ' + env['sinatra.error'].message
2119
2119
  end
@@ -2121,7 +2121,7 @@ end
2121
2121
 
2122
2122
  Errores personalizados:
2123
2123
 
2124
- ``` ruby
2124
+ ```ruby
2125
2125
  error MiErrorPersonalizado do
2126
2126
  'Lo que pasó fue...' + env['sinatra.error'].message
2127
2127
  end
@@ -2129,7 +2129,7 @@ end
2129
2129
 
2130
2130
  Entonces, si pasa esto:
2131
2131
 
2132
- ``` ruby
2132
+ ```ruby
2133
2133
  get '/' do
2134
2134
  raise MiErrorPersonalizado, 'algo malo'
2135
2135
  end
@@ -2141,7 +2141,7 @@ Obtenés esto:
2141
2141
 
2142
2142
  También, podés instalar un manejador de errores para un código de estado:
2143
2143
 
2144
- ``` ruby
2144
+ ```ruby
2145
2145
  error 403 do
2146
2146
  'Acceso prohibido'
2147
2147
  end
@@ -2153,7 +2153,7 @@ end
2153
2153
 
2154
2154
  O un rango:
2155
2155
 
2156
- ``` ruby
2156
+ ```ruby
2157
2157
  error 400..510 do
2158
2158
  'Boom'
2159
2159
  end
@@ -2174,7 +2174,7 @@ proporcionar varios tipos de funcionalidades comunes.
2174
2174
  Sinatra hace muy sencillo construir tuberías de Rack middleware a través del
2175
2175
  método top-level `use`:
2176
2176
 
2177
- ``` ruby
2177
+ ```ruby
2178
2178
  require 'sinatra'
2179
2179
  require 'mi_middleware_personalizado'
2180
2180
 
@@ -2187,11 +2187,11 @@ end
2187
2187
  ```
2188
2188
 
2189
2189
  La semántica de `use` es idéntica a la definida para el DSL
2190
- Rack::Builder[http://rubydoc.info/github/rack/rack/master/Rack/Builder] (más
2190
+ Rack::Builder[http://www.rubydoc.info/github/rack/rack/master/Rack/Builder] (más
2191
2191
  frecuentemente usado en archivos rackup). Por ejemplo, el método `use`
2192
2192
  acepta argumentos múltiples/variables así como bloques:
2193
2193
 
2194
- ``` ruby
2194
+ ```ruby
2195
2195
  use Rack::Auth::Basic do |nombre_de_usuario, password|
2196
2196
  nombre_de_usuario == 'admin' && password == 'secreto'
2197
2197
  end
@@ -2211,9 +2211,9 @@ o en la [Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware).
2211
2211
 
2212
2212
  Las pruebas para las aplicaciones Sinatra pueden ser escritas utilizando
2213
2213
  cualquier framework o librería de pruebas basada en Rack. Se recomienda usar
2214
- [Rack::Test](http://rdoc.info/github/brynary/rack-test/master/frames):
2214
+ [Rack::Test](http://www.rubydoc.info/github/brynary/rack-test/master/frames):
2215
2215
 
2216
- ``` ruby
2216
+ ```ruby
2217
2217
  require 'mi_app_sinatra'
2218
2218
  require 'minitest/autorun'
2219
2219
  require 'rack/test'
@@ -2253,7 +2253,7 @@ asume una configuración apropiada para micro-aplicaciones (por ejemplo, un
2253
2253
  `./views`, logging, página con detalles de excepción, etc.). Ahí es
2254
2254
  donde `Sinatra::Base` entra en el juego:
2255
2255
 
2256
- ``` ruby
2256
+ ```ruby
2257
2257
  require 'sinatra/base'
2258
2258
 
2259
2259
  class MiApp < Sinatra::Base
@@ -2279,7 +2279,7 @@ aplicaciones top-level se pueden convertir en componentes
2279
2279
 
2280
2280
  `Sinatra::Base` es una pizarra en blanco. La mayoría de las opciones están
2281
2281
  desactivadas por defecto, incluyendo el servidor incorporado. Mirá
2282
- [Opciones y Configuraciones](http://sinatra.github.com/configuration.html)
2282
+ [Opciones y Configuraciones](http://www.sinatrarb.com/configuration.html)
2283
2283
  para detalles sobre las opciones disponibles y su comportamiento.
2284
2284
 
2285
2285
  ### Estilo Modular vs. Clásico
@@ -2336,7 +2336,7 @@ de ambos estilos:
2336
2336
  <tr>
2337
2337
  <td>static</td>
2338
2338
  <td>true</td>
2339
- <td>false</td>
2339
+ <td>File.exist?(public_folder)</td>
2340
2340
  </tr>
2341
2341
  </table>
2342
2342
 
@@ -2345,7 +2345,7 @@ de ambos estilos:
2345
2345
  Las dos opciones más comunes para iniciar una aplicación modular son, iniciarla
2346
2346
  activamente con `run!`:
2347
2347
 
2348
- ``` ruby
2348
+ ```ruby
2349
2349
  # mi_app.rb
2350
2350
  require 'sinatra/base'
2351
2351
 
@@ -2359,13 +2359,13 @@ end
2359
2359
 
2360
2360
  Iniciar con:
2361
2361
 
2362
- ``` shell
2362
+ ```shell
2363
2363
  ruby mi_app.rb
2364
2364
  ```
2365
2365
 
2366
2366
  O, con un archivo `config.ru`, que permite usar cualquier handler Rack:
2367
2367
 
2368
- ``` ruby
2368
+ ```ruby
2369
2369
  # config.ru
2370
2370
  require './mi_app'
2371
2371
  run MiApp
@@ -2373,7 +2373,7 @@ run MiApp
2373
2373
 
2374
2374
  Después ejecutar:
2375
2375
 
2376
- ``` shell
2376
+ ```shell
2377
2377
  rackup -p 4567
2378
2378
  ```
2379
2379
 
@@ -2381,7 +2381,7 @@ rackup -p 4567
2381
2381
 
2382
2382
  Escribí el archivo de tu aplicación:
2383
2383
 
2384
- ``` ruby
2384
+ ```ruby
2385
2385
  # app.rb
2386
2386
  require 'sinatra'
2387
2387
 
@@ -2392,7 +2392,7 @@ end
2392
2392
 
2393
2393
  Y el `config.ru` correspondiente:
2394
2394
 
2395
- ``` ruby
2395
+ ```ruby
2396
2396
  require './app'
2397
2397
  run Sinatra::Application
2398
2398
  ```
@@ -2417,7 +2417,7 @@ cualquier aplicación Sinatra puede ser agregada delante de un endpoint Rack
2417
2417
  como middleware. Este endpoint puede ser otra aplicación Sinatra, o cualquier
2418
2418
  aplicación basada en Rack (Rails/Ramaze/Camping/...):
2419
2419
 
2420
- ``` ruby
2420
+ ```ruby
2421
2421
  require 'sinatra/base'
2422
2422
 
2423
2423
  class PantallaDeLogin < Sinatra::Base
@@ -2454,7 +2454,7 @@ Puede que en algunas ocasiones quieras crear nuevas aplicaciones en
2454
2454
  tiempo de ejecución sin tener que asignarlas a una constante. Para
2455
2455
  esto tenés `Sinatra.new`:
2456
2456
 
2457
- ``` ruby
2457
+ ```ruby
2458
2458
  require 'sinatra/base'
2459
2459
  mi_app = Sinatra.new { get('/') { "hola" } }
2460
2460
  mi_app.run!
@@ -2463,7 +2463,7 @@ mi_app.run!
2463
2463
  Acepta como argumento opcional una aplicación desde la que se
2464
2464
  heredará:
2465
2465
 
2466
- ``` ruby
2466
+ ```ruby
2467
2467
  # config.ru
2468
2468
  require 'sinatra/base'
2469
2469
 
@@ -2487,7 +2487,7 @@ testear extensiones Sinatra o para usar Sinatra en tus librerías.
2487
2487
  Por otro lado, hace extremadamente sencillo usar Sinatra como
2488
2488
  middleware:
2489
2489
 
2490
- ``` ruby
2490
+ ```ruby
2491
2491
  require 'sinatra/base'
2492
2492
 
2493
2493
  use Sinatra do
@@ -2513,7 +2513,7 @@ clase de la aplicación para todas las peticiones.
2513
2513
 
2514
2514
  Las opciones creadas utilizando `set` son métodos al nivel de la clase:
2515
2515
 
2516
- ``` ruby
2516
+ ```ruby
2517
2517
  class MiApp < Sinatra::Base
2518
2518
  # Ey, estoy en el ámbito de la aplicación!
2519
2519
  set :foo, 42
@@ -2545,7 +2545,7 @@ es creada y todos los bloques de rutas son ejecutados en ese ámbito. Desde este
2545
2545
  de renderización como `erb` o `haml`. Podés acceder al ámbito de la aplicación
2546
2546
  desde el ámbito de la petición utilizando `settings`:
2547
2547
 
2548
- ``` ruby
2548
+ ```ruby
2549
2549
  class MiApp < Sinatra::Base
2550
2550
  # Ey, estoy en el ámbito de la aplicación!
2551
2551
  get '/definir_ruta/:nombre' do
@@ -2591,7 +2591,7 @@ que [extiende el objeto main](https://github.com/sinatra/sinatra/blob/ca06364/li
2591
2591
 
2592
2592
  Las aplicaciones Sinatra pueden ser ejecutadas directamente:
2593
2593
 
2594
- ``` shell
2594
+ ```shell
2595
2595
  ruby miapp.rb [-h] [-x] [-e ENTORNO] [-p PUERTO] [-o HOST] [-s MANEJADOR]
2596
2596
  ```
2597
2597
 
@@ -2606,6 +2606,41 @@ Las opciones son:
2606
2606
  -x # activa el mutex lock (está desactivado por defecto)
2607
2607
  ```
2608
2608
 
2609
+ ### Multi-threading
2610
+
2611
+ _Basado en [esta respuesta en StackOverflow][so-answer] escrita por Konstantin_
2612
+
2613
+ Sinatra no impone ningún modelo de concurrencia, sino que lo deja en manos del
2614
+ handler Rack que se esté usando (Thin, Puma, WEBrick). Sinatra en sí mismo es
2615
+ thread-safe, así que no hay problema en que el Rack handler use un modelo de
2616
+ concurrencia basado en hilos.
2617
+
2618
+ Esto significa que, cuando estemos arrancando el servidor, tendríamos que
2619
+ especificar la opción adecuada para el handler Rack específico. En este ejemplo
2620
+ vemos cómo arrancar un servidor Thin multihilo:
2621
+
2622
+ ```ruby
2623
+ # app.rb
2624
+
2625
+ require 'sinatra/base'
2626
+
2627
+ class App < Sinatra::Base
2628
+ get '/' do
2629
+ "¡Hola, Mundo!"
2630
+ end
2631
+ end
2632
+
2633
+ App.run!
2634
+ ```
2635
+
2636
+ Para arrancar el servidor, el comando sería:
2637
+
2638
+ ```shell
2639
+ thin --threaded start
2640
+ ```
2641
+
2642
+ [so-answer]: http://stackoverflow.com/questions/6278817/is-sinatra-multi-threaded/6282999#6282999)
2643
+
2609
2644
  ## Versiones de Ruby Soportadas
2610
2645
 
2611
2646
  Las siguientes versiones de Ruby son soportadas oficialmente:
@@ -2688,7 +2723,7 @@ tu aplicación sobre la rama master, en general es bastante estable.
2688
2723
 
2689
2724
  También liberamos prereleases de vez en cuando, así, podés hacer:
2690
2725
 
2691
- ``` shell
2726
+ ```shell
2692
2727
  gem install sinatra --pre
2693
2728
  ```
2694
2729
 
@@ -2697,17 +2732,17 @@ Para obtener algunas de las últimas características.
2697
2732
  ### Con Bundler
2698
2733
 
2699
2734
  Esta es la manera recomendada para ejecutar tu aplicación sobre la última
2700
- versión de Sinatra usando [Bundler](http://gembundler.com/).
2735
+ versión de Sinatra usando [Bundler](http://bundler.io).
2701
2736
 
2702
2737
  Primero, instalá Bundler si no lo hiciste todavía:
2703
2738
 
2704
- ``` shell
2739
+ ```shell
2705
2740
  gem install bundler
2706
2741
  ```
2707
2742
 
2708
2743
  Después, en el directorio de tu proyecto, creá un archivo `Gemfile`:
2709
2744
 
2710
- ``` ruby
2745
+ ```ruby
2711
2746
  source :rubygems
2712
2747
  gem 'sinatra', :git => "git://github.com/sinatra/sinatra.git"
2713
2748
 
@@ -2722,7 +2757,7 @@ porque Bundler las agrega directamente.
2722
2757
 
2723
2758
  Ahora podés arrancar tu aplicación así:
2724
2759
 
2725
- ``` shell
2760
+ ```shell
2726
2761
  bundle exec ruby miapp.rb
2727
2762
  ```
2728
2763
 
@@ -2731,7 +2766,7 @@ bundle exec ruby miapp.rb
2731
2766
  Cloná el repositorio localmente y ejecutá tu aplicación, asegurándote que el
2732
2767
  directorio `sinatra/lib` esté en el `$LOAD_PATH`:
2733
2768
 
2734
- ``` shell
2769
+ ```shell
2735
2770
  cd miapp
2736
2771
  git clone git://github.com/sinatra/sinatra.git
2737
2772
  ruby -Isinatra/lib miapp.rb
@@ -2739,7 +2774,7 @@ ruby -Isinatra/lib miapp.rb
2739
2774
 
2740
2775
  Para actualizar el código fuente de Sinatra en el futuro:
2741
2776
 
2742
- ``` shell
2777
+ ```shell
2743
2778
  cd miapp/sinatra
2744
2779
  git pull
2745
2780
  ```
@@ -2748,7 +2783,7 @@ git pull
2748
2783
 
2749
2784
  Podés construir la gem vos mismo:
2750
2785
 
2751
- ``` shell
2786
+ ```shell
2752
2787
  git clone git://github.com/sinatra/sinatra.git
2753
2788
  cd sinatra
2754
2789
  rake sinatra.gemspec
@@ -2757,7 +2792,7 @@ rake install
2757
2792
 
2758
2793
  Si instalás tus gems como root, el último paso debería ser
2759
2794
 
2760
- ``` shell
2795
+ ```shell
2761
2796
  sudo rake install
2762
2797
  ```
2763
2798
 
@@ -2772,15 +2807,15 @@ siguiendo las especificaciones SemVer y SemVerTag.
2772
2807
  adicional, noticias, y enlaces a otros recursos.
2773
2808
  * [Contribuyendo](http://www.sinatrarb.com/contributing) - ¿Encontraste un
2774
2809
  error?. ¿Necesitás ayuda?. ¿Tenés un parche?.
2775
- * [Seguimiento de problemas](http://github.com/sinatra/sinatra/issues)
2776
- * [Twitter](http://twitter.com/sinatra)
2810
+ * [Seguimiento de problemas](https://github.com/sinatra/sinatra/issues)
2811
+ * [Twitter](https://twitter.com/sinatra)
2777
2812
  * [Lista de Correo](http://groups.google.com/group/sinatrarb/topics)
2778
2813
  * [IRC: #sinatra](irc://chat.freenode.net/#sinatra) en http://freenode.net
2779
2814
  * [Sinatra Book](https://github.com/sinatra/sinatra-book/) Tutorial (en inglés).
2780
2815
  * [Sinatra Recipes](http://recipes.sinatrarb.com/) Recetas contribuidas
2781
2816
  por la comunidad (en inglés).
2782
2817
  * Documentación de la API para la
2783
- [última versión liberada](http://rubydoc.info/gems/sinatra) o para la
2784
- [rama de desarrollo actual](http://rubydoc.info/github/sinatra/sinatra)
2785
- en http://rubydoc.info/
2786
- * [Servidor de CI](http://travis-ci.org/sinatra/sinatra)
2818
+ [última versión liberada](http://www.rubydoc.info/gems/sinatra) o para la
2819
+ [rama de desarrollo actual](http://www.rubydoc.info/github/sinatra/sinatra)
2820
+ en http://www.rubydoc.info/
2821
+ * [Servidor de CI](https://travis-ci.org/sinatra/sinatra)