From d66cfcc451c4536906eb84b1ec38fb3220c8bae0 Mon Sep 17 00:00:00 2001 From: Seiichi Yonezawa Date: Mon, 21 Sep 2015 01:50:57 +0900 Subject: [PATCH] Remove unnecessary whitespaces --- README.de.md | 26 ++--- README.es.md | 272 +++++++++++++++++++++---------------------- README.fr.md | 298 ++++++++++++++++++++++++------------------------ README.ja.md | 282 ++++++++++++++++++++++----------------------- README.ko.md | 296 +++++++++++++++++++++++------------------------ README.md | 292 +++++++++++++++++++++++------------------------ README.pt-br.md | 196 +++++++++++++++---------------- README.pt-pt.md | 110 +++++++++--------- README.ru.md | 8 +- README.zh.md | 250 ++++++++++++++++++++-------------------- 10 files changed, 1015 insertions(+), 1015 deletions(-) diff --git a/README.de.md b/README.de.md index 75fc2aa9..ef0d2325 100644 --- a/README.de.md +++ b/README.de.md @@ -227,7 +227,7 @@ end Routen können auch den query-Parameter verwenden: -``` ruby +```ruby get '/posts' do # matches "GET /posts?title=foo&author=bar" title = params['title'] @@ -527,7 +527,7 @@ Rendering-Methoden rendern jeden String direkt. ### Direkte Templates -``` ruby +```ruby get '/' do haml '%div.title Hallo Welt' end @@ -969,14 +969,14 @@ Da man aus dem Mediawiki-Template heraus keine Ruby-Methoden aufrufen und auch keine locals verwenden kann, wird man Mediawiki üblicherweise in Kombination mit anderen Renderern verwenden wollen: -``` ruby +```ruby erb :overview, :locals => { :text => mediawiki(:introduction) } ``` Beachte: Man kann die `mediawiki`-Methode auch aus anderen Templates heraus aufrufen: -``` ruby +```ruby %h1 Grüße von Haml! %p= mediawiki(:greetings) ``` @@ -1031,7 +1031,7 @@ Templates zu verwenden und einen anderen für das Layout, indem die Um Stylus-Templates ausführen zu können, müssen `stylus` und `stylus/tilt` zuerst geladen werden: -``` ruby +```ruby require 'sinatra' require 'stylus' require 'stylus/tilt' @@ -1068,7 +1068,7 @@ end Die Template-Quelle wird als Ruby-String evaluiert. Die daraus resultierende json Variable wird mit Hilfe von `#to_json` umgewandelt: -``` ruby +```ruby json = { :foo => 'bar' } json[:baz] = key ``` @@ -1076,7 +1076,7 @@ json[:baz] = key Die `:callback` und `:variable` Optionen können mit dem gerenderten Objekt verwendet werden: -``` javascript +```javascript var resource = {"foo":"bar","baz":"qux"}; present(resource); ``` @@ -1134,7 +1134,7 @@ Ein Layout ist üblicherweise ein Template, das ein `yield` aufruft. Ein solches Template kann entweder wie oben beschrieben über die `:template` Option verwendet werden oder mit einem Block gerendert werden: -``` ruby +```ruby erb :post, :layout => false do erb :index end @@ -1145,7 +1145,7 @@ Dieser Code entspricht weitestgehend `erb :index, :layout => :post`. Blöcke an Render-Methoden weiterzugeben ist besonders bei verschachtelten Layouts hilfreich: -``` ruby +```ruby erb :main_layout, :layout => false do erb :admin_layout do erb :user @@ -1155,7 +1155,7 @@ end Der gleiche Effekt kann auch mit weniger Code erreicht werden: -``` ruby +```ruby erb :admin_layout, :layout => :main_layout do erb :user end @@ -1257,7 +1257,7 @@ Tilt zu erfahren. Um einen eigenen Mechanismus zum Aufsuchen von Templates zu implementieren, muss `#find_template` definiert werden: -``` ruby +```ruby configure do set :views [ './views/a', './views/b' ] end @@ -1395,7 +1395,7 @@ set :sessions, :domain => 'foo.com' Um eine Session mit anderen Apps und zwischen verschiedenen Subdomains von foo.com zu teilen, wird ein *.* der Domain vorangestellt: -``` ruby +```ruby set :sessions, :domain => '.foo,com' ``` @@ -2469,7 +2469,7 @@ Details über mögliche Optionen. Damit eine App sich ähnlich wie eine klassische App verhält, kann man auch eine Subclass von `Sinatra::Application` erstellen: -``` ruby +```ruby require 'sinatra/base' class MyApp < Sinatra::Application diff --git a/README.es.md b/README.es.md index 3c901cb6..efd4aa37 100644 --- a/README.es.md +++ b/README.es.md @@ -6,7 +6,7 @@ Sinatra es un [DSL](http://es.wikipedia.org/wiki/Lenguaje_específico_del_dominio) para crear aplicaciones web rápidamente en Ruby con un mínimo esfuerzo: -``` ruby +```ruby # miapp.rb require 'sinatra' @@ -17,7 +17,7 @@ end Instalar la gema y correr la aplicación con: -``` shell +```shell gem install sinatra ruby miapp.rb ``` @@ -31,7 +31,7 @@ Se recomienda ejecutar `gem install thin`, porque Sinatra lo utilizará si está En Sinatra, una ruta es un método HTTP junto a un patrón de un URL. Cada ruta está asociada a un bloque: -``` ruby +```ruby get '/' do .. mostrar algo .. end @@ -72,7 +72,7 @@ que coincide con la petición es escogida. Los patrones de las rutas pueden incluir parámetros nombrados, accesibles a través del hash `params`: -``` ruby +```ruby get '/hola/:nombre' do # coincide con "GET /hola/foo" y "GET /hola/bar" # params['nombre'] es 'foo' o 'bar' @@ -82,7 +82,7 @@ end También puede acceder a los parámetros nombrados usando parámetros de bloque: -``` ruby +```ruby get '/hola/:nombre' do |n| # coincide con "GET /hola/foo" y "GET /hola/bar" # params['nombre'] es 'foo' o 'bar' @@ -94,7 +94,7 @@ end Los patrones de ruta también pueden incluir parámetros splat (o wildcard), accesibles a través del arreglo `params['splat']`: -``` ruby +```ruby get '/decir/*/al/*' do # coincide con /decir/hola/al/mundo params['splat'] # => ["hola", "mundo"] @@ -108,7 +108,7 @@ end O, con parámetros de bloque: -``` ruby +```ruby get '/descargar/*.*' do |path, ext| [path, ext] # => ["path/al/archivo", "xml"] end @@ -116,7 +116,7 @@ end Rutas con Expresiones Regulares: -``` ruby +```ruby get /\A\/hola\/([\w]+)\z/ do "Hola, #{params['captures'].first}!" end @@ -124,7 +124,7 @@ end O con un parámetro de bloque: -``` ruby +```ruby get %r{/hola/([\w]+)} do |c| "Hola, #{c}!" end @@ -132,7 +132,7 @@ end Los patrones de ruta pueden contener parámetros opcionales: -``` ruby +```ruby get '/posts.?:formato?' do # coincide con "GET /posts" y además admite cualquier extensión, por # ejemplo, "GET /posts.json", "GET /posts.xml", etc. @@ -148,7 +148,7 @@ antes de que se compare con los de tus rutas. Las rutas pueden incluir una variedad de condiciones de selección, como por ejemplo el user agent: -``` ruby +```ruby get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do "Estás usando la versión de Songbird #{params['agent'][0]}" end @@ -160,7 +160,7 @@ end Otras condiciones disponibles son `host_name` y `provides`: -``` ruby +```ruby get '/', :host_name => /^admin\./ do "Área de Administración, Acceso denegado!" end @@ -176,7 +176,7 @@ end Puede definir sus propias condiciones fácilmente: -``` ruby +```ruby set(:probabilidad) { |valor| condition { rand <= valor } } 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 definir la condición, se puede utilizar el operador splat en la lista de parámetros: -``` ruby +```ruby set(:autorizar) do |*roles| # <- mirá el splat condition do 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: De esa manera, podemos fácilmente implementar un ejemplo de streaming: -``` ruby +```ruby class Stream def each 100.times { |i| yield "#{i}\n" } @@ -246,7 +246,7 @@ Como se mostró anteriormente, Sinatra permite utilizar strings y expresiones regulares para definir las rutas. Sin embargo, la cosa no termina ahí. Podés definir tus propios comparadores muy fácilmente: -``` ruby +```ruby class PatronCualquieraMenos Match = Struct.new(:captures) @@ -272,7 +272,7 @@ end Tenga en cuenta que el ejemplo anterior es un poco rebuscado. Un resultado similar puede conseguirse más sencillamente: -``` ruby +```ruby get // do pass if request.path_info == "/index" # ... @@ -281,7 +281,7 @@ end O, usando un lookahead negativo: -``` ruby +```ruby get %r{^(?!/index$)} do # ... end @@ -293,7 +293,7 @@ Los archivos estáticos son servidos desde el directorio público `./public`. Puede especificar una ubicación diferente ajustando la opción `:public_folder`: -``` ruby +```ruby set :public_folder, File.dirname(__FILE__) + '/estaticos' ``` @@ -309,7 +309,7 @@ Use la configuración `:static_cache_control` para agregar el encabezado Cada lenguaje de plantilla se expone a través de un método de renderizado que lleva su nombre. Estos métodos simplemente devuelven un string: -``` ruby +```ruby get '/' do erb :index end @@ -320,7 +320,7 @@ Renderiza `views/index.erb`. En lugar del nombre de la plantilla podés proporcionar directamente el contenido de la misma: -``` ruby +```ruby get '/' do codigo = "<%= Time.now %>" erb codigo @@ -330,7 +330,7 @@ end Los métodos de renderizado, aceptan además un segundo argumento, el hash de opciones: -``` ruby +```ruby get '/' do erb :index, :layout => :post end @@ -343,7 +343,7 @@ cuando este último archivo exista). Cualquier opción que Sinatra no entienda le será pasada al motor de renderizado de la plantilla: -``` ruby +```ruby get '/' do haml :index, :format => :html5 end @@ -352,7 +352,7 @@ end Además, puede definir las opciones para un lenguaje de plantillas de forma general: -``` ruby +```ruby set :haml, :format => :html5 get '/' do @@ -435,7 +435,7 @@ Algunos lenguajes tienen varias implementaciones. Para especificar que implementación usar (y para ser thread-safe), deberías requerirla antes de usarla: -``` ruby +```ruby require 'rdiscount' # o require 'bluecloth' get('/') { markdown :index } ``` @@ -614,14 +614,14 @@ plantilla Liquid, casi siempre va a querer pasarle locales. No es posible llamar métodos desde markdown, ni pasarle locales. Por lo tanto, generalmente va a usarlo en combinación con otro motor de renderizado: -``` ruby +```ruby erb :resumen, :locals => { :texto => markdown(:introduccion) } ``` Tenga en cuenta que también podés llamar al método `markdown` desde otras plantillas: -``` ruby +```ruby %h1 Hola Desde Haml! %p= markdown(:saludos) ``` @@ -650,14 +650,14 @@ layout distinto al de la plantilla pasando la opción `:layout_engine`. No es posible llamar métodos desde textile, ni pasarle locales. Por lo tanto, generalmente vas a usarlo en combinación con otro motor de renderizado: -``` ruby +```ruby erb :resumen, :locals => { :texto => textile(:introduccion) } ``` Tené en cuenta que también podés llamar al método `textile` desde otras plantillas: -``` ruby +```ruby %h1 Hola Desde Haml! %p= textile(:saludos) ``` @@ -686,14 +686,14 @@ layout distinto al de la plantilla pasando la opción `:layout_engine`. No es posible llamar métodos desde rdoc, ni pasarle locales. Por lo tanto, generalmente vas a usarlo en combinación con otro motor de renderizado: -``` ruby +```ruby erb :resumen, :locals => { :texto => rdoc(:introduccion) } ``` Tené en cuenta que también podés llamar al método `rdoc` desde otras plantillas: -``` ruby +```ruby %h1 Hola Desde Haml! %p= rdoc(:saludos) ``` @@ -795,14 +795,14 @@ Además, acepta un bloque con la definición de la plantilla (ver ejemplo). No es posible llamar métodos desde creole, ni pasarle locales. Por lo tanto, generalmente va a usarlo en combinación con otro motor de renderizado: -``` ruby +```ruby erb :resumen, :locals => { :texto => cerole(:introduccion) } ``` Debe tomar en cuenta que también puede llamar al método `creole` desde otras plantillas: -``` ruby +```ruby %h1 Hola Desde Haml! %p= creole(:saludos) ``` @@ -885,14 +885,14 @@ distinto al de la plantilla pasando la opción `:layout_engine`. El contenido de la plantilla se evalúa como código Ruby, y la variable `json` es convertida a JSON mediante `#to_json`. -``` ruby +```ruby json = { :foo => 'bar' } json[:baz] = key ``` Las opciones `:callback` y `:variable` se pueden utilizar para decorar el objeto renderizado: -``` ruby +```ruby var resource = {"foo":"bar","baz":"qux"}; present(resource); ``` @@ -918,7 +918,7 @@ plantilla WLang, casi siempre vas a querer pasarle locales. ### Plantillas Embebidas -``` ruby +```ruby get '/' do haml '%div.titulo Hola Mundo' end @@ -932,7 +932,7 @@ Las plantillas son evaluadas dentro del mismo contexto que los manejadores de ruta. Las variables de instancia asignadas en los manejadores de ruta son accesibles directamente por las plantillas: -``` ruby +```ruby get '/:id' do @foo = Foo.find(params['id']) haml '%h1= @foo.nombre' @@ -941,7 +941,7 @@ end O es posible especificar un Hash de variables locales explícitamente: -``` ruby +```ruby get '/:id' do foo = Foo.find(params['id']) haml '%h1= bar.nombre', :locals => { :bar => foo } @@ -955,7 +955,7 @@ adentro de otras plantillas. Las plantillas pueden ser definidas al final del archivo fuente: -``` ruby +```ruby require 'rubygems' require 'sinatra' @@ -983,7 +983,7 @@ archivos fuente. Las plantillas también pueden ser definidas usando el método top-level `template`: -``` ruby +```ruby template :layout do "%html\n =yield\n" end @@ -1002,7 +1002,7 @@ una plantilla es renderizada. Podés desactivar los layouts individualmente pasando `:layout => false` o globalmente con `set :haml, :layout => false`: -``` ruby +```ruby get '/' do haml :index, :layout => !request.xhr? end @@ -1014,7 +1014,7 @@ Para asociar una extensión de archivo con un motor de renderizado, usá `Tilt.register`. Por ejemplo, si querés usar la extensión `tt` para las plantillas Textile, podés hacer lo siguiente: -``` ruby +```ruby Tilt.register :tt, Tilt[:textile] ``` @@ -1022,7 +1022,7 @@ Tilt.register :tt, Tilt[:textile] Primero, registrá tu motor con Tilt, y después, creá tu método de renderizado: -``` ruby +```ruby Tilt.register :mipg, MiMotorParaPlantillaGenial helpers do @@ -1044,7 +1044,7 @@ contexto que las rutas. Pueden modificar la petición y la respuesta. Las variables de instancia asignadas en los filtros son accesibles por las rutas y las plantillas: -``` ruby +```ruby before do @nota = 'Hey!' request.path_info = '/foo/bar/baz' @@ -1061,7 +1061,7 @@ contexto y también pueden modificar la petición y la respuesta. Las variables de instancia asignadas en los filtros `before` y en las rutas son accesibles por los filtros `after`: -``` ruby +```ruby after do puts response.status end @@ -1075,7 +1075,7 @@ Los filtros aceptan un patrón opcional, que cuando está presente causa que los mismos sean evaluados únicamente si el path de la petición coincide con ese patrón: -``` ruby +```ruby before '/protegido/*' do autenticar! end @@ -1087,7 +1087,7 @@ end Al igual que las rutas, los filtros también pueden aceptar condiciones: -``` ruby +```ruby before :agent => /Songbird/ do # ... end @@ -1102,7 +1102,7 @@ end Usá el método top-level *helpers* para definir métodos ayudantes que pueden ser utilizados dentro de los manejadores de rutas y las plantillas: -``` ruby +```ruby helpers do def bar(nombre) "#{nombre}bar" @@ -1117,7 +1117,7 @@ end Por cuestiones organizativas, puede resultar conveniente organizar los métodos ayudantes en distintos módulos: -``` ruby +```ruby module FooUtils def foo(nombre) "#{nombre}foo" end end @@ -1137,7 +1137,7 @@ incluir los módulos en la clase de la aplicación. Una sesión es usada para mantener el estado a través de distintas peticiones. Cuando están activadas, proporciona un hash de sesión para cada sesión de usuario: -``` ruby +```ruby enable :sessions get '/' do @@ -1155,7 +1155,7 @@ el tráfico, por citar un ejemplo). Podés usar cualquier middleware Rack para manejar sesiones, de la misma manera que usarías cualquier otro middleware, pero con la salvedad de que *no* tenés que llamar a `enable :sessions`: -``` ruby +```ruby use Rack::Session::Pool, :expire_after => 2592000 get '/' do @@ -1174,14 +1174,14 @@ tener en cuenta que cada vez que inicies la aplicación se va a generar uno nuevo. Así, si querés que todas las instancias de tu aplicación compartan un único secreto, tenés que definirlo vos: -``` ruby +```ruby set :session_secret, 'super secreto' ``` Si necesitás una configuración más específica, `sessions` acepta un Hash con opciones: -``` ruby +```ruby set :sessions, :domain => 'foo.com' ``` @@ -1189,37 +1189,37 @@ set :sessions, :domain => 'foo.com' Para detener inmediatamente una petición dentro de un filtro o una ruta usá: -``` ruby +```ruby halt ``` También podés especificar el estado: -``` ruby +```ruby halt 410 ``` O el cuerpo: -``` ruby +```ruby halt 'esto va a ser el cuerpo' ``` O los dos: -``` ruby +```ruby halt 401, 'salí de acá!' ``` Con cabeceras: -``` ruby +```ruby halt 402, { 'Content-Type' => 'text/plain' }, 'venganza' ``` Obviamente, es posible utilizar `halt` con una plantilla: -``` ruby +```ruby halt erb(:error) ``` @@ -1228,7 +1228,7 @@ halt erb(:error) Una ruta puede pasarle el procesamiento a la siguiente ruta que coincida con la petición usando `pass`: -``` ruby +```ruby get '/adivina/:quien' do pass unless params['quien'] == 'Franco' 'Adivinaste!' @@ -1247,7 +1247,7 @@ siguiente ruta que coincida. Si no coincide ninguna ruta, se devuelve 404. Cuando querés obtener el resultado de la llamada a una ruta, `pass` no te va a servir. Para lograr esto, podés usar `call`: -``` ruby +```ruby get '/foo' do status, headers, body = call env.merge("PATH_INFO" => '/bar') [status, headers, body.map(&:upcase)] @@ -1276,7 +1276,7 @@ escenarios, puede que sea conveniente asignar el cuerpo en un punto arbitrario del flujo de ejecución con el método `body`. A partir de ahí, podés usar ese mismo método para acceder al cuerpo de la respuesta: -``` ruby +```ruby get '/foo' do body "bar" end @@ -1291,7 +1291,7 @@ handler (podés usar esto para implementar streaming, mirá "Valores de retorno" De manera similar, también podés asignar el código de estado y encabezados: -``` ruby +```ruby get '/foo' do status 418 headers \ @@ -1311,7 +1311,7 @@ terminaste de generar su cuerpo. También es posible que, en algunos casos, quieras seguir enviando información hasta que el cliente cierre la conexión. Cuando esto ocurra, el helper `stream` te va a ser de gran ayuda: -``` ruby +```ruby get '/' do stream do |out| out << "Esto va a ser legen -\n" @@ -1342,7 +1342,7 @@ que quieras. Nuevamente, hay que tener en cuenta que este comportamiento es posible solo en servidores que soporten eventos, como Thin o Rainbows. El resto de los servidores van a cerrar el stream de todos modos: -``` ruby +```ruby set :server, :thin conexiones = [] @@ -1363,7 +1363,7 @@ end En el ámbito de la petición, el helper `logger` (registrador) expone una instancia de `Logger`: -``` ruby +```ruby get '/' do logger.info "cargando datos" # ... @@ -1379,7 +1379,7 @@ Tené en cuenta que el logueo está habilitado por defecto únicamente para `Sinatra::Application`. Si heredaste de `Sinatra::Base`, probablemente quieras habilitarlo manualmente: -``` ruby +```ruby class MiApp < Sinatra::Base configure :production, :development do enable :logging @@ -1398,7 +1398,7 @@ Cuando usás `send_file` o archivos estáticos tal vez tengas tipos mime que Sinatra no entiende. Usá `mime_type` para registrarlos a través de la extensión de archivo: -``` ruby +```ruby configure do mime_type :foo, 'text/foo' end @@ -1406,7 +1406,7 @@ end También lo podés usar con el ayudante `content_type`: -``` ruby +```ruby get '/' do content_type :foo "foo foo foo" @@ -1417,7 +1417,7 @@ end Para generar URLs deberías usar el método `url`. Por ejemplo, en Haml: -``` ruby +```ruby %a{:href => url('/foo')} foo ``` @@ -1430,7 +1430,7 @@ a continuación). Podés redireccionar al navegador con el método `redirect`: -``` ruby +```ruby get '/foo' do redirect to('/bar') end @@ -1439,7 +1439,7 @@ end Cualquier parámetro adicional se utiliza de la misma manera que los argumentos pasados a `halt`: -``` ruby +```ruby redirect to('/bar'), 303 redirect 'http://google.com', 'te confundiste de lugar, compañero' ``` @@ -1447,7 +1447,7 @@ redirect 'http://google.com', 'te confundiste de lugar, compañero' También podés redireccionar fácilmente de vuelta hacia la página desde donde vino el usuario con `redirect back`: -``` ruby +```ruby get '/foo' do "hacer algo" end @@ -1461,13 +1461,13 @@ end Para pasar argumentos con una redirección, podés agregarlos a la cadena de búsqueda: -``` ruby +```ruby redirect to('/bar?suma=42') ``` O usar una sesión: -``` ruby +```ruby enable :sessions get '/foo' do @@ -1487,7 +1487,7 @@ HTTP correcto. Podés asignar el encabezado Cache-Control fácilmente: -``` ruby +```ruby get '/' do cache_control :public "cachealo!" @@ -1496,7 +1496,7 @@ end Pro tip: configurar el cacheo en un filtro `before`: -``` ruby +```ruby before do cache_control :public, :must_revalidate, :max_age => 60 end @@ -1505,7 +1505,7 @@ end Si estás usando el helper `expires` para definir el encabezado correspondiente, `Cache-Control` se va a definir automáticamente: -``` ruby +```ruby before do expires 500, :public, :must_revalidate end @@ -1516,7 +1516,7 @@ Para usar cachés adecuadamente, deberías considerar usar `etag` o cualquier trabajo pesado, ya que van a enviar la respuesta inmediatamente si el cliente ya tiene la versión actual en su caché: -``` ruby +```ruby get '/articulo/:id' do @articulo = Articulo.find params['id'] last_modified @articulo.updated_at @@ -1528,7 +1528,7 @@ end También es posible usar una [weak ETag](http://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation): -``` ruby +```ruby etag @articulo.sha1, :weak ``` @@ -1537,7 +1537,7 @@ información necesaria para poder hacerlo. Si estás buscando soluciones rápida de cacheo con proxys reversos, mirá [rack-cache](https://github.com/rtomayko/rack-cache): -``` ruby +```ruby require "rack/cache" require "sinatra" @@ -1561,7 +1561,7 @@ y potentes (como put) que el recurso existe, mientras que para el resto (como post) asume que no. Podés cambiar este comportamiento con la opción `:new_resource`: -``` ruby +```ruby get '/crear' do etag '', :new_resource => true Articulo.create @@ -1571,7 +1571,7 @@ end Si querés seguir usando una weak ETag, indicalo con la opción `:kind`: -``` ruby +```ruby etag '', :new_resource => true, :kind => :weak ``` @@ -1579,7 +1579,7 @@ etag '', :new_resource => true, :kind => :weak Para enviar archivos, podés usar el método `send_file`: -``` ruby +```ruby get '/' do send_file 'foo.png' end @@ -1587,7 +1587,7 @@ end Además acepta un par de opciones: -``` ruby +```ruby send_file 'foo.png', :type => :jpg ``` @@ -1625,7 +1625,7 @@ El objeto de la petición entrante puede ser accedido desde el nivel de la petición (filtros, rutas y manejadores de errores) a través del método `request`: -``` ruby +```ruby # app corriendo en http://ejemplo.com/ejemplo get '/foo' do t = %w[text/css text/html application/javascript] @@ -1661,7 +1661,7 @@ end Algunas opciones, como `script_name` o `path_info` pueden también ser escritas: -``` ruby +```ruby before { request.path_info = "/" } get "/" do @@ -1671,7 +1671,7 @@ end El objeto `request.body` es una instancia de IO o StringIO: -``` ruby +```ruby post "/api" do request.body.rewind # en caso de que alguien ya lo haya leído datos = JSON.parse request.body.read @@ -1684,7 +1684,7 @@ end Podés usar el helper `attachment` para indicarle al navegador que almacene la respuesta en el disco en lugar de mostrarla en pantalla: -``` ruby +```ruby get '/' do attachment "guardalo!" @@ -1693,7 +1693,7 @@ end También podés pasarle un nombre de archivo: -``` ruby +```ruby get '/' do attachment "info.txt" "guardalo!" @@ -1707,7 +1707,7 @@ a partir del valor que recibe como argumento. Este valor puede ser un `String`, pero también es capaz de convertir objetos `DateTime`, `Date` y de otras clases similares: -``` ruby +```ruby get '/' do pass if Time.now > time_for('Dec 23, 2012') "todavía hay tiempo" @@ -1718,7 +1718,7 @@ Este método es usado internamente por métodos como `expires` y `last_modified` entre otros. Por lo tanto, es posible extender el comportamiento de estos métodos sobreescribiendo `time_for` en tu aplicación: -``` ruby +```ruby helpers do def time_for(value) case value @@ -1741,7 +1741,7 @@ end El helper `find_template` se utiliza para encontrar los archivos de las plantillas que se van a renderizar: -``` ruby +```ruby find_template settings.views, 'foo', Tilt[:haml] do |archivo| puts "podría ser #{archivo}" end @@ -1751,7 +1751,7 @@ Si bien esto no es muy útil, lo interesante es que podés sobreescribir este método, y así enganchar tu propio mecanismo de búsqueda. Por ejemplo, para poder utilizar más de un directorio de vistas: -``` ruby +```ruby set :views, ['vistas', 'plantillas'] helpers do @@ -1764,7 +1764,7 @@ end Otro ejemplo consiste en usar directorios diferentes para los distintos motores de renderizado: -``` ruby +```ruby set :views, :sass => 'vistas/sass', :haml => 'plantillas', :defecto => 'vistas' helpers do @@ -1789,7 +1789,7 @@ tener en cuenta lo anterior si escribís un método extraño. Ejecutar una vez, en el inicio, en cualquier entorno: -``` ruby +```ruby configure do # asignando una opción set :opcion, 'valor' @@ -1811,7 +1811,7 @@ end Ejecutar únicamente cuando el entorno (la variable de entorno RACK_ENV) es `:production`: -``` ruby +```ruby configure :production do ... end @@ -1819,7 +1819,7 @@ end Ejecutar cuando el entorno es `:production` o `:test`: -``` ruby +```ruby configure :production, :test do ... end @@ -1827,7 +1827,7 @@ end Podés acceder a estas opciones utilizando el método `settings`: -``` ruby +```ruby configure do set :foo, 'bar' end @@ -1847,19 +1847,19 @@ querés desactivar esta funcionalidad, podés hacerlo como se indica a continuación (ten en cuenta que tu aplicación va a quedar expuesta a un montón de vulnerabilidades bien conocidas): -``` ruby +```ruby disable :protection ``` También es posible desactivar una única capa de defensa: -``` ruby +```ruby set :protection, :except => :path_traversal ``` O varias: -``` ruby +```ruby set :protection, :except => [:path_traversal, :session_hijacking] ``` @@ -2083,7 +2083,7 @@ Para utilizar alguno de los otros entornos puede asignarse el valor correspondiente a la variable de entorno `RACK_ENV`, o bien utilizar la opción `-e` al ejecutar la aplicación: -``` shell +```shell ruby mi_app.rb -e ``` @@ -2101,7 +2101,7 @@ y los filtros `before`, lo que significa que podés usar, por ejemplo, Cuando se eleva una excepción `Sinatra::NotFound`, o el código de estado de la respuesta es 404, el manejador `not_found` es invocado: -``` ruby +```ruby not_found do 'No existo' end @@ -2113,7 +2113,7 @@ El manejador `error` es invocado cada vez que una excepción es elevada desde un bloque de ruta o un filtro. El objeto de la excepción se puede obtener de la variable Rack `sinatra.error`: -``` ruby +```ruby error do 'Disculpá, ocurrió un error horrible - ' + env['sinatra.error'].message end @@ -2121,7 +2121,7 @@ end Errores personalizados: -``` ruby +```ruby error MiErrorPersonalizado do 'Lo que pasó fue...' + env['sinatra.error'].message end @@ -2129,7 +2129,7 @@ end Entonces, si pasa esto: -``` ruby +```ruby get '/' do raise MiErrorPersonalizado, 'algo malo' end @@ -2141,7 +2141,7 @@ Obtenés esto: También, podés instalar un manejador de errores para un código de estado: -``` ruby +```ruby error 403 do 'Acceso prohibido' end @@ -2153,7 +2153,7 @@ end O un rango: -``` ruby +```ruby error 400..510 do 'Boom' end @@ -2174,7 +2174,7 @@ proporcionar varios tipos de funcionalidades comunes. Sinatra hace muy sencillo construir tuberías de Rack middleware a través del método top-level `use`: -``` ruby +```ruby require 'sinatra' require 'mi_middleware_personalizado' @@ -2191,7 +2191,7 @@ Rack::Builder[http://rubydoc.info/github/rack/rack/master/Rack/Builder] (más frecuentemente usado en archivos rackup). Por ejemplo, el método `use` acepta argumentos múltiples/variables así como bloques: -``` ruby +```ruby use Rack::Auth::Basic do |nombre_de_usuario, password| nombre_de_usuario == 'admin' && password == 'secreto' end @@ -2213,7 +2213,7 @@ Las pruebas para las aplicaciones Sinatra pueden ser escritas utilizando cualquier framework o librería de pruebas basada en Rack. Se recomienda usar [Rack::Test](http://rdoc.info/github/brynary/rack-test/master/frames): -``` ruby +```ruby require 'mi_app_sinatra' require 'minitest/autorun' require 'rack/test' @@ -2253,7 +2253,7 @@ asume una configuración apropiada para micro-aplicaciones (por ejemplo, un `./views`, logging, página con detalles de excepción, etc.). Ahí es donde `Sinatra::Base` entra en el juego: -``` ruby +```ruby require 'sinatra/base' class MiApp < Sinatra::Base @@ -2345,7 +2345,7 @@ de ambos estilos: Las dos opciones más comunes para iniciar una aplicación modular son, iniciarla activamente con `run!`: -``` ruby +```ruby # mi_app.rb require 'sinatra/base' @@ -2359,13 +2359,13 @@ end Iniciar con: -``` shell +```shell ruby mi_app.rb ``` O, con un archivo `config.ru`, que permite usar cualquier handler Rack: -``` ruby +```ruby # config.ru require './mi_app' run MiApp @@ -2373,7 +2373,7 @@ run MiApp Después ejecutar: -``` shell +```shell rackup -p 4567 ``` @@ -2381,7 +2381,7 @@ rackup -p 4567 Escribí el archivo de tu aplicación: -``` ruby +```ruby # app.rb require 'sinatra' @@ -2392,7 +2392,7 @@ end Y el `config.ru` correspondiente: -``` ruby +```ruby require './app' run Sinatra::Application ``` @@ -2417,7 +2417,7 @@ cualquier aplicación Sinatra puede ser agregada delante de un endpoint Rack como middleware. Este endpoint puede ser otra aplicación Sinatra, o cualquier aplicación basada en Rack (Rails/Ramaze/Camping/...): -``` ruby +```ruby require 'sinatra/base' class PantallaDeLogin < Sinatra::Base @@ -2454,7 +2454,7 @@ Puede que en algunas ocasiones quieras crear nuevas aplicaciones en tiempo de ejecución sin tener que asignarlas a una constante. Para esto tenés `Sinatra.new`: -``` ruby +```ruby require 'sinatra/base' mi_app = Sinatra.new { get('/') { "hola" } } mi_app.run! @@ -2463,7 +2463,7 @@ mi_app.run! Acepta como argumento opcional una aplicación desde la que se heredará: -``` ruby +```ruby # config.ru require 'sinatra/base' @@ -2487,7 +2487,7 @@ testear extensiones Sinatra o para usar Sinatra en tus librerías. Por otro lado, hace extremadamente sencillo usar Sinatra como middleware: -``` ruby +```ruby require 'sinatra/base' use Sinatra do @@ -2513,7 +2513,7 @@ clase de la aplicación para todas las peticiones. Las opciones creadas utilizando `set` son métodos al nivel de la clase: -``` ruby +```ruby class MiApp < Sinatra::Base # Ey, estoy en el ámbito de la aplicación! set :foo, 42 @@ -2545,7 +2545,7 @@ es creada y todos los bloques de rutas son ejecutados en ese ámbito. Desde este de renderización como `erb` o `haml`. Podés acceder al ámbito de la aplicación desde el ámbito de la petición utilizando `settings`: -``` ruby +```ruby class MiApp < Sinatra::Base # Ey, estoy en el ámbito de la aplicación! get '/definir_ruta/:nombre' do @@ -2591,7 +2591,7 @@ que [extiende el objeto main](https://github.com/sinatra/sinatra/blob/ca06364/li Las aplicaciones Sinatra pueden ser ejecutadas directamente: -``` shell +```shell ruby miapp.rb [-h] [-x] [-e ENTORNO] [-p PUERTO] [-o HOST] [-s MANEJADOR] ``` @@ -2619,7 +2619,7 @@ Esto significa que, cuando estemos arrancando el servidor, tendríamos que especificar la opción adecuada para el handler Rack específico. En este ejemplo vemos cómo arrancar un servidor Thin multihilo: -``` ruby +```ruby # app.rb require 'sinatra/base' @@ -2635,7 +2635,7 @@ App.run! Para arrancar el servidor, el comando sería: -``` shell +```shell thin --threaded start ``` @@ -2723,7 +2723,7 @@ tu aplicación sobre la rama master, en general es bastante estable. También liberamos prereleases de vez en cuando, así, podés hacer: -``` shell +```shell gem install sinatra --pre ``` @@ -2736,13 +2736,13 @@ versión de Sinatra usando [Bundler](http://gembundler.com/). Primero, instalá Bundler si no lo hiciste todavía: -``` shell +```shell gem install bundler ``` Después, en el directorio de tu proyecto, creá un archivo `Gemfile`: -``` ruby +```ruby source :rubygems gem 'sinatra', :git => "git://github.com/sinatra/sinatra.git" @@ -2757,7 +2757,7 @@ porque Bundler las agrega directamente. Ahora podés arrancar tu aplicación así: -``` shell +```shell bundle exec ruby miapp.rb ``` @@ -2766,7 +2766,7 @@ bundle exec ruby miapp.rb Cloná el repositorio localmente y ejecutá tu aplicación, asegurándote que el directorio `sinatra/lib` esté en el `$LOAD_PATH`: -``` shell +```shell cd miapp git clone git://github.com/sinatra/sinatra.git ruby -Isinatra/lib miapp.rb @@ -2774,7 +2774,7 @@ ruby -Isinatra/lib miapp.rb Para actualizar el código fuente de Sinatra en el futuro: -``` shell +```shell cd miapp/sinatra git pull ``` @@ -2783,7 +2783,7 @@ git pull Podés construir la gem vos mismo: -``` shell +```shell git clone git://github.com/sinatra/sinatra.git cd sinatra rake sinatra.gemspec @@ -2792,7 +2792,7 @@ rake install Si instalás tus gems como root, el último paso debería ser -``` shell +```shell sudo rake install ``` diff --git a/README.fr.md b/README.fr.md index 8b5c989c..b5504543 100644 --- a/README.fr.md +++ b/README.fr.md @@ -5,7 +5,7 @@ il n'est peut-être plus à jour.* Sinatra est un [DSL](http://fr.wikipedia.org/wiki/Langage_dédié) pour créer rapidement et facilement des applications web en Ruby : -``` ruby +```ruby # mon_application.rb require 'sinatra' @@ -16,13 +16,13 @@ end Installez la gem Sinatra : -``` shell +```shell gem install sinatra ``` Puis lancez votre programme : -``` shell +```shell ruby mon_application.rb ``` @@ -122,7 +122,7 @@ Sinatra utilise le server Thin quand il est disponible. Dans Sinatra, une route est une méthode HTTP couplée à un masque (pattern) URL. Chaque route est associée à un bloc : -``` ruby +```ruby get '/' do .. montrer quelque chose .. end @@ -162,7 +162,7 @@ route qui correspond à la requête est appelée. Les masques peuvent inclure des paramètres nommés, accessibles par l'intermédiaire du hash `params` : -``` ruby +```ruby get '/bonjour/:nom' do # répond aux requêtes "GET /bonjour/foo" et "GET /bonjour/bar" # params['nom'] est 'foo' ou 'bar' @@ -173,7 +173,7 @@ end Vous pouvez aussi accéder aux paramètres nommés directement grâce aux paramètres du bloc comme ceci : -``` ruby +```ruby get '/bonjour/:nom' do |n| # répond aux requêtes "GET /bonjour/foo" et "GET /bonjour/bar" # params['nom'] est 'foo' ou 'bar' @@ -185,7 +185,7 @@ end Une route peut contenir un `splat` (caractère joker), accessible par l'intermédiaire du tableau `params['splat']` : -``` ruby +```ruby get '/dire/*/a/*' do # répond à /dire/bonjour/a/monde params['splat'] # => ["bonjour", "monde"] @@ -199,7 +199,7 @@ end Ou par l'intermédiaire des paramètres du bloc : -``` ruby +```ruby get '/telecharger/*.*' do |chemin, ext| [chemin, ext] # => ["path/to/file", "xml"] end @@ -207,7 +207,7 @@ end Une route peut aussi être définie par une expression régulière : -``` ruby +```ruby get /\A\/bonjour\/([\w]+)\z/ do "Bonjour, #{params['captures'].first} !" end @@ -215,7 +215,7 @@ end Là encore on peut utiliser les paramètres de bloc : -``` ruby +```ruby get %r{/bonjour/([\w]+)} do |c| # répond à "GET /meta/bonjour/monde", "GET /bonjour/monde/1234" etc. "Bonjour, #{c} !" @@ -224,7 +224,7 @@ end Les routes peuvent aussi comporter des paramètres optionnels : -``` ruby +```ruby get '/articles.?:format?' do # répond à "GET /articles" ou avec une extension "GET /articles.json", "GET /articles.xml" etc... end @@ -232,7 +232,7 @@ end Ainsi que des paramètres d'URL : -``` ruby +```ruby get '/articles' do # répond à "GET /articles?titre=foo&auteur=bar" titre = params['titre'] @@ -250,7 +250,7 @@ avant d'être comparée à vos routes. Les routes peuvent définir toutes sortes de conditions, comme par exemple le "user agent" : -``` ruby +```ruby get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do "Vous utilisez Songbird version #{params['agent'][0]}" end @@ -262,7 +262,7 @@ end Les autres conditions disponibles sont `host_name` et `provides` : -``` ruby +```ruby get '/', :host_name => /^admin\./ do "Zone Administrateur, Accès refusé !" end @@ -279,7 +279,7 @@ end Vous pouvez facilement définir vos propres conditions : -``` ruby +```ruby set(:chance) { |valeur| condition { rand <= valeur } } get '/gagner_une_voiture', :chance => 0.1 do @@ -294,7 +294,7 @@ end Utilisez un `splat` (caractère joker) dans le cas d'une condition qui prend plusieurs valeurs : -``` ruby +```ruby set(:auth) do |*roles| # <- ici on utilise un splat condition do unless logged_in? && roles.any? {|role| current_user.in_role? role } @@ -333,7 +333,7 @@ valide, d'un corps de réponse Rack ou d'un code statut HTTP : Ainsi, on peut facilement implémenter un exemple de streaming : -``` ruby +```ruby class Stream def each 100.times { |i| yield "#{i}\n" } @@ -354,7 +354,7 @@ masques sous forme de chaines de caractères ou des expressions régulières pour définir les routes. Mais il est possible de faire bien plus. Vous pouvez facilement définir vos propres masques : -``` ruby +```ruby class MasqueToutSauf Masque = Struct.new(:captures) @@ -379,7 +379,7 @@ end Notez que l'exemple ci-dessus est plus compliqué qu'il ne devrait et peut être implémenté de la façon suivante : -``` ruby +```ruby get // do pass if request.path_info == "/index" # ... @@ -388,7 +388,7 @@ end Ou bien en utilisant cette expression regulière : -``` ruby +```ruby get %r{^(?!/index$)} do # ... end @@ -398,7 +398,7 @@ end Les fichiers du dossier `./public` sont servis de façon statique. Vous pouvez spécifier un autre dossier avec le paramètre `:public_folder` : -``` ruby +```ruby set :public_folder, File.dirname(__FILE__) + '/statique' ``` @@ -414,7 +414,7 @@ d'en-tête `Cache-Control` (voir plus bas). Chaque langage de template est disponible via sa propre méthode de rendu, lesquelles renvoient tout simplement une chaîne de caractères. -``` ruby +```ruby get '/' do erb :index end @@ -425,7 +425,7 @@ Ceci génère la vue `views/index.erb`. Plutôt que d'utiliser le nom d'un template, vous pouvez directement passer le contenu du template : -``` ruby +```ruby get '/' do code = "<%= Time.now %>" erb code @@ -434,7 +434,7 @@ end Les méthodes de templates acceptent un hash d'options comme second argument : -``` ruby +```ruby get '/' do erb :index, :layout => :post end @@ -444,7 +444,7 @@ Ceci génèrera la vue `views/index.erb` en l'intégrant au *layout* `views/post Toute option que Sinatra ne comprend pas sera passée au moteur de rendu : -``` ruby +```ruby get '/' do haml :index, :format => :html5 end @@ -453,7 +453,7 @@ end Vous pouvez également définir les options de chaque langage de template de façon générale : -``` ruby +```ruby set :haml, :format => html5 get '/' do @@ -475,7 +475,7 @@ Options disponibles :
default_encoding
- Encodage de caractères à utiliser en cas d'incertitude. Par défaut + Encodage de caractères à utiliser en cas d'incertitude. Par défaut settings.default_encoding.
@@ -521,7 +521,7 @@ Options disponibles : Les templates sont supposés se trouver directement dans le dossier `./views`. Pour utiliser un dossier de vues différent : -``` ruby +```ruby set :views, settings.root + '/templates' ``` @@ -533,7 +533,7 @@ caractères au lieu de les considérer comme un chemin vers un fichier. ### Templates littéraux -``` ruby +```ruby get '/' do haml '%div.title Bonjour le monde' end @@ -547,7 +547,7 @@ Certains langages ont plusieurs implémentations. Pour préciser l'implémentati à utiliser (et garantir l'aspect thread-safe), vous devez simplement l'avoir chargée au préalable : -``` ruby +```ruby require 'rdiscount' # ou require 'bluecloth' get('/') { markdown :index } ``` @@ -735,13 +735,13 @@ Il n’est pas possible d’appeler des méthodes depuis markdown, ni de lui passer de variables locales. Par conséquent, il sera souvent utilisé en combinaison avec un autre moteur de rendu : -``` ruby +```ruby erb :accueil, :locals => { :text => markdown(:introduction) } ``` Notez que vous pouvez également appeler la méthode `markdown` depuis un autre template : -``` ruby +```ruby %h1 Bonjour depuis Haml ! %p= markdown(:bienvenue) ``` @@ -772,13 +772,13 @@ Il n’est pas possible d’appeler de méthodes depuis textile, ni de lui passer de variables locales. Par conséquent, il sera souvent utilisé en combinaison avec un autre moteur de rendu : -``` ruby +```ruby erb :accueil, :locals => { :text => textile(:introduction) } ``` Notez que vous pouvez également appeler la méthode `textile` depuis un autre template : -``` ruby +```ruby %h1 Bonjour depuis Haml ! %p= textile(:bienvenue) ``` @@ -809,13 +809,13 @@ Il n’est pas possible d’appeler de méthodes Ruby depuis rdoc, ni de lui passer de variables locales. Par conséquent, il sera souvent utilisé en combinaison avec un autre moteur de rendu : -``` ruby +```ruby erb :accueil, :locals => { :text => rdoc(:introduction) } ``` Notez que vous pouvez également appeler la méthode `rdoc` depuis un autre template : -``` ruby +```ruby %h1 Bonjour depuis Haml ! %p= rdoc(:bienvenue) ``` @@ -919,13 +919,13 @@ Il n'est pas possible d'appeler de méthodes Ruby depuis creole, ni de lui passer de variables locales. Par conséquent, il sera souvent utilisé en combinaison avec un autre moteur de rendu : -``` ruby +```ruby erb :accueil, :locals => { :text => markdown(:introduction) } ``` Notez que vous pouvez également appeler la méthode `creole` depuis un autre template : -``` ruby +```ruby %h1 Bonjour depuis Haml ! %p= creole(:bienvenue) ``` @@ -988,7 +988,7 @@ en utilisant l'option `:layout_engine`. Avant de pouvoir utiliser des templates Stylus, vous devez auparavant charger `stylus` et `stylus/tilt` : -``` ruby +```ruby require 'sinatra' require 'stylus' require 'stylus/tilt' @@ -1021,7 +1021,7 @@ end La source du template est évaluée en tant que chaine Ruby, puis la variable json obtenue est convertie avec #to_json. -``` ruby +```ruby json = { :foo => 'bar' } json[:baz] = key ``` @@ -1029,7 +1029,7 @@ json[:baz] = key Les options `:callback` et `:variable` peuvent être utilisées pour décorer l’objet retourné. -``` ruby +```ruby var ressource = {"foo":"bar","baz":"qux"}; present(ressource); ``` @@ -1061,7 +1061,7 @@ Un template est évalué dans le même contexte que l'endroit d'où il a été appelé (gestionnaire de route). Les variables d'instance déclarées dans le gestionnaire de route sont directement accessibles dans le template : -``` ruby +```ruby get '/:id' do @foo = Foo.find(params['id']) haml '%h1= @foo.nom' @@ -1070,7 +1070,7 @@ end Alternativement, on peut passer un hash contenant des variables locales : -``` ruby +```ruby get '/:id' do foo = Foo.find(params['id']) haml '%h1= foo.nom', :locals => { :foo => foo } @@ -1085,7 +1085,7 @@ En général, un layout est un simple template qui appelle `yield`. Ce genre de template peut s'utiliser via l'option `:template` comme décrit précédemment ou peut être rendu depuis un bloc : -``` ruby +```ruby erb :post, :layout => false do erb :index end @@ -1096,7 +1096,7 @@ Ce code est plus ou moins équivalent à `erb :index, :layout => :post`. Le fait de passer des blocs aux méthodes de rendu est particulièrement utile pour gérer des templates imbriqués : -``` ruby +```ruby erb :layout_principal, :layout => false do erb :layout_admin do erb :utilisateur @@ -1106,7 +1106,7 @@ end Ou plus brièvement : -``` ruby +```ruby erb :layout_admin, :layout => :layout_principal do erb :utilisateur end @@ -1121,7 +1121,7 @@ un bloc. Des templates peuvent être définis dans le fichier source comme ceci : -``` ruby +```ruby require 'sinatra' get '/' do @@ -1148,7 +1148,7 @@ fichiers source, il faut explicitement les déclarer avec Les templates peuvent aussi être définis grâce à la méthode de haut niveau `template` : -``` ruby +```ruby template :layout do "%html\n =yield\n" end @@ -1167,7 +1167,7 @@ template sera affiché. Vous pouvez désactivez les layouts au cas par cas en passant `:layout => false` ou bien les désactiver par défaut au moyen de `set :haml, :layout => false` : -``` ruby +```ruby get '/' do haml :index, :layout => !request.xhr? end @@ -1179,7 +1179,7 @@ Pour associer une extension de fichier avec un moteur de rendu, utilisez `Tilt.register`. Par exemple, si vous désirez utiliser l'extension de fichier `tt` pour les templates Textile, vous pouvez faire comme suit : -``` ruby +```ruby Tilt.register :tt, Tilt[:textile] ``` @@ -1188,7 +1188,7 @@ Tilt.register :tt, Tilt[:textile] En premier lieu, déclarez votre moteur de rendu avec Tilt, ensuite créez votre méthode de rendu : -``` ruby +```ruby Tilt.register :monmoteur, MonMerveilleuxMoteurDeRendu helpers do @@ -1209,7 +1209,7 @@ que les routes, et permettent de modifier la requête et sa réponse. Les variables d'instance déclarées dans les filtres sont accessibles au niveau des routes et des templates : -``` ruby +```ruby before do @note = 'Coucou !' request.path_info = '/foo/bar/baz' @@ -1226,7 +1226,7 @@ contexte et permettent de modifier la requête et sa réponse. Les variables d'instance déclarées dans les filtres `before` ou les routes sont accessibles au niveau des filtres `after` : -``` ruby +```ruby after do puts response.status end @@ -1239,7 +1239,7 @@ méthode `body` au lieu de simplement renvoyer une chaine depuis vos routes). Les filtres peuvent être associés à un masque, ce qui permet de limiter leur exécution aux cas où la requête correspond à ce masque : -``` ruby +```ruby before '/secret/*' do authentification! end @@ -1251,7 +1251,7 @@ end Tout comme les routes, les filtres acceptent également des conditions : -``` ruby +```ruby before :agent => /Songbird/ do # ... end @@ -1266,7 +1266,7 @@ end Utilisez la méthode de haut niveau `helpers` pour définir des méthodes qui seront accessibles dans vos gestionnaires de route et dans vos templates : -``` ruby +```ruby helpers do def bar(nom) "#{nom}bar" @@ -1280,7 +1280,7 @@ end Vous pouvez aussi définir les méthodes helper dans un module séparé : -``` ruby +```ruby module FooUtils def foo(nom) "#{nom}foo" end end @@ -1300,7 +1300,7 @@ l'application. Les sessions sont utilisées pour conserver un état entre les requêtes. Une fois activées, vous avez un hash de session par session utilisateur : -``` ruby +```ruby enable :sessions get '/' do @@ -1319,7 +1319,7 @@ quel middleware Rack de session afin d'éviter cela. N'utilisez **pas** `enable :sessions` dans ce cas mais chargez le middleware de votre choix comme vous le feriez pour n'importe quel autre middleware : -``` ruby +```ruby use Rack::Session::Pool, :expire_after => 2592000 get '/' do @@ -1337,21 +1337,21 @@ hasard par Sinatra. Toutefois, comme cette clé change à chaque démarrage de votre application, vous pouvez définir cette clé vous-même afin que toutes les instances de votre application la partage : -``` ruby +```ruby set :session_secret, 'super secret' ``` Si vous souhaitez avoir plus de contrôle, vous pouvez également enregistrer un hash avec des options lors de la configuration de `sessions` : -``` ruby +```ruby set :sessions, :domain => 'foo.com' ``` Pour que les différents sous-domaines de foo.com puissent partager une session, vous devez précéder le domaine d'un *.* (point) : -``` ruby +```ruby set :sessions, :domain => '.foo.com' ``` @@ -1361,37 +1361,37 @@ set :sessions, :domain => '.foo.com' Pour arrêter immédiatement la requête dans un filtre ou un gestionnaire de route : -``` ruby +```ruby halt ``` Vous pouvez aussi passer le code retour ... -``` ruby +```ruby halt 410 ``` Ou le texte ... -``` ruby +```ruby halt 'Ceci est le texte' ``` Ou les deux ... -``` ruby +```ruby halt 401, 'Partez !' ``` Ainsi que les en-têtes ... -``` ruby +```ruby halt 402, {'Content-Type' => 'text/plain'}, 'revanche' ``` Bien sûr il est possible de combiner un template avec `halt` : -``` ruby +```ruby halt erb(:erreur) ``` @@ -1400,7 +1400,7 @@ halt erb(:erreur) Une route peut passer le relais aux autres routes qui correspondent également avec `pass` : -``` ruby +```ruby get '/devine/:qui' do pass unless params['qui'] == 'Frank' "Tu m'as eu !" @@ -1421,7 +1421,7 @@ Parfois, `pass` n'est pas ce que vous recherchez, au lieu de cela vous souhaitez obtenir le résultat d'une autre route. Pour cela, utilisez simplement `call` : -``` ruby +```ruby get '/foo' do status, headers, body = call env.merge("PATH_INFO" => '/bar') [status, headers, body.map(&:upcase)] @@ -1452,7 +1452,7 @@ le coprs de la réponse à un moment arbitraire de l'exécution. Vous pouvez le faire au moyen de la méthode `body`. Si vous faites ainsi, vous pouvez alors utiliser cette même méthode pour accéder au corps de la réponse : -``` ruby +```ruby get '/foo' do body "bar" end @@ -1469,7 +1469,7 @@ voir "Valeurs de retour"). Pareillement au corps de la réponse, vous pouvez également définir le code retour et les en-têtes : -``` ruby +```ruby get '/foo' do status 418 headers \ @@ -1490,7 +1490,7 @@ extrèmes, vous souhaitez continuer à envoyer des données tant que le client n'abandonne pas la connexion. Vous pouvez alors utiliser le helper `stream` pour éviter de créer votre propre système : -``` ruby +```ruby get '/' do stream do |out| out << "Ca va être hallu -\n" @@ -1511,7 +1511,7 @@ provient d'une ressource lente. Le fonctionnement du streaming, notamment le nombre de requêtes simultanées, dépend énormément du serveur web utilisé. Certains ne prennent pas du tout en charge le streaming. Lorsque le serveur ne gère pas le streaming, la partie -body de la réponse sera envoyée au client en une seule fois, après +body de la réponse sera envoyée au client en une seule fois, après l'exécution du bloc passé au helper `stream`. Le streaming ne fonctionne pas du tout avec Shotgun. @@ -1521,7 +1521,7 @@ tout moment au cours de l'exécution. Ceci ne fonctionne qu'avec les serveurs evented (ie non threadés) tels que Thin et Rainbows. Les autres serveurs fermeront malgré tout le flux : -``` ruby +```ruby # interrogation prolongée set :server, :thin @@ -1555,7 +1555,7 @@ end Dans le contexte de la requête, la méthode utilitaire `logger` expose une instance de `Logger` : -``` ruby +```ruby get '/' do logger.info "chargement des données" # ... @@ -1571,7 +1571,7 @@ Notez que la journalisation est seulement activée par défaut pour `Sinatra::Application`, donc si vous héritez de `>Sinatra::Base`, vous aurez à l'activer vous-même : -``` ruby +```ruby class MonApp < Sinatra::Base configure :production, :development do enable :logging @@ -1590,7 +1590,7 @@ Quand vous utilisez `send_file` ou des fichiers statiques, vous pouvez rencontrer des types mime que Sinatra ne connaît pas. Utilisez `mime_type` pour les déclarer par extension de fichier : -``` ruby +```ruby configure do mime_type :foo, 'text/foo' end @@ -1598,7 +1598,7 @@ end Vous pouvez également les utiliser avec la méthode `content_type` : -``` ruby +```ruby get '/' do content_type :foo "foo foo foo" @@ -1610,7 +1610,7 @@ end Pour former des URLs, vous devriez utiliser la méthode `url`, par exemple en Haml : -``` ruby +```ruby %a{:href => url('/foo')} foo ``` @@ -1624,7 +1624,7 @@ pour un exemple). Vous pouvez déclencher une redirection du navigateur avec la méthode `redirect` : -``` ruby +```ruby get '/foo' do redirect to('/bar') end @@ -1633,7 +1633,7 @@ end Tout paramètre additionnel sera utilisé comme argument pour la méthode `halt` : -``` ruby +```ruby redirect to('/bar'), 303 redirect 'http://google.com', 'mauvais endroit mon pote' ``` @@ -1641,7 +1641,7 @@ redirect 'http://google.com', 'mauvais endroit mon pote' Vous pouvez aussi rediriger vers la page dont l'utilisateur venait au moyen de `redirect back` : -``` ruby +```ruby get '/foo' do "faire quelque chose" end @@ -1654,13 +1654,13 @@ end Pour passer des arguments à une redirection, ajoutez-les soit à la requête : -``` ruby +```ruby redirect to('/bar?sum=42') ``` Ou bien utilisez une session : -``` ruby +```ruby enable :sessions get '/foo' do @@ -1679,7 +1679,7 @@ Définissez correctement vos en-têtes à la base pour un bon cache HTTP. Vous pouvez facilement définir l'en-tête Cache-Control de la manière suivante : -``` ruby +```ruby get '/' do cache_control :public "met le en cache !" @@ -1688,7 +1688,7 @@ end Conseil de pro : définir le cache dans un filtre before : -``` ruby +```ruby before do cache_control :public, :must_revalidate, :max_age => 60 end @@ -1697,7 +1697,7 @@ end Si vous utilisez la méthode `expires` pour définir l'en-tête correspondant, `Cache-Control` sera alors défini automatiquement : -``` ruby +```ruby before do expires 500, :public, :must_revalidate end @@ -1708,7 +1708,7 @@ Pour utiliser correctement le cache, vous devriez utiliser `etag` ou d'importantes modifications, car elles vont immédiatement déclencher la réponse si le client a déjà la version courante dans son cache : -``` ruby +```ruby get '/article/:id' do @article = Article.find params['id'] last_modified @article.updated_at @@ -1720,7 +1720,7 @@ end Il est également possible d'utiliser un [weak ETag](http://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation) : -``` ruby +```ruby etag @article.sha1, :weak ``` @@ -1729,7 +1729,7 @@ fournissent les informations nécessaires pour le cache de votre navigateur. Si recherche d'une solution rapide pour un reverse-proxy de cache, essayez [rack-cache](https://github.com/rtomayko/rack-cache) : -``` ruby +```ruby require "rack/cache" require "sinatra" @@ -1753,7 +1753,7 @@ put) existent déjà et pour les autres ressources (par exemple dans le cas de requêtes post) qu'il s'agit de nouvelles ressources. Vous pouvez modifier ce comportement en passant une option `:new_resource` : -``` ruby +```ruby get '/create' do etag '', :new_resource => true Article.create @@ -1763,7 +1763,7 @@ end Si vous souhaitez avoir un ETag faible, utilisez l'option `:kind` : -``` ruby +```ruby etag '', :new_resource => true, :kind => :weak ``` @@ -1771,7 +1771,7 @@ etag '', :new_resource => true, :kind => :weak Pour envoyer des fichiers, vous pouvez utiliser la méthode `send_file` : -``` ruby +```ruby get '/' do send_file 'foo.png' end @@ -1779,7 +1779,7 @@ end Quelques options sont également acceptées : -``` ruby +```ruby send_file 'foo.png', :type => :jpg ``` @@ -1828,7 +1828,7 @@ L'objet correspondant à la requête envoyée peut être récupéré dans le con de la requête (filtres, routes, gestionnaires d'erreur) au moyen de la méthode `request` : -``` ruby +```ruby # application tournant à l'adresse http://exemple.com/exemple get '/foo' do t = %w[text/css text/html application/javascript] @@ -1866,7 +1866,7 @@ end Certaines options, telles que `script_name` ou `path_info` peuvent également être modifiées : -``` ruby +```ruby before { request.path_info = "/" } get "/" do @@ -1876,7 +1876,7 @@ end `request.body` est un objet IO ou StringIO : -``` ruby +```ruby post "/api" do request.body.rewind # au cas où il a déjà été lu donnees = JSON.parse request.body.read @@ -1890,7 +1890,7 @@ Vous pouvez utiliser la méthode `attachment` pour indiquer au navigateur que la réponse devrait être stockée sur le disque plutôt qu'affichée : -``` ruby +```ruby get '/' do attachment "enregistre-le !" @@ -1899,7 +1899,7 @@ end Vous pouvez également lui passer un nom de fichier : -``` ruby +```ruby get '/' do attachment "info.txt" "enregistre-le !" @@ -1912,7 +1912,7 @@ Sinatra fourni un helper `time_for` pour convertir une valeur donnée en objet `Time`. Il peut aussi faire la conversion à partir d'objets `DateTime`, `Date` ou de classes similaires : -``` ruby +```ruby get '/' do pass if Time.now > time_for('Dec 23, 2012') "encore temps" @@ -1924,7 +1924,7 @@ consorts. Par conséquent, vous pouvez très facilement étendre le fonctionnement de ces méthodes en surchargeant le helper `time_for` dans votre application : -``` ruby +```ruby helpers do def time_for(value) case value @@ -1947,7 +1947,7 @@ end La méthode `find_template` est utilisée pour trouver les fichiers de templates à générer : -``` ruby +```ruby find_template settings.views, 'foo', Tilt[:haml] do |file| puts "pourrait être #{file}" end @@ -1957,7 +1957,7 @@ Ce n'est pas très utile. En revanche, il est utile de pouvoir surcharger cette méthode afin de définir son propre mécanisme de recherche. Par exemple, vous pouvez utiliser plus d'un répertoire de vues : -``` ruby +```ruby set :views, ['views', 'templates'] helpers do @@ -1970,7 +1970,7 @@ end Un autre exemple est d'utiliser des répertoires différents pour des moteurs de rendu différents : -``` ruby +```ruby set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views' helpers do @@ -1996,7 +1996,7 @@ devez garder cela en tête si vous écrivez une méthode vraiment dingue. Lancé une seule fois au démarrage de tous les environnements : -``` ruby +```ruby configure do # définir un paramètre set :option, 'valeur' @@ -2017,7 +2017,7 @@ end Lancé si l'environnement (variable d'environnement RACK_ENV) est `:production` : -``` ruby +```ruby configure :production do ... end @@ -2025,7 +2025,7 @@ Lancé si l'environnement (variable d'environnement RACK_ENV) est `:production` Lancé si l'environnement est `:production` ou `:test` : -``` ruby +```ruby configure :production, :test do ... end @@ -2033,7 +2033,7 @@ Lancé si l'environnement est `:production` ou `:test` : Vous pouvez accéder à ces paramètres via `settings` : -``` ruby +```ruby configure do set :foo, 'bar' end @@ -2052,21 +2052,21 @@ pour protéger votre application contre les principales attaques opportunistes. Vous pouvez très simplement désactiver cette fonctionnalité (ce qui exposera votre application à beaucoup de vulnerabilités courantes) : -``` ruby +```ruby disable :protection ``` Pour désactiver seulement un type de protection, vous pouvez définir `protection` avec un hash d'options : -``` ruby +```ruby set :protection, :except => :path_traversal ``` Vous pouvez également lui passer un tableau pour désactiver plusieurs types de protection : -``` ruby +```ruby set :protection, :except => [:path_traversal, :session_hijacking] ``` @@ -2075,7 +2075,7 @@ un système de protection au niveau de la session. Dans le cas où vous gérez vous même les sessions, vous devez utiliser l'option `:session` pour que cela soit le cas : -``` ruby +```ruby use Rack::Session::Pool set :protection, :session => true ``` @@ -2238,14 +2238,14 @@ templates sont mis en cache par défaut. Pour exécuter votre application dans un environnement différent, définissez la variable d'environnement `RACK_ENV` : -``` shell +```shell RACK_ENV=production ruby my_app.rb ``` Vous pouvez utiliser une des méthodes `development?`, `test?` et `production?` pour déterminer quel est l'environnement en cours : -``` ruby +```ruby get '/' do if settings.development? "développement !" @@ -2266,7 +2266,7 @@ vieux `haml`, `erb`, `halt`, etc. Quand une exception Sinatra::NotFound est soulevée, ou que le code retour est 404, le gestionnaire not_found est invoqué : -``` ruby +```ruby not_found do 'Pas moyen de trouver ce que vous cherchez' end @@ -2278,7 +2278,7 @@ Le gestionnaire `error` est invoqué à chaque fois qu'une exception est soulevée dans une route ou un filtre. L'objet exception est accessible via la variable Rack `sinatra.error` : -``` ruby +```ruby error do 'Désolé mais une méchante erreur est survenue - ' + env['sinatra.error'].message end @@ -2286,7 +2286,7 @@ end Erreur sur mesure : -``` ruby +```ruby error MonErreurSurMesure do 'Oups ! Il est arrivé...' + env['sinatra.error'].message end @@ -2294,7 +2294,7 @@ end Donc si cette erreur est soulevée : -``` ruby +```ruby get '/' do raise MonErreurSurMesure, 'quelque chose de mal' end @@ -2309,7 +2309,7 @@ Oups ! Il est arrivé... quelque chose de mal Alternativement, vous pouvez avoir un gestionnaire d'erreur associé à un code particulier : -``` ruby +```ruby error 403 do 'Accès interdit' end @@ -2321,14 +2321,14 @@ end Ou un intervalle : -``` ruby +```ruby error 400..510 do 'Boom' end ``` Sinatra installe pour vous quelques gestionnaires `not_found` et -`error` génériques lorsque vous êtes en environnement de +`error` génériques lorsque vous êtes en environnement de `development`. ## Les Middlewares Rack @@ -2343,7 +2343,7 @@ fonctionnalités classiques. Sinatra permet d'utiliser facilement des middlewares Rack via la méthode de haut niveau `use` : -``` ruby +```ruby require 'sinatra' require 'mon_middleware_perso' @@ -2360,7 +2360,7 @@ La sémantique de `use` est identique à celle définie dans le DSL de (le plus souvent utilisé dans un fichier `rackup`). Par exemple, la méthode `use` accepte divers arguments ainsi que des blocs : -``` ruby +```ruby use Rack::Auth::Basic do |identifiant, mot_de_passe| identifiant == 'admin' && mot_de_passe == 'secret' end @@ -2382,7 +2382,7 @@ Les tests pour Sinatra peuvent être écrit avec n'importe quelle bibliothèque basée sur Rack. [Rack::Test](http://gitrdoc.com/brynary/rack-test) est recommandé : -``` ruby +```ruby require 'mon_application_sinatra' require 'minitest/autorun' require 'rack/test' @@ -2422,7 +2422,7 @@ niveau supérieur suppose une configuration dans le style des micro-applications `./views`, des logs, une page d'erreur, etc...). C'est là que `Sinatra::Base` prend tout son intérêt : -``` ruby +```ruby require 'sinatra/base' class MonApplication < Sinatra::Base @@ -2453,7 +2453,7 @@ souhaitez un comportement plus proche de celui obtenu lorsque vous définissez votre application au niveau supérieur (aussi connu sous le nom de style Classique), vous pouvez créer une classe héritant de `Sinatra::Application`. -``` ruby +```ruby require 'sinatra/base' class MyApp < Sinatra::Application @@ -2466,7 +2466,7 @@ end ### Style modulaire vs. style classique Contrairement aux idées reçues, il n'y a rien de mal à utiliser le style -classique. Si c'est ce qui convient pour votre application, vous n'avez +classique. Si c'est ce qui convient pour votre application, vous n'avez aucune raison de passer à une application modulaire. Le principal inconvénient du style classique sur le style modulaire est que vous @@ -2533,7 +2533,7 @@ mineures en ce qui concerne les paramètres par défaut : Il y a deux façons de faire pour démarrer une application modulaire, démarrez avec `run!` : -``` ruby +```ruby # my_app.rb require 'sinatra/base' @@ -2547,14 +2547,14 @@ end Démarrez ensuite avec : -``` shell +```shell ruby my_app.rb ``` Ou alors avec un fichier `config.ru`, qui permet d'utiliser n'importe quel gestionnaire Rack : -``` ruby +```ruby # config.ru require './my_app' run MyApp @@ -2562,7 +2562,7 @@ run MyApp Exécutez : -``` shell +```shell rackup -p 4567 ``` @@ -2570,7 +2570,7 @@ rackup -p 4567 Ecrivez votre application : -``` ruby +```ruby # app.rb require 'sinatra' @@ -2581,7 +2581,7 @@ end Et un fichier `config.ru` correspondant : -``` ruby +```ruby require './app' run Sinatra::Application ``` @@ -2608,7 +2608,7 @@ en tant que middleware. Cet endpoint peut très bien être une autre application Sinatra, ou n'importe quelle application basée sur Rack (Rails/Ramaze/Camping/...) : -``` ruby +```ruby require 'sinatra/base' class EcranDeConnexion < Sinatra::Base @@ -2645,7 +2645,7 @@ Il se peut que vous ayez besoin de créer une nouvelle application à l'exécuti sans avoir à les assigner à une constante, vous pouvez le faire grâce à `Sinatra.new` : -``` ruby +```ruby require 'sinatra/base' mon_app = Sinatra.new { get('/') { "salut" } } mon_app.run! @@ -2653,7 +2653,7 @@ mon_app.run! L'application dont elle hérite peut être passé en argument optionnel : -``` ruby +```ruby # config.ru require 'sinatra/base' @@ -2676,7 +2676,7 @@ utiliser Sinatra dans votre propre bibliothèque. Cela permet également d'utiliser très facilement Sinatra comme middleware : -``` ruby +```ruby require 'sinatra/base' use Sinatra do @@ -2702,7 +2702,7 @@ les requêtes sont traitées par une seule classe d'application. Les options définies au moyen de `set` deviennent des méthodes de classe : -``` ruby +```ruby class MonApp < Sinatra::Base # Eh, je suis dans le contexte de l'application ! set :foo, 42 @@ -2736,7 +2736,7 @@ contexte. Depuis celui-ci, vous pouvez accéder aux objets `request` et Vous pouvez accéder au contexte de l'application depuis le contexte de la requête au moyen de `settings` : -``` ruby +```ruby class MonApp < Sinatra::Base # Eh, je suis dans le contexte de l'application ! get '/ajouter_route/:nom' do @@ -2783,7 +2783,7 @@ qui [étend l'objet principal](https://github.com/sinatra/sinatra/blob/ca06364/l Les applications Sinatra peuvent être lancées directement : -``` shell +```shell ruby mon_application.rb [-h] [-x] [-e ENVIRONNEMENT] [-p PORT] [-o HOTE] [-s SERVEUR] ``` @@ -2915,7 +2915,7 @@ stable. Pour cela, la méthode la plus simple est d'installer une gem de prerelease que nous publions de temps en temps : -``` shell +```shell gem install sinatra --pre ``` Ce qui permet de bénéficier des toutes dernières fonctionnalités. @@ -2927,13 +2927,13 @@ faire tourner votre application avec la dernière version de Sinatra. Pour commencer, installez bundler si nécessaire : -``` shell +```shell gem install bundler ``` Ensuite, créez un fichier `Gemfile` dans le dossier de votre projet : -``` ruby +```ruby source 'https://rubygems.org' gem 'sinatra', :github => "sinatra/sinatra" @@ -2948,7 +2948,7 @@ automatiquement téléchargées et ajoutées par Bundler. Vous pouvez alors lancer votre application de la façon suivante : -``` shell +```shell bundle exec ruby myapp.rb ``` @@ -2958,7 +2958,7 @@ Si vous ne souhaitez pas employer Bundler, vous pouvez cloner Sinatra en local dans votre projet et démarrez votre application avec le dossier `sinatra/lib` dans le `$LOAD_PATH` : -``` shell +```shell cd myapp git clone git://github.com/sinatra/sinatra.git ruby -I sinatra/lib myapp.rb @@ -2967,7 +2967,7 @@ ruby -I sinatra/lib myapp.rb Et de temps en temps, vous devrez récupérer la dernière version du code source de Sinatra : -``` shell +```shell cd myapp/sinatra git pull ``` @@ -2976,7 +2976,7 @@ git pull Une dernière méthode consiste à construire la gem vous-même : -``` shell +```shell git clone git://github.com/sinatra/sinatra.git cd sinatra rake sinatra.gemspec @@ -2985,7 +2985,7 @@ rake install Si vous installez les gems en tant que root, vous devez encore faire un : -``` shell +```shell sudo rake install ``` diff --git a/README.ja.md b/README.ja.md index b6c2af05..077665cd 100644 --- a/README.ja.md +++ b/README.ja.md @@ -5,7 +5,7 @@ Sinatraは最小の労力でRubyによるWebアプリケーションを手早く作るための[DSL](http://ja.wikipedia.org/wiki/ドメイン固有言語)です。 -``` ruby +```ruby # myapp.rb require 'sinatra' @@ -16,13 +16,13 @@ end gemをインストールし、 -``` shell +```shell gem install sinatra ``` 次のように実行します。 -``` shell +```shell ruby myapp.rb ``` @@ -123,7 +123,7 @@ ThinがあればSinatraはこれを利用するので、`gem install thin`する Sinatraでは、ルーティングはHTTPメソッドとURLマッチングパターンがペアになっています。 ルーティングはブロックに結び付けられています。 -``` ruby +```ruby get '/' do .. 何か見せる .. end @@ -163,7 +163,7 @@ end ルーティングのパターンは名前付きパラメータを含むことができ、 `params`ハッシュで取得できます。 -``` ruby +```ruby get '/hello/:name' do # "GET /hello/foo" と "GET /hello/bar" にマッチ # params['name'] は 'foo' か 'bar' @@ -173,7 +173,7 @@ end また、ブロックパラメータで名前付きパラメータにアクセスすることもできます。 -``` ruby +```ruby get '/hello/:name' do |n| # "GET /hello/foo" と "GET /hello/bar" にマッチ # params['name'] は 'foo' か 'bar' @@ -185,7 +185,7 @@ end ルーティングパターンはアスタリスク(すなわちワイルドカード)を含むこともでき、 `params['splat']` で取得できます。 -``` ruby +```ruby get '/say/*/to/*' do # /say/hello/to/world にマッチ params['splat'] # => ["hello", "world"] @@ -199,7 +199,7 @@ end ここで、ブロックパラメータを使うこともできます。 -``` ruby +```ruby get '/download/*.*' do |path, ext| [path, ext] # => ["path/to/file", "xml"] end @@ -207,7 +207,7 @@ end ルーティングを正規表現にマッチさせることもできます。 -``` ruby +```ruby get /\A\/hello\/([\w]+)\z/ do "Hello, #{params['captures'].first}!" end @@ -215,7 +215,7 @@ end ここでも、ブロックパラメータが使えます。 -``` ruby +```ruby get %r{/hello/([\w]+)} do |c| "Hello, #{c}!" end @@ -223,7 +223,7 @@ end ルーティングパターンは、オプショナルパラメータを取ることもできます。 -``` ruby +```ruby get '/posts.?:format?' do # "GET /posts" と "GET /posts.json", "GET /posts.xml" の拡張子などにマッチ end @@ -236,7 +236,7 @@ end ルーティングにはユーザエージェントのようなさまざまな条件を含めることができます。 -``` ruby +```ruby get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do "Songbirdのバージョン #{params['agent'][0]}を使ってます。" end @@ -248,7 +248,7 @@ end ほかに`host_name`と`provides`条件が利用可能です。 -``` ruby +```ruby get '/', :host_name => /^admin\./ do "Adminエリアです。アクセスを拒否します!" end @@ -264,7 +264,7 @@ end 独自の条件を定義することも簡単にできます。 -``` ruby +```ruby set(:probability) { |value| condition { rand <= value } } get '/win_a_car', :probability => 0.1 do @@ -278,7 +278,7 @@ end 複数の値を取る条件には、アスタリスクを使います。 -``` ruby +```ruby set(:auth) do |*roles| # <- ここでアスタリスクを使う condition do unless logged_in? && roles.any? {|role| current_user.in_role? role } @@ -314,7 +314,7 @@ Rackレスポンス、Rackボディオブジェクト、HTTPステータスコ これにより、例えばストリーミングを簡単に実装することができます。 -``` ruby +```ruby class Stream def each 100.times { |i| yield "#{i}\n" } @@ -330,7 +330,7 @@ get('/') { Stream.new } 先述のようにSinatraはルーティングマッチャーとして、文字列パターンと正規表現を使うことをビルトインでサポートしています。しかしこれに留まらず、独自のマッチャーを簡単に定義することもできるのです。 -``` ruby +```ruby class AllButPattern Match = Struct.new(:captures) @@ -355,7 +355,7 @@ end ノート: この例はオーバースペックであり、以下のようにも書くことができます。 -``` ruby +```ruby get // do pass if request.path_info == "/index" # ... @@ -364,7 +364,7 @@ end または、否定先読みを使って: -``` ruby +```ruby get %r{^(?!/index$)} do # ... end @@ -376,7 +376,7 @@ end 静的ファイルは`./public`ディレクトリから配信されます。 `:public_folder`オプションを指定することで別の場所を指定することができます。 -``` ruby +```ruby set :public_folder, File.dirname(__FILE__) + '/static' ``` @@ -389,7 +389,7 @@ set :public_folder, File.dirname(__FILE__) + '/static' 各テンプレート言語はそれ自身のレンダリングメソッドを通して展開されます。それらのメソッドは単に文字列を返します。 -``` ruby +```ruby get '/' do erb :index end @@ -399,7 +399,7 @@ end テンプレート名を渡す代わりに、直接そのテンプレートの中身を渡すこともできます。 -``` ruby +```ruby get '/' do code = "<%= Time.now %>" erb code @@ -408,7 +408,7 @@ end テンプレートのレイアウトは第2引数のハッシュ形式のオプションをもとに表示されます。 -``` ruby +```ruby get '/' do erb :index, :layout => :post end @@ -419,7 +419,7 @@ end Sinatraが理解できないオプションは、テンプレートエンジンに渡されることになります。 -``` ruby +```ruby get '/' do haml :index, :format => :html5 end @@ -427,7 +427,7 @@ end テンプレート言語ごとにオプションをセットすることもできます。 -``` ruby +```ruby set :haml, :format => :html5 get '/' do @@ -486,7 +486,7 @@ end テンプレートは`./views`ディレクトリ下に配置されています。 他のディレクトリを使用する場合の例: -``` ruby +```ruby set :views, settings.root + '/templates' ``` @@ -496,7 +496,7 @@ set :views, settings.root + '/templates' ### リテラルテンプレート(Literal Templates) -``` ruby +```ruby get '/' do haml '%div.title Hello World' end @@ -509,7 +509,7 @@ end いくつかの言語には複数の実装があります。使用する(そしてスレッドセーフにする)実装を指定するには、それを最初にrequireしてください。 -``` ruby +```ruby require 'rdiscount' # または require 'bluecloth' get('/') { markdown :index } ``` @@ -691,13 +691,13 @@ LiquidテンプレートからRubyのメソッド(`yield`を除く)を呼び出 Markdownからメソッドを呼び出すことも、localsに変数を渡すこともできません。 それゆえ、他のレンダリングエンジンとの組み合わせで使うのが普通です。 -``` ruby +```ruby erb :overview, :locals => { :text => markdown(:introduction) } ``` ノート: 他のテンプレート内で`markdown`メソッドを呼び出せます。 -``` ruby +```ruby %h1 Hello From Haml! %p= markdown(:greetings) ``` @@ -725,13 +725,13 @@ MarkdownからはRubyを呼ぶことができないので、Markdownで書かれ Textileからメソッドを呼び出すことも、localsに変数を渡すこともできません。 それゆえ、他のレンダリングエンジンとの組み合わせで使うのが普通です。 -``` ruby +```ruby erb :overview, :locals => { :text => textile(:introduction) } ``` ノート: 他のテンプレート内で`textile`メソッドを呼び出せます。 -``` ruby +```ruby %h1 Hello From Haml! %p= textile(:greetings) ``` @@ -758,14 +758,14 @@ TexttileからはRubyを呼ぶことができないので、Textileで書かれ RDocからメソッドを呼び出すことも、localsに変数を渡すこともできません。 それゆえ、他のレンダリングエンジンとの組み合わせで使うのが普通です。 -``` ruby +```ruby erb :overview, :locals => { :text => rdoc(:introduction) } ``` ノート: 他のテンプレート内で`rdoc`メソッドを呼び出せます。 -``` ruby +```ruby %h1 Hello From Haml! %p= rdoc(:greetings) ``` @@ -884,13 +884,13 @@ RadiusテンプレートからRubyのメソッドを直接呼び出すことが Creoleからメソッドを呼び出すことも、localsに変数を渡すこともできません。 それゆえ、他のレンダリングエンジンとの組み合わせで使うのが普通です。 -``` ruby +```ruby erb :overview, :locals => { :text => creole(:introduction) } ``` ノート: 他のテンプレート内で`creole`メソッドを呼び出せます。 -``` ruby +```ruby %h1 Hello From Haml! %p= creole(:greetings) ``` @@ -972,7 +972,7 @@ erb :overview, :locals => { :text => mediawiki(:introduction) } Stylusテンプレートを使えるようにする前に、まず`stylus`と`stylus/tilt`を読み込む必要があります。 -``` ruby +```ruby require 'sinatra' require 'stylus' require 'stylus/tilt' @@ -1009,14 +1009,14 @@ end テンプレートのソースはRubyの文字列として評価され、その結果のJSON変数は`#to_json`を使って変換されます。 -``` ruby +```ruby json = { :foo => 'bar' } json[:baz] = key ``` `:callback`および`:variable`オプションは、レンダリングされたオブジェクトを装飾するために使うことができます。 -``` ruby +```ruby var resource = {"foo":"bar","baz":"qux"}; present(resource); ``` @@ -1043,7 +1043,7 @@ WLang内でのRubyメソッドの呼び出しは一般的ではないので、 テンプレートはルーティングハンドラと同じコンテキストの中で評価されます。ルーティングハンドラでセットされたインスタンス変数はテンプレート内で直接使うことができます。 -``` ruby +```ruby get '/:id' do @foo = Foo.find(params['id']) haml '%h1= @foo.name' @@ -1052,7 +1052,7 @@ end また、ローカル変数のハッシュで明示的に指定することもできます。 -``` ruby +```ruby get '/:id' do foo = Foo.find(params['id']) haml '%h1= bar.name', :locals => { :bar => foo } @@ -1066,7 +1066,7 @@ end レイアウトは通常、`yield`を呼ぶ単なるテンプレートに過ぎません。 そのようなテンプレートは、既に説明した`:template`オプションを通して使われるか、または次のようなブロックを伴ってレンダリングされます。 -``` ruby +```ruby erb :post, :layout => false do erb :index end @@ -1076,7 +1076,7 @@ end レンダリングメソッドにブロックを渡すスタイルは、ネストしたレイアウトを作るために最も役立ちます。 -``` ruby +```ruby erb :main_layout, :layout => false do erb :admin_layout do erb :user @@ -1086,7 +1086,7 @@ end これはまた次のより短いコードでも達成できます。 -``` ruby +```ruby erb :admin_layout, :layout => :main_layout do erb :user end @@ -1101,7 +1101,7 @@ end テンプレートはソースファイルの最後で定義することもできます。 -``` ruby +```ruby require 'sinatra' get '/' do @@ -1124,7 +1124,7 @@ __END__ テンプレートはトップレベルの`template`メソッドで定義することもできます。 -``` ruby +```ruby template :layout do "%html\n =yield\n" end @@ -1140,7 +1140,7 @@ end 「layout」というテンプレートが存在する場合、そのテンプレートファイルは他のテンプレートがレンダリングされる度に使用されます。`:layout => false`で個別に、または`set :haml, :layout => false`でデフォルトとして、レイアウトを無効にすることができます。 -``` ruby +```ruby get '/' do haml :index, :layout => !request.xhr? end @@ -1150,7 +1150,7 @@ end 任意のテンプレートエンジンにファイル拡張子を関連付ける場合は、`Tilt.register`を使います。例えば、Textileテンプレートに`tt`というファイル拡張子を使いたい場合は、以下のようにします。 -``` ruby +```ruby Tilt.register :tt, Tilt[:textile] ``` @@ -1158,7 +1158,7 @@ Tilt.register :tt, Tilt[:textile] まず、Tiltでそのエンジンを登録し、次にレンダリングメソッドを作ります。 -``` ruby +```ruby Tilt.register :myat, MyAwesomeTemplateEngine helpers do @@ -1176,7 +1176,7 @@ end beforeフィルタは、リクエストのルーティングと同じコンテキストで各リクエストの前に評価され、それによってリクエストとレスポンスを変更可能にします。フィルタ内でセットされたインスタンス変数はルーティングとテンプレートからアクセスすることができます。 -``` ruby +```ruby before do @note = 'Hi!' request.path_info = '/foo/bar/baz' @@ -1190,7 +1190,7 @@ end afterフィルタは、リクエストのルーティングと同じコンテキストで各リクエストの後に評価され、それによってこれもリクエストとレスポンスを変更可能にします。beforeフィルタとルーティング内でセットされたインスタンス変数はafterフィルタからアクセスすることができます。 -``` ruby +```ruby after do puts response.status end @@ -1200,7 +1200,7 @@ end フィルタにはオプションとしてパターンを渡すことができ、この場合はリクエストのパスがパターンにマッチした場合にのみフィルタが評価されるようになります。 -``` ruby +```ruby before '/protected/*' do authenticate! end @@ -1212,7 +1212,7 @@ end ルーティング同様、フィルタもまた条件を取ることができます。 -``` ruby +```ruby before :agent => /Songbird/ do # ... end @@ -1226,7 +1226,7 @@ end トップレベルの`helpers`メソッドを使用してルーティングハンドラやテンプレートで使うヘルパーメソッドを定義できます。 -``` ruby +```ruby helpers do def bar(name) "#{name}bar" @@ -1240,7 +1240,7 @@ end あるいは、ヘルパーメソッドをモジュール内で個別に定義することもできます。 -``` ruby +```ruby module FooUtils def foo(name) "#{name}foo" end end @@ -1259,7 +1259,7 @@ helpers FooUtils, BarUtils セッションはリクエスト間での状態維持のために使用されます。その起動により、ユーザセッションごとに一つのセッションハッシュが与えられます。 -``` ruby +```ruby enable :sessions get '/' do @@ -1273,7 +1273,7 @@ end ノート: `enable :sessions`は実際にはすべてのデータをクッキーに保持します。これは必ずしも期待通りのものにならないかもしれません(例えば、大量のデータを保持することでトラフィックが増大するなど)。Rackセッションミドルウェアの利用が可能であり、その場合は`enable :sessions`を呼ばずに、選択したミドルウェアを他のミドルウェアのときと同じようにして取り込んでください。 -``` ruby +```ruby use Rack::Session::Pool, :expire_after => 2592000 get '/' do @@ -1287,19 +1287,19 @@ end セキュリティ向上のため、クッキー内のセッションデータはセッション秘密鍵(session secret)で署名されます。Sinatraによりランダムな秘密鍵が個別に生成されます。しかし、この秘密鍵はアプリケーションの立ち上げごとに変わってしまうので、すべてのアプリケーションのインスタンスで共有できる秘密鍵をセットしたくなるかもしれません。 -``` ruby +```ruby set :session_secret, 'super secret' ``` 更に、設定変更をしたい場合は、`sessions`の設定においてオプションハッシュを保持することもできます。 -``` ruby +```ruby set :sessions, :domain => 'foo.com' ``` foo.comのサブドメイン上のアプリ間でセッションを共有化したいときは、代わりにドメインの前に *.* を付けます。 -``` ruby +```ruby set :sessions, :domain => '.foo.com' ``` @@ -1307,37 +1307,37 @@ set :sessions, :domain => '.foo.com' フィルタまたはルーティング内で直ちにリクエストを止める場合 -``` ruby +```ruby halt ``` この際、ステータスを指定することもできます。 -``` ruby +```ruby halt 410 ``` body部を指定することも、 -``` ruby +```ruby halt 'ここにbodyを書く' ``` ステータスとbody部を指定することも、 -``` ruby +```ruby halt 401, '立ち去れ!' ``` ヘッダを付けることもできます。 -``` ruby +```ruby halt 402, {'Content-Type' => 'text/plain'}, 'リベンジ' ``` もちろん、テンプレートを`halt`に結びつけることも可能です。 -``` ruby +```ruby halt erb(:error) ``` @@ -1345,7 +1345,7 @@ halt erb(:error) ルーティングは`pass`を使って次のルーティングに飛ばすことができます。 -``` ruby +```ruby get '/guess/:who' do pass unless params['who'] == 'Frank' "見つかっちゃった!" @@ -1362,7 +1362,7 @@ end `pass`を使ってルーティングを飛ばすのではなく、他のルーティングを呼んだ結果を得たいというときがあります。これを実現するには`call`を使えばいいです。 -``` ruby +```ruby get '/foo' do status, headers, body = call env.merge("PATH_INFO" => '/bar') [status, headers, body.map(&:upcase)] @@ -1384,7 +1384,7 @@ end ステータスコードおよびレスポンスボディを、ルーティングブロックの戻り値にセットすることが可能であり、これは推奨されています。しかし、あるケースでは実行フローの任意のタイミングでボディをセットしたくなるかもしれません。`body`ヘルパーメソッドを使えばそれができます。そうすると、それ以降、ボディにアクセスするためにそのメソッドを使うことができるようになります。 -``` ruby +```ruby get '/foo' do body "bar" end @@ -1398,7 +1398,7 @@ end ボディと同様に、ステータスコードおよびヘッダもセットできます。 -``` ruby +```ruby get '/foo' do status 418 headers \ @@ -1414,7 +1414,7 @@ end レスポンスボディの部分を未だ生成している段階で、データを送り出したいということがあります。極端な例では、クライアントがコネクションを閉じるまでデータを送り続けたいことがあります。`stream`ヘルパーを使えば、独自ラッパーを作る必要はありません。 -``` ruby +```ruby get '/' do stream do |out| out << "それは伝 -\n" @@ -1432,7 +1432,7 @@ end オプション引数が`keep_open`にセットされている場合、ストリームオブジェクト上で`close`は呼ばれず、実行フローの任意の遅れたタイミングでユーザがこれを閉じることを可能にします。これはThinやRainbowsのようなイベント型サーバ上でしか機能しません。他のサーバでは依然ストリームは閉じられます。 -``` ruby +```ruby # ロングポーリング set :server, :thin @@ -1466,7 +1466,7 @@ end リクエストスコープにおいて、`logger`ヘルパーは`Logger`インスタンスを作り出します。 -``` ruby +```ruby get '/' do logger.info "loading data" # ... @@ -1477,7 +1477,7 @@ end ノート: ロギングは、`Sinatra::Application`に対してのみデフォルトで有効にされているので、`Sinatra::Base`を継承している場合は、ユーザがこれを有効化する必要があります。 -``` ruby +```ruby class MyApp < Sinatra::Base configure :production, :development do enable :logging @@ -1491,7 +1491,7 @@ end `send_file`か静的ファイルを使う時、SinatraがMIMEタイプを理解できない場合があります。その時は `mime_type` を使ってファイル拡張子毎に登録して下さい。 -``` ruby +```ruby configure do mime_type :foo, 'text/foo' end @@ -1499,7 +1499,7 @@ end これは`content_type`ヘルパーで利用することができます: -``` ruby +```ruby get '/' do content_type :foo "foo foo foo" @@ -1510,7 +1510,7 @@ end URLを生成するためには`url`ヘルパーメソッドが使えます。Hamlではこのようにします。 -``` ruby +```ruby %a{:href => url('/foo')} foo ``` @@ -1522,7 +1522,7 @@ URLを生成するためには`url`ヘルパーメソッドが使えます。Ham `redirect` ヘルパーメソッドを使うことで、ブラウザをリダイレクトさせることができます。 -``` ruby +```ruby get '/foo' do redirect to('/bar') end @@ -1530,14 +1530,14 @@ end 他に追加されるパラメータは、`halt`に渡される引数と同様に取り扱われます。 -``` ruby +```ruby redirect to('/bar'), 303 redirect 'http://google.com', 'wrong place, buddy' ``` また、`redirect back`を使えば、簡単にユーザが来たページへ戻るリダイレクトを作れます。 -``` ruby +```ruby get '/foo' do "do something" end @@ -1551,13 +1551,13 @@ end redirectに引数を渡すには、それをクエリーに追加するか、 -``` ruby +```ruby redirect to('/bar?sum=42') ``` または、セッションを使います。 -``` ruby +```ruby enable :sessions get '/foo' do @@ -1576,7 +1576,7 @@ end キャッシュ制御ヘッダ(Cache-Control header)は、次のように簡単に設定できます。 -``` ruby +```ruby get '/' do cache_control :public "キャッシュしました!" @@ -1585,7 +1585,7 @@ end ヒント: キャッシングをbeforeフィルタ内で設定します。 -``` ruby +```ruby before do cache_control :public, :must_revalidate, :max_age => 60 end @@ -1593,7 +1593,7 @@ end `expires`ヘルパーを対応するヘッダに使っている場合は、キャッシュ制御は自動で設定されます。 -``` ruby +```ruby before do expires 500, :public, :must_revalidate end @@ -1601,7 +1601,7 @@ end キャッシュを適切に使うために、`etag`または`last_modified`を使うことを検討してください。これらのヘルパーを、重い仕事をさせる *前* に呼ぶことを推奨します。そうすれば、クライアントが既にキャッシュに最新版を持っている場合はレスポンスを直ちに破棄するようになります。 -``` ruby +```ruby get '/article/:id' do @article = Article.find params['id'] last_modified @article.updated_at @@ -1612,14 +1612,14 @@ end また、[weak ETag](http://ja.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation)を使うこともできます。 -``` ruby +```ruby etag @article.sha1, :weak ``` これらのヘルパーは、キャッシングをしてくれませんが、必要な情報をキャッシュに与えてくれます。もし手早いリバースプロキシキャッシングの解決策をお探しなら、 [rack-cache](https://github.com/rtomayko/rack-cache)を試してください。 -``` ruby +```ruby require "rack/cache" require "sinatra" @@ -1636,7 +1636,7 @@ end RFC 2616によれば、アプリケーションは、If-MatchまたはIf-None-Matchヘッダが`*`に設定されている場合には、要求されたリソースが既に存在するか否かに応じて、異なる振る舞いをすべきとなっています。Sinatraは、getのような安全なリクエストおよびputのような冪等なリクエストは既に存在しているものとして仮定し、一方で、他のリソース(例えば、postリクエスト)は新たなリソースとして取り扱われるよう仮定します。この振る舞いは、`:new_resource`オプションを渡すことで変更できます。 -``` ruby +```ruby get '/create' do etag '', :new_resource => true Article.create @@ -1646,7 +1646,7 @@ end ここでもWeak ETagを使いたい場合は、`:kind`オプションを渡してください。 -``` ruby +```ruby etag '', :new_resource => true, :kind => :weak ``` @@ -1654,7 +1654,7 @@ etag '', :new_resource => true, :kind => :weak ファイルを送信するには、`send_file`ヘルパーメソッドを使います。 -``` ruby +```ruby get '/' do send_file 'foo.png' end @@ -1662,7 +1662,7 @@ end これはオプションを取ることもできます。 -``` ruby +```ruby send_file 'foo.png', :type => :jpg ``` @@ -1700,7 +1700,7 @@ send_file 'foo.png', :type => :jpg 受信するリクエストオブジェクトは、`request`メソッドを通じてリクエストレベル(フィルタ、ルーティング、エラーハンドラ)からアクセスすることができます。 -``` ruby +```ruby # アプリケーションが http://example.com/example で動作している場合 get '/foo' do t = %w[text/css text/html application/javascript] @@ -1735,7 +1735,7 @@ end `script_name`や`path_info`などのオプションは次のように利用することもできます。 -``` ruby +```ruby before { request.path_info = "/" } get "/" do @@ -1745,7 +1745,7 @@ end `request.body`はIOまたはStringIOのオブジェクトです。 -``` ruby +```ruby post "/api" do request.body.rewind # 既に読まれているときのため data = JSON.parse request.body.read @@ -1757,7 +1757,7 @@ end `attachment`ヘルパーを使って、レスポンスがブラウザに表示されるのではなく、ディスクに保存されることをブラウザに対し通知することができます。 -``` ruby +```ruby get '/' do attachment "保存しました!" @@ -1766,7 +1766,7 @@ end ファイル名を渡すこともできます。 -``` ruby +```ruby get '/' do attachment "info.txt" "保存しました!" @@ -1777,7 +1777,7 @@ end Sinatraは`time_for`ヘルパーメソッドを提供しており、それは与えられた値からTimeオブジェクトを生成します。これはまた`DateTime`、`Date`および類似のクラスを変換できます。 -``` ruby +```ruby get '/' do pass if Time.now > time_for('Dec 23, 2012') "まだ時間がある" @@ -1786,7 +1786,7 @@ end このメソッドは、`expires`、`last_modified`といった種類のものの内部で使われています。そのため、アプリケーションにおいて、`time_for`をオーバーライドすることでそれらのメソッドの挙動を簡単に拡張できます。 -``` ruby +```ruby helpers do def time_for(value) case value @@ -1808,7 +1808,7 @@ end `find_template`ヘルパーは、レンダリングのためのテンプレートファイルを見つけるために使われます。 -``` ruby +```ruby find_template settings.views, 'foo', Tilt[:haml] do |file| puts "could be #{file}" end @@ -1817,7 +1817,7 @@ end この例はあまり有益ではありません。しかし、このメソッドを、独自の探索機構で働くようオーバーライドするなら有益になります。例えば、複数のビューディレクトリを使えるようにしたいときがあります。 -``` ruby +```ruby set :views, ['views', 'templates'] helpers do @@ -1829,7 +1829,7 @@ end 他の例としては、異なるエンジン用の異なるディレクトリを使う場合です。 -``` ruby +```ruby set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views' helpers do @@ -1849,7 +1849,7 @@ end どの環境でも起動時に1回だけ実行されます。 -``` ruby +```ruby configure do # 1つのオプションをセット set :option, 'value' @@ -1870,7 +1870,7 @@ end 環境設定(`RACK_ENV`環境変数)が`:production`に設定されている時だけ実行する方法: -``` ruby +```ruby configure :production do ... end @@ -1878,7 +1878,7 @@ end 環境設定が`:production`か`:test`に設定されている時だけ実行する方法: -``` ruby +```ruby configure :production, :test do ... end @@ -1886,7 +1886,7 @@ end 設定したオプションには`settings`からアクセスできます: -``` ruby +```ruby configure do set :foo, 'bar' end @@ -1902,24 +1902,24 @@ end Sinatraは、[Rack::Protection](https://github.com/rkh/rack-protection#readme)を使って、アプリケーションを多発する日和見的攻撃から守っています。この挙動は簡単に無効化できます(これはアプリケーションを大量の脆弱性攻撃に晒すことになります)。 -``` ruby +```ruby disable :protection ``` 単一の防御層を外すためには、`protection`をオプションハッシュにセットします。 -``` ruby +```ruby set :protection, :except => :path_traversal ``` また配列を渡して、複数の防御を無効にすることもできます。 -``` ruby +```ruby set :protection, :except => [:path_traversal, :session_hijacking] ``` デフォルトでSinatraは、`:sessions`が有効になっている場合、セッションベースの防御だけを設定します。しかし、自身でセッションを設定したい場合があります。その場合は、`:session`オプションを渡すことにより、セッションベースの防御を設定することができます。 -``` ruby +```ruby use Rack::Session::Pool set :protection, :session => true ``` @@ -2074,13 +2074,13 @@ set :protection, :session => true 異なる環境を走らせるには、`RACK_ENV`環境変数を設定します。 -``` shell +```shell RACK_ENV=production ruby my_app.rb ``` 既定メソッド、`development?`、`test?`および`production?`を、現在の環境設定を確認するために使えます。 -``` ruby +```ruby get '/' do if settings.development? "development!" @@ -2098,7 +2098,7 @@ end `Sinatra::NotFound`例外が発生したとき、またはレスポンスのステータスコードが404のときに、`not_found`ハンドラが発動します。 -``` ruby +```ruby not_found do 'ファイルが存在しません' end @@ -2108,7 +2108,7 @@ end `error`ハンドラはルーティングブロックまたはフィルタ内で例外が発生したときはいつでも発動します。例外オブジェクトはRack変数`sinatra.error`から取得できます。 -``` ruby +```ruby error do 'エラーが発生しました。 - ' + env['sinatra.error'].message end @@ -2116,7 +2116,7 @@ end エラーをカスタマイズする場合は、 -``` ruby +```ruby error MyCustomError do 'エラーメッセージ...' + env['sinatra.error'].message end @@ -2124,7 +2124,7 @@ end と書いておいて、下記のように呼び出します。 -``` ruby +```ruby get '/' do raise MyCustomError, '何かがまずかったようです' end @@ -2138,7 +2138,7 @@ end あるいは、ステータスコードに対応するエラーハンドラを設定することもできます。 -``` ruby +```ruby error 403 do 'Access forbidden' end @@ -2150,7 +2150,7 @@ end 範囲指定もできます。 -``` ruby +```ruby error 400..510 do 'Boom' end @@ -2165,7 +2165,7 @@ SinatraはRuby製Webフレームワークのミニマルな標準的インタフ Sinatraはトップレベルの`use`メソッドを通して、Rackミドルウェアパイプラインの構築を楽にします。 -``` ruby +```ruby require 'sinatra' require 'my_custom_middleware' @@ -2179,7 +2179,7 @@ end `use`の文法は、[Rack::Builder](http://rubydoc.info/github/rack/rack/master/Rack/Builder)DSLで定義されているそれ(rackupファイルで最もよく使われる)と同じです。例えば `use`メソッドは複数の引数、そしてブロックも取ることができます。 -``` ruby +```ruby use Rack::Auth::Basic do |username, password| username == 'admin' && password == 'secret' end @@ -2197,7 +2197,7 @@ Rackは、ロギング、デバッギング、URLルーティング、認証、 SinatraでのテストはRackベースのテストライブラリまたはフレームワークを使って書くことができます。[Rack::Test](http://rdoc.info/github/brynary/rack-test/master/frames)をお薦めします。 -``` ruby +```ruby require 'my_sinatra_app' require 'minitest/autorun' require 'rack/test' @@ -2232,7 +2232,7 @@ end 軽量なアプリケーションであれば、トップレベルでアプリケーションを定義していくことはうまくいきますが、再利用性可能なコンポーネント、例えばRackミドルウェア、RailsのMetal、サーバコンポーネントを含むシンプルなライブラリ、あるいはSinatraの拡張プログラムを構築するような場合、これは無視できない欠点を持つものとなります。トップレベルは、軽量なアプリケーションのスタイルにおける設定(例えば、単一のアプリケーションファイル、`./public`および`./views`ディレクトリ、ロギング、例外詳細ページなど)を仮定しています。そこで`Sinatra::Base`の出番です。 -``` ruby +```ruby require 'sinatra/base' class MyApp < Sinatra::Base @@ -2328,7 +2328,7 @@ end モジュラーアプリケーションを開始、つまり`run!`を使って開始させる二種類のやり方があります。 -``` ruby +```ruby # my_app.rb require 'sinatra/base' @@ -2342,13 +2342,13 @@ end として、次のように起動するか、 -``` shell +```shell ruby my_app.rb ``` または、Rackハンドラを使えるようにする`config.ru`ファイルを書いて、 -``` ruby +```ruby # config.ru (rackupで起動) require './my_app' run MyApp @@ -2356,7 +2356,7 @@ run MyApp 起動します。 -``` shell +```shell rackup -p 4567 ``` @@ -2364,7 +2364,7 @@ rackup -p 4567 アプリケーションファイルと、 -``` ruby +```ruby # app.rb require 'sinatra' @@ -2375,7 +2375,7 @@ end 対応する`config.ru`を書きます。 -``` ruby +```ruby require './app' run Sinatra::Application ``` @@ -2397,7 +2397,7 @@ Sinatraは他のRackミドルウェアを利用することができるだけで このエンドポイントには、別のSinatraアプリケーションまたは他のRackベースのアプリケーション(Rails/Ramaze/Camping/…)が用いられるでしょう。 -``` ruby +```ruby require 'sinatra/base' class LoginScreen < Sinatra::Base @@ -2432,7 +2432,7 @@ end 新しいアプリケーションを実行時に、定数に割り当てることなく生成したくなる場合があるでしょう。`Sinatra.new`を使えばそれができます。 -``` ruby +```ruby require 'sinatra/base' my_app = Sinatra.new { get('/') { "hi" } } my_app.run! @@ -2462,7 +2462,7 @@ end これはまた、Sinatraをミドルウェアとして利用することを極めて簡単にします。 -``` ruby +```ruby require 'sinatra/base' use Sinatra do @@ -2486,7 +2486,7 @@ run RailsProject::Application `set`によって作られたオプションはクラスレベルのメソッドです。 -``` ruby +```ruby class MyApp < Sinatra::Base # アプリケーションスコープの中だよ! set :foo, 42 @@ -2517,7 +2517,7 @@ end このスコープの内側からは`request`や`session`オブジェクトにアクセスすることができ、`erb`や`haml`のようなレンダリングメソッドを呼び出すことができます。 リクエストスコープの内側からは、`settings`ヘルパーによってアプリケーションスコープにアクセスすることができます。 -``` ruby +```ruby class MyApp < Sinatra::Base # アプリケーションスコープの中だよ! get '/define_route/:name' do @@ -2561,7 +2561,7 @@ mixin](https://github.com/sinatra/sinatra/blob/ca06364/lib/sinatra/base.rb#L1609 Sinatraアプリケーションは直接実行できます。 -``` shell +```shell ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER] ``` @@ -2668,7 +2668,7 @@ Sinatraは現在、Cardinal、SmallRuby、BlueRubyまたは1.8.7以前のバー Sinatraの最新開発版のコードを使いたい場合は、マスターブランチに対してアプリケーションを走らせて構いません。ある程度安定しています。また、適宜プレリリース版gemをpushしているので、 -``` shell +```shell gem install sinatra --pre ``` @@ -2680,7 +2680,7 @@ gem install sinatra --pre まず、Bundlerがなければそれをインストールします。 -``` shell +```shell gem install bundler ``` @@ -2699,7 +2699,7 @@ gem 'activerecord', '~> 3.0' # ActiveRecord 3.xが必要かもしれません これで、以下のようにしてアプリケーションを起動することができます。 -``` shell +```shell bundle exec ruby myapp.rb ``` @@ -2707,7 +2707,7 @@ bundle exec ruby myapp.rb ローカルにクローンを作って、`sinatra/lib`ディレクトリを`$LOAD_PATH`に追加してアプリケーションを起動します。 -``` shell +```shell cd myapp git clone git://github.com/sinatra/sinatra.git ruby -I sinatra/lib myapp.rb @@ -2715,7 +2715,7 @@ ruby -I sinatra/lib myapp.rb 追ってSinatraのソースを更新する方法。 -``` shell +```shell cd myapp/sinatra git pull ``` @@ -2724,7 +2724,7 @@ git pull Sinatraのgemを自身でビルドすることもできます。 -``` shell +```shell git clone git://github.com/sinatra/sinatra.git cd sinatra rake sinatra.gemspec @@ -2733,7 +2733,7 @@ rake install gemをルートとしてインストールする場合は、最後のステップはこうなります。 -``` shell +```shell sudo rake install ``` diff --git a/README.ko.md b/README.ko.md index 6811110d..a3a347f8 100644 --- a/README.ko.md +++ b/README.ko.md @@ -5,7 +5,7 @@ Sinatra는 최소한의 노력으로 루비 기반 웹 애플리케이션을 신속하게 만들 수 있게 해 주는 [DSL](http://en.wikipedia.org/wiki/Domain-specific_language)입니다. -``` ruby +```ruby # myapp.rb require 'sinatra' @@ -16,13 +16,13 @@ end 젬을 설치합니다. -``` shell +```shell gem install sinatra ``` 실행합니다. -``` shell +```shell ruby myapp.rb ``` @@ -125,7 +125,7 @@ thin이 설치되어 있을 경우 Sinatra는 thin을 통해 실행합니다. Sinatra에서, 라우터(route)는 URL-매칭 패턴과 쌍을 이루는 HTTP 메서드입니다. 각각의 라우터는 블록과 연결됩니다. -``` ruby +```ruby get '/' do .. 무언가 보여주기(show) .. end @@ -163,7 +163,7 @@ end 라우터 패턴에는 이름을 가진 매개변수가 포함될 수 있으며, `params` 해시로 접근할 수 있습니다. -``` ruby +```ruby get '/hello/:name' do # "GET /hello/foo" 및 "GET /hello/bar"와 매치 # params['name']은 'foo' 또는 'bar' @@ -173,7 +173,7 @@ end 또한 블록 매개변수를 통하여도 이름을 가진 매개변수에 접근할 수 있습니다. -``` ruby +```ruby get '/hello/:name' do |n| # "GET /hello/foo" 및 "GET /hello/bar"와 매치 # params['name']은 'foo' 또는 'bar' @@ -184,7 +184,7 @@ end 라우터 패턴에는 스플랫(splat, 또는 와일드카드)도 매개변수도 포함될 수 있으며, 이럴 경우 `params['splat']` 배열을 통해 접근할 수 있습니다. -``` ruby +```ruby get '/say/*/to/*' do # /say/hello/to/world와 매치 params['splat'] # => ["hello", "world"] @@ -198,7 +198,7 @@ end 블록 매개변수로도 접근할 수 있습니다. -``` ruby +```ruby get '/download/*.*' do |path, ext| [path, ext] # => ["path/to/file", "xml"] end @@ -206,7 +206,7 @@ end 라우터는 정규표현식으로 매치할 수 있습니다. -``` ruby +```ruby get /\A\/hello\/([\w]+)\z/ do "Hello, #{params['captures'].first}!" end @@ -214,7 +214,7 @@ end 블록 매개변수로도 사용가능합니다. -``` ruby +```ruby get %r{/hello/([\w]+)} do |c| # "GET /meta/hello/world", "GET /hello/world/1234" 등과 매치 "Hello, #{c}!" @@ -223,7 +223,7 @@ end 라우터 패턴에는 선택적인(optional) 매개변수도 올 수 있습니다. -``` ruby +```ruby get '/posts.?:format?' do # "GET /posts" 는 물론 "GET /posts.json", "GET /posts.xml" 와 같은 어떤 확장자와도 매칭 end @@ -231,7 +231,7 @@ end 쿼리 파라메터로도 이용가능 합니다. -``` ruby +```ruby get '/posts' do # matches "GET /posts?title=foo&author=bar" title = params['title'] @@ -247,7 +247,7 @@ end 라우터는 사용자 에이전트(user agent)같은 다양한 매칭 조건을 포함할 수 있습니다. -``` ruby +```ruby get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do "Songbird 버전 #{params['agent'][0]}을 사용하는군요!" end @@ -259,7 +259,7 @@ end 다른 가능한 조건에는 `host_name`과 `provides`가 있습니다. -``` ruby +```ruby get '/', :host_name => /^admin\./ do "Admin Area, Access denied!" end @@ -276,7 +276,7 @@ end 사용자 정의 조건도 쉽게 만들 수 있습니다. -``` ruby +```ruby set(:probability) { |value| condition { rand <= value } } get '/win_a_car', :probability => 0.1 do @@ -290,7 +290,7 @@ end 여러 값을 받는 조건에는 스플랫(splat)을 사용합니다. -``` ruby +```ruby set(:auth) do |*roles| # <- 이게 스플랫 condition do unless logged_in? && roles.any? {|role| current_user.in_role? role } @@ -322,7 +322,7 @@ end 이것을 이용한 예를 들자면, 스트리밍(streaming) 예제를 쉽게 구현할 수 있습니다. -``` ruby +```ruby class Stream def each 100.times { |i| yield "#{i}\n" } @@ -339,7 +339,7 @@ get('/') { Stream.new } 위에서 보듯, Sinatra에는 문자열 패턴 및 정규표현식을 이용한 라우터 매칭 지원이 내장되어 있습니다. 하지만, 그게 끝은 아닙니다. 여러분 만의 매처(matcher)도 쉽게 정의할 수 있습니다. -``` ruby +```ruby class AllButPattern Match = Struct.new(:captures) @@ -364,7 +364,7 @@ end 사실 위의 예제는 조금 과하게 작성된 면이 있습니다. 간단하게 표현할 수도 있어요. -``` ruby +```ruby get // do pass if request.path_info == "/index" # ... @@ -373,7 +373,7 @@ end 또는 거꾸로 탐색(negative look ahead)할 수도 있습니다. -``` ruby +```ruby get %r{^(?!/index$)} do # ... end @@ -384,7 +384,7 @@ end 정적 파일들은 `./public` 디렉터리에서 제공됩니다. 위치를 다른 곳으로 변경하려면 `:public_folder` 옵션을 지정하면 됩니다. -``` ruby +```ruby set :public_folder, File.dirname(__FILE__) + '/static' ``` @@ -398,7 +398,7 @@ public 디렉터리명은 URL에 포함되지 않는다는 점에 주의하세 템플릿 언어들은 각각의 렌더링 메서드를 통해 표출됩니다. 이들 메서드는 문자열을 반환할 뿐입니다. -``` ruby +```ruby get '/' do erb :index end @@ -408,7 +408,7 @@ end 템플릿 이름 대신 템플릿의 내용을 직접 넘길 수도 있습니다. -``` ruby +```ruby get '/' do code = "<%= Time.now %>" erb code @@ -417,7 +417,7 @@ end 템플릿은 두 번째 인자로 옵션값의 해시를 받습니다. -``` ruby +```ruby get '/' do erb :index, :layout => :post end @@ -428,7 +428,7 @@ end Sinatra가 이해하지 못하는 모든 옵션값들은 템플릿 엔진으로 전달됩니다. -``` ruby +```ruby get '/' do haml :index, :format => :html5 end @@ -436,7 +436,7 @@ end 옵션값은 템플릿 언어별로 전역적으로 설정할 수도 있습니다. -``` ruby +```ruby set :haml, :format => :html5 get '/' do @@ -496,7 +496,7 @@ render 메서드에서 전달된 옵션값들은 `set`을 통해 설정한 옵 템플릿은 `./views` 디렉터리에 있는 것으로 가정됩니다. 뷰 디렉터리를 다른 곳으로 하고 싶으시면 이렇게 하세요. -``` ruby +```ruby set :views, settings.root + '/templates' ``` @@ -507,7 +507,7 @@ set :views, settings.root + '/templates' ### 리터럴 템플릿(Literal Templates) -``` ruby +```ruby get '/' do haml '%div.title Hello World' end @@ -520,7 +520,7 @@ end 일부 언어는 여러 개의 구현이 있습니다. (스레드에 안전하게 thread-safe) 어느 구현을 사용할지 저정하려면, 먼저 require 하기만 하면 됩니다. -``` ruby +```ruby require 'rdiscount' # or require 'bluecloth' get('/') { markdown :index } ``` @@ -695,13 +695,13 @@ Liquid 템플릿에서는 루비 메서드(`yield` 제외)를 호출할 수 없 Markdown에서는 메서드 호출 뿐 아니라 locals 전달도 안됩니다. 따라서 일반적으로는 다른 렌더링 엔진과 함께 사용하게 됩니다. -``` ruby +```ruby erb :overview, :locals => { :text => markdown(:introduction) } ``` 다른 템플릿 속에서 `markdown` 메서드를 호출할 수도 있습니다. -``` ruby +```ruby %h1 안녕 Haml! %p= markdown(:greetings) ``` @@ -730,13 +730,13 @@ Markdown에서 루비를 호출할 수 없기 때문에, Markdown으로 작성 Textile에서는 메서드 호출 뿐 아니라 locals 전달도 안됩니다. 따라서 일반적으로는 다른 렌더링 엔진과 함께 사용하게 됩니다. -``` ruby +```ruby erb :overview, :locals => { :text => textile(:introduction) } ``` 다른 템플릿 속에서 `textile` 메서드를 호출할 수도 있습니다. -``` ruby +```ruby %h1 안녕 Haml! %p= textile(:greetings) ``` @@ -765,13 +765,13 @@ Textile에서 루비를 호출할 수 없기 때문에, Textile으로 작성된 RDoc에서는 메서드 호출 뿐 아니라 locals 전달도 안됩니다. 따라서 일반적으로는 다른 렌더링 엔진과 함께 사용하게 됩니다. -``` ruby +```ruby erb :overview, :locals => { :text => rdoc(:introduction) } ``` 다른 템플릿 속에서 `rdoc` 메서드를 호출할 수도 있습니다. -``` ruby +```ruby %h1 Hello From Haml! %p= rdoc(:greetings) ``` @@ -893,13 +893,13 @@ Radius 템플릿에서는 루비 메서드를 호출할 수 없기 Creole에서는 메서드 호출 뿐 아니라 locals 전달도 안됩니다. 따라서 일반적으로는 다른 렌더링 엔진과 함께 사용하게 됩니다. -``` ruby +```ruby erb :overview, :locals => { :text => creole(:introduction) } ``` 다른 템플릿 속에서 `creole` 메서드를 호출할 수도 있습니다. -``` ruby +```ruby %h1 Hello From Haml! %p= creole(:greetings) ``` @@ -928,13 +928,13 @@ Creole에서 루비를 호출할 수 없기 때문에, Creole으로 작성된 MediaWiki 마크업에서는 메서드 호출 뿐 아니라 locals 전달도 불가능합니다. 따라서 일반적으로는 다른 렌더링 엔진과 함께 사용하게 됩니다. -``` ruby +```ruby erb :overview, :locals => { :text => mediawiki(:introduction) } ``` 다른 템플릿 속에서 `mediawiki` 메서드를 호출할 수도 있습니다. -``` ruby +```ruby %h1 Hello From Haml! %p= mediawiki(:greetings) ``` @@ -994,7 +994,7 @@ MediaWiki에서 루비를 호출할 수 없기 때문에, MediaWiki으로 작성 Stylus 템플릿을 사용가능하게 하려면, 먼저 `stylus`와 `stylus/tilt`를 로드 해야합니다. -``` ruby +```ruby require 'sinatra' require 'stylus' require 'stylus/tilt' @@ -1030,7 +1030,7 @@ end 템플릿 소스는 루비 문자열로 평가(evaluate)되고, 결과인 json 변수는 `#to_json`으로 변환됩니다. -``` ruby +```ruby json = { :foo => 'bar' } json[:baz] = key ``` @@ -1068,7 +1068,7 @@ WLang으로 쓰여진 레이아웃과 `yield`는 지원합니다. 템플릿은 라우터 핸들러와 같은 맥락(context)에서 평가됩니다. 라우터 핸들러에서 설정한 인스턴스 변수들은 템플릿에서 직접 접근 가능합니다. -``` ruby +```ruby get '/:id' do @foo = Foo.find(params['id']) haml '%h1= @foo.name' @@ -1077,7 +1077,7 @@ end 명시적으로 로컬 변수의 해시를 지정할 수도 있습니다. -``` ruby +```ruby get '/:id' do foo = Foo.find(params['id']) haml '%h1= bar.name', :locals => { :bar => foo } @@ -1093,7 +1093,7 @@ end 위에 설명된 `:template` 옵션을 통해 템플릿을 사용하거나, 다음 예제처럼 블록으로 렌더링 할 수 있습니다. -``` ruby +```ruby erb :post, :layout => false do erb :index end @@ -1103,7 +1103,7 @@ end 렌더링 메서드에 블록 넘기기는 중첩 레이아웃을 만들때 유용합니다. -``` ruby +```ruby erb :main_layout, :layout => false do erb :admin_layout do erb :user @@ -1113,7 +1113,7 @@ end 위의 코드도 줄일 수 있습니다. -``` ruby +```ruby erb :admin_layout, :layout => :main_layout do erb :user end @@ -1126,7 +1126,7 @@ end 템플릿은 소스 파일의 마지막에서 정의할 수도 있습니다. -``` ruby +```ruby require 'sinatra' get '/' do @@ -1151,7 +1151,7 @@ __END__ 템플릿은 톱 레벨(top-level)에서 `template`메서드로도 정의할 수 있습니다. -``` ruby +```ruby template :layout do "%html\n =yield\n" end @@ -1170,7 +1170,7 @@ end 비활성시키거나 `set :haml, :layout => false`으로 기본값을 비활성으로 둘 수 있습니다. -``` ruby +```ruby get '/' do haml :index, :layout => !request.xhr? end @@ -1182,7 +1182,7 @@ end 됩니다. 예를 들어, `tt`라는 파일 확장자를 Textile 템플릿과 연결하고 싶다면, 다음과 같이 하면 됩니다. -``` ruby +```ruby Tilt.register :tt, Tilt[:textile] ``` @@ -1190,7 +1190,7 @@ Tilt.register :tt, Tilt[:textile] 우선, Tilt로 여러분 엔진을 등록하고, 렌더링 메서드를 생성합니다. -``` ruby +```ruby Tilt.register :myat, MyAwesomeTemplateEngine helpers do @@ -1209,7 +1209,7 @@ Tilt에 대한 더 자세한 내용은 https://github.com/rtomayko/tilt 참조 고유한 템플릿 룩업을 구현하기 위해서는 `#find_template` 메서드를 만드셔야 합니다. -``` ruby +```ruby configure do set :views [ './views/a', './views/b' ] end @@ -1227,7 +1227,7 @@ end 요청과 응답을 변형할 수 있습니다. 필터에서 설정된 인스턴스 변수들은 라우터와 템플릿에서 접근 가능합니다. -``` ruby +```ruby before do @note = 'Hi!' request.path_info = '/foo/bar/baz' @@ -1243,7 +1243,7 @@ end 마찬가지로 요청과 응답을 변형할 수 있습니다. 사전 필터와 라우터에서 설정된 인스턴스 변수들은 사후 필터에서 접근 가능합니다. -``` ruby +```ruby after do puts response.status end @@ -1256,7 +1256,7 @@ end 필터는 패턴을 취할 수도 있으며, 이 경우 요청 경로가 그 패턴과 매치할 경우에만 필터가 평가될 것입니다. -``` ruby +```ruby before '/protected/*' do authenticate! end @@ -1268,7 +1268,7 @@ end 라우터와 마찬가지로, 필터 역시 조건을 취할 수 있습니다. -``` ruby +```ruby before :agent => /Songbird/ do # ... end @@ -1283,7 +1283,7 @@ end 톱-레벨의 `helpers` 메서드를 사용하여 라우터 핸들러와 템플릿에서 사용할 헬퍼 메서드들을 정의할 수 있습니다. -``` ruby +```ruby helpers do def bar(name) "#{name}bar" @@ -1297,7 +1297,7 @@ end 또는, 헬퍼 메서드는 별도의 모듈 속에 정의할 수도 있습니다. -``` ruby +```ruby module FooUtils def foo(name) "#{name}foo" end end @@ -1316,7 +1316,7 @@ helpers FooUtils, BarUtils 세션은 요청 동안에 상태를 유지하기 위해 사용합니다. 세션이 활성화되면, 사용자 세션 당 세션 해시 하나씩을 갖게 됩니다. -``` ruby +```ruby enable :sessions get '/' do @@ -1335,7 +1335,7 @@ end `enable :sessions`을 호출하지 **않는** 대신에, 선택한 미들웨어를 다른 미들웨어들처럼 포함시키면 됩니다. -``` ruby +```ruby use Rack::Session::Pool, :expire_after => 2592000 get '/' do @@ -1352,21 +1352,21 @@ end 시크릿은 애플리케이션 시작 시마다 변경되기 때문에, 애플리케이션의 모든 인스턴스들이 공유할 시크릿을 직접 만들 수도 있습니다. -``` ruby +```ruby set :session_secret, 'super secret' ``` 조금 더 세부적인 설정이 필요하다면, `sessions` 설정에서 옵션이 있는 해시를 저장할 수도 있습니다. -``` ruby +```ruby set :sessions, :domain => 'foo.com' ``` 세션을 다른 foo.com의 서브도메인 들과 공유하기 원한다면, 다음에 나오는 것 처럼 도메인 앞에 *.*을 붙이셔야 합니다. -``` ruby +```ruby set :sessions, :domain => '.foo.com' ``` @@ -1374,37 +1374,37 @@ set :sessions, :domain => '.foo.com' 필터나 라우터에서 요청을 즉각 중단하고 싶을 때 사용하합니다. -``` ruby +```ruby halt ``` 중단할 때 상태를 지정할 수도 있습니다. -``` ruby +```ruby halt 410 ``` 본문을 넣을 수도 있습니다. -``` ruby +```ruby halt 'this will be the body' ``` 둘 다 할 수도 있습니다. -``` ruby +```ruby halt 401, 'go away!' ``` 헤더를 추가할 경우에는 다음과 같이 하면 됩니다. -``` ruby +```ruby halt 402, {'Content-Type' => 'text/plain'}, 'revenge' ``` 당연히 `halt`와 템플릿은 같이 사용할 수 있습니다. -``` ruby +```ruby halt erb(:error) ``` @@ -1412,7 +1412,7 @@ halt erb(:error) 라우터는 `pass`를 사용하여 다음 번 매칭되는 라우터로 처리를 넘길 수 있습니다. -``` ruby +```ruby get '/guess/:who' do pass unless params['who'] == 'Frank' 'You got me!' @@ -1431,7 +1431,7 @@ end 때로는 `pass`가 아니라, 다른 라우터를 호출한 결과를 얻고 싶을 때도 있습니다. 이럴때는 간단하게 `call`을 사용하면 됩니다. -``` ruby +```ruby get '/foo' do status, headers, body = call env.merge("PATH_INFO" => '/bar') [status, headers, body.map(&:upcase)] @@ -1457,7 +1457,7 @@ end 지점에서 설정해야 할때도 있습니다. 이런 경우 `body` 헬퍼 메서드를 사용하면 됩니다. 이렇게 하면, 그 순간부터 본문에 접근할 때 그 메서드를 사용할 수가 있습니다. -``` ruby +```ruby get '/foo' do body "bar" end @@ -1473,7 +1473,7 @@ end 본문와 마찬가지로, 상태코드와 헤더도 설정할 수 있습니다. -``` ruby +```ruby get '/foo' do status 418 headers \ @@ -1493,7 +1493,7 @@ end 계속 데이터를 내보내고 싶을 경우도 있죠. 여러분만의 래퍼(wrapper)를 만들지 않으려면 `stream` 헬퍼를 사용하면 됩니다. -``` ruby +```ruby get '/' do stream do |out| out << "It's gonna be legen -\n" @@ -1522,7 +1522,7 @@ Events](http://dev.w3.org/html5/eventsource/)를 구현할 수 있고, 이 방 있습니다. 이 옵션은 Thin과 Rainbow 같은 이벤트 기반 서버에서만 작동하고 다른 서버들은 여전히 스트림을 닫습니다. -``` ruby +```ruby # long polling set :server, :thin @@ -1556,7 +1556,7 @@ end 요청 스코프(request scope) 내에서, `Logger`의 인스턴스인 `logger` 헬퍼를 사용할 수 있습니다. -``` ruby +```ruby get '/' do logger.info "loading data" # ... @@ -1570,7 +1570,7 @@ end 로깅은 `Sinatra::Application`에서만 기본으로 활성화되어 있음에 유의합시다. 만약 `Sinatra::Base`로부터 상속받은 경우라면 직접 활성화시켜 줘야 합니다. -``` ruby +```ruby class MyApp < Sinatra::Base configure :production, :development do enable :logging @@ -1589,7 +1589,7 @@ Sinatra는 `env['rack.logger']`에서 찾은 로거를 사용할 것입니다. 마임 타입이 있을 수 있습니다. 이 경우 `mime_type`을 사용하여 파일 확장자를 등록합니다. -``` ruby +```ruby configure do mime_type :foo, 'text/foo' end @@ -1597,7 +1597,7 @@ end `content_type` 헬퍼로 쓸 수도 있습니다. -``` ruby +```ruby get '/' do content_type :foo "foo foo foo" @@ -1609,7 +1609,7 @@ end URL을 생성할때 `url` 헬퍼 메서드를 사용합니다. 예를 들어 Haml에서는 이렇게 합니다. -``` ruby +```ruby %a{:href => url('/foo')} foo ``` @@ -1621,7 +1621,7 @@ URL을 생성할때 `url` 헬퍼 메서드를 사용합니다. 예를 들어 Ham `redirect` 헬퍼 메서드를 사용하여 브라우저를 리다이렉트 시킬 수 있습니다. -``` ruby +```ruby get '/foo' do redirect to('/bar') end @@ -1629,7 +1629,7 @@ end 다른 부가적인 매개변수들은 `halt`에 전달하는 인자들과 비슷합니다. -``` ruby +```ruby redirect to('/bar'), 303 redirect 'http://google.com', 'wrong place, buddy' ``` @@ -1637,7 +1637,7 @@ redirect 'http://google.com', 'wrong place, buddy' `redirect back`을 사용하면 쉽게 사용자가 왔던 페이지로 다시 돌아가게 할 수 있습니다. -``` ruby +```ruby get '/foo' do "do something" end @@ -1650,13 +1650,13 @@ end 리다이렉트와 함께 인자를 전달하려면, 쿼리로 붙이거나, -``` ruby +```ruby redirect to('/bar?sum=42') ``` 세션을 사용하면 됩니다. -``` ruby +```ruby enable :sessions get '/foo' do @@ -1675,7 +1675,7 @@ end Cache-Control 헤더를 다음과 같이 간단하게 설정할 수 있습니다. -``` ruby +```ruby get '/' do cache_control :public "cache it!" @@ -1684,7 +1684,7 @@ end 프로 팁: 캐싱은 사전 필터에서 설정하세요. -``` ruby +```ruby before do cache_control :public, :must_revalidate, :max_age => 60 end @@ -1693,7 +1693,7 @@ end `expires` 헬퍼를 사용하여 그에 상응하는 헤더를 설정한다면, `Cache-Control`이 자동으로 설정됩니다. -``` ruby +```ruby before do expires 500, :public, :must_revalidate end @@ -1704,7 +1704,7 @@ end 클라이언트 캐시에 현재 버전이 이미 들어 있을 경우엔 즉각 응답을 뿌릴(flush) 것입니다. -``` ruby +```ruby get "/article/:id" do @article = Article.find params['id'] last_modified @article.updated_at @@ -1716,7 +1716,7 @@ end [약한 ETag](http://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation)를 사용할 수 도 있습니다. -``` ruby +```ruby etag @article.sha1, :weak ``` @@ -1724,7 +1724,7 @@ etag @article.sha1, :weak 손쉬운 리버스 프록시(reverse-proxy) 캐싱 솔루션을 찾고 있다면, [rack-cache](https://github.com/rtomayko/rack-cache)를 써보세요. -``` ruby +```ruby require "rack/cache" require "sinatra" @@ -1746,7 +1746,7 @@ RFC 2616에 따르면 If-Match 또는 If-None-Match 헤더가 `*`로 설정된 이미 존재한다고 가정하지만, 다른 리소스(예를 들면 post 요청 같은)의 경우는 새 리소스로 취급합니다. 이 행동은 `:new_resource` 옵션을 전달하여 변경할 수 있습니다. -``` ruby +```ruby get '/create' do etag '', :new_resource => true Article.create @@ -1756,7 +1756,7 @@ end 약한 ETag를 사용하고자 한다면, `:kind`으로 전달합시다. -``` ruby +```ruby etag '', :new_resource => true, :kind => :weak ``` @@ -1764,7 +1764,7 @@ etag '', :new_resource => true, :kind => :weak 응답(response)으로 파일의 컨탠츠를 리턴하려면, `send_file` 헬퍼 메서드를 사용하면 됩니다. -``` ruby +```ruby get '/' do send_file 'foo.png' end @@ -1772,7 +1772,7 @@ end 이 메서드는 몇 가지 옵션을 받습니다. -``` ruby +```ruby send_file 'foo.png', :type => :jpg ``` @@ -1813,7 +1813,7 @@ send_file 'foo.png', :type => :jpg 들어오는 요청 객에는 요청 레벨(필터, 라우터, 오류 핸들러)에서 `request` 메서드를 통해 접근 가능합니다. -``` ruby +```ruby # http://example.com/example 상에서 실행 중인 앱 get '/foo' do t = %w[text/css text/html application/javascript] @@ -1848,7 +1848,7 @@ end `script_name`, `path_info`같은 일부 옵션들은 이렇게 쓸 수도 있습니다. -``` ruby +```ruby before { request.path_info = "/" } get "/" do @@ -1858,7 +1858,7 @@ end `request.body`는 IO 객체이거나 StringIO 객체입니다. -``` ruby +```ruby post "/api" do request.body.rewind # 누군가 이미 읽은 경우 data = JSON.parse request.body.read @@ -1871,7 +1871,7 @@ end `attachment` 헬퍼를 사용하여 응답이 브라우저에 표시하는 대신 디스크에 저장되어야 함을 블라우저에게 알릴 수 있습니다. -``` ruby +```ruby get '/' do attachment "store it!" @@ -1880,7 +1880,7 @@ end 파일명을 전달할 수도 있습니다. -``` ruby +```ruby get '/' do attachment "info.txt" "store it!" @@ -1893,7 +1893,7 @@ Sinatra는 `time_for_` 헬퍼 메서드를 제공합니다. 이 메서드는 주어진 값으로부터 Time 객체를 생성한다. `DateTime`, `Date` 같은 비슷한 클래스들도 변환됩니다. -``` ruby +```ruby get '/' do pass if Time.now > time_for('Dec 23, 2012') "still time" @@ -1904,7 +1904,7 @@ end 따라서 여러분은 애플리케이션에서 `time_for`를 오버라이딩하여 이들 메서드의 동작을 쉽게 확장할 수 있습니다. -``` ruby +```ruby helpers do def time_for(value) case value @@ -1926,7 +1926,7 @@ end `find_template`는 렌더링할 템플릿 파일을 찾는데 사용됩니다. -``` ruby +```ruby find_template settings.views, 'foo', Tilt[:haml] do |file| puts "could be #{file}" end @@ -1936,7 +1936,7 @@ end 참조 메커니즘에서 가로채게 하면 유용해집니다. 예를 들어, 하나 이상의 뷰 디렉터리를 사용하고자 한다면 이렇게 하세요. -``` ruby +```ruby set :views, ['views', 'templates'] helpers do @@ -1948,7 +1948,7 @@ end 다른 예제는 각 엔진마다 다른 디렉터리를 사용할 경우입니다. -``` ruby +```ruby set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views' helpers do @@ -1972,7 +1972,7 @@ end 모든 환경에서, 시작될 때, 한번만 실행되게 하려면 이렇게 하면 됩니다. -``` ruby +```ruby configure do # 옵션 하나 설정 set :option, 'value' @@ -1993,7 +1993,7 @@ end 환경(RACK_ENV 환경 변수)이 `:production`일 때만 실행되게 하려면 이렇게 하면 됩니다. -``` ruby +```ruby configure :production do ... end @@ -2001,7 +2001,7 @@ end 환경이 `:production` 또는 `:test`일 때 실행되게 하려면 이렇게 하면 됩니다. -``` ruby +```ruby configure :production, :test do ... end @@ -2009,7 +2009,7 @@ end 이 옵션들은 `settings`를 통해 접근 가능합니다. -``` ruby +```ruby configure do set :foo, 'bar' end @@ -2027,19 +2027,19 @@ Sinatra는 [Rack::Protection](https://github.com/rkh/rack-protection#readme)을 일반적이고 일어날 수 있는 공격에 대비합니다. 이 모듈은 간단하게 비활성시킬 수 있습니다. (하지만 애플리케이션에 엄청나게 많은 취약성을 야기합니다.) -``` ruby +```ruby disable :protection ``` 하나의 방어층만 스킵하려면, 옵션 해시에 `protection`을 설정하면 됩니다. -``` ruby +```ruby set :protection, :except => :path_traversal ``` 배열로 넘김으로써 방어층 여러 개를 비활성화할 수 있습니다. -``` ruby +```ruby set :protection, :except => [:path_traversal, :session_hijacking] ``` @@ -2047,7 +2047,7 @@ set :protection, :except => [:path_traversal, :session_hijacking] 때로는 자신만의 세션을 설정할 때도 있습니다. 이런 경우 `:session` 옵션을 넘겨줌으로써 세션을 기반으로한 방어층을 설정 할 수 있습니다. -``` ruby +```ruby use Rack::Session::Pool set :protection, :session => true ``` @@ -2233,14 +2233,14 @@ set :protection, :session => true 다른 환경으로 실행시키려면 `RACK_ENV` 환경 변수를 사용하세요. -``` shell +```shell RACK_ENV=production ruby my_app.rb ``` 현재 설정된 환경이 무엇인지 검사하기 위해서는 준비된 `development?`, `test?`, `production?` 메서드를 사용할 수 있습니다. -``` ruby +```ruby get '/' do if settings.development? "development!" @@ -2261,7 +2261,7 @@ end `Sinatra::NotFound` 예외가 발생하거나 또는 응답의 상태 코드가 404라면, `not_found` 핸들러가 호출됩니다. -``` ruby +```ruby not_found do '아무 곳에도 찾을 수 없습니다.' end @@ -2273,13 +2273,13 @@ end 하지만 개발 환경에서는 예외 확인 옵션을 `:after_handler`로 설정되어 있을 경우에만 실행됨을 주의하세요. -``` ruby +```ruby set :show_exceptions, :after_handler ``` 예외 객체는 Rack 변수 `sinatra.error`로부터 얻을 수 있습니다. -``` ruby +```ruby error do '고약한 오류가 발생했군요 - ' + env['sinatra.error'].message end @@ -2287,7 +2287,7 @@ end 사용자 정의 오류는 이렇게 정의합니다. -``` ruby +```ruby error MyCustomError do '무슨 일이 생겼나면요...' + env['sinatra.error'].message end @@ -2295,7 +2295,7 @@ end 그런 다음, 이 오류가 발생하면 이렇게 처리합니다. -``` ruby +```ruby get '/' do raise MyCustomError, '안좋은 일' end @@ -2309,7 +2309,7 @@ end 상태 코드에 대해 오류 핸들러를 설치할 수도 있습니다. -``` ruby +```ruby error 403 do '액세스가 금지됨' end @@ -2321,7 +2321,7 @@ end 범위로 지정할 수도 있습니다. -``` ruby +```ruby error 400..510 do '어이쿠' end @@ -2341,7 +2341,7 @@ Sinatra는 [Rack](http://rack.github.io/) 위에서 동작하며, Rack은 루비 Sinatra는 톱레벨의 `use` 메서드를 사용하여 Rack 미들웨어의 파이프라인을 만드는 일을 식은 죽 먹기로 만듭니다. -``` ruby +```ruby require 'sinatra' require 'my_custom_middleware' @@ -2357,7 +2357,7 @@ end (rackup 파일에서 가장 많이 사용)에서 정의한 것과 동일합니다. 예를 들어, `use` 메서드는 블록이나 여러 개의/가변적인 인자도 받을 수 있습니다. -``` ruby +```ruby use Rack::Auth::Basic do |username, password| username == 'admin' && password == 'secret' end @@ -2378,7 +2378,7 @@ Rack은 로깅, 디버깅, URL 라우팅, 인증, 그리고 세센 핸들링을 Sinatra 테스트는 많은 Rack 기반 테스팅 라이브러리, 프레임워크를 사용하여 작성가능합니다. 그 중 [Rack::Test](http://rdoc.info/github/brynary/rack-test/master/frames)를 권장합니다. -``` ruby +```ruby require 'my_sinatra_app' require 'minitest/autorun' require 'rack/test' @@ -2419,7 +2419,7 @@ Rack 미들웨어나, Rails 메탈(metal) 또는 서버 컴포넌트를 갖는 입니다. (즉, 하나의 단일 애플리케이션 파일과 `./public` 및 `./views` 디렉터리, 로깅, 예외 상세 페이지 등등). 이 곳에서 `Sinatra::Base`가 필요합니다. -``` ruby +```ruby require 'sinatra/base' class MyApp < Sinatra::Base @@ -2501,7 +2501,7 @@ end 모듈 앱을 시작하는 두 가지 일반적인 옵션이 있습니다. `run!`으로 능동적으로 시작하는 방법은 이렇습니다. -``` ruby +```ruby # my_app.rb require 'sinatra/base' @@ -2515,14 +2515,14 @@ end 이렇게 시작할 수도 있습니다. -``` shell +```shell ruby my_app.rb ``` `config.ru`와 함께 사용할수도 있습니다. 이 경우는 어떠한 Rack 핸들러도 사용할 수 있도록 허용 합다. -``` ruby +```ruby # config.ru require './my_app' run MyApp @@ -2530,7 +2530,7 @@ run MyApp 실행은 이렇게 합니다. -``` shell +```shell rackup -p 4567 ``` @@ -2538,7 +2538,7 @@ rackup -p 4567 앱 파일을 다음과 같이 작성합니다. -``` ruby +```ruby # app.rb require 'sinatra' @@ -2549,7 +2549,7 @@ end 대응하는 `config.ru`는 다음과 같이 작성합니다. -``` ruby +```ruby require './app' run Sinatra::Application ``` @@ -2573,7 +2573,7 @@ Sinatra에서 다른 Rack 미들웨어를 사용할 수 있을 뿐 아니라, 또는 Rack 기반의 어떠한 애플리케이션(Rails/Ramaze/Camping/...)이 될 수도 있습니다. -``` ruby +```ruby require 'sinatra/base' class LoginScreen < Sinatra::Base @@ -2609,7 +2609,7 @@ end 어떤 상수에 할당하지 않고 런타임에서 새 애플리케이션들을 생성하려면, `Sinatra.new`를 쓰면 됩니다. -``` ruby +```ruby require 'sinatra/base' my_app = Sinatra.new { get('/') { "hi" } } my_app.run! @@ -2617,7 +2617,7 @@ my_app.run! 선택적 인자로 상속할 애플리케이션을 받을 수 있습니다. -``` ruby +```ruby # config.ru require 'sinatra/base' @@ -2640,7 +2640,7 @@ end 이 방법은 Sinatra를 미들웨어로 사용하는 것을 아주 쉽게 만들어 주기도 합니다. -``` ruby +```ruby require 'sinatra/base' use Sinatra do @@ -2665,7 +2665,7 @@ run RailsProject::Application `set`으로 생성한 옵션들은 클래스 레벨의 메서드들입니다. -``` ruby +```ruby class MyApp < Sinatra::Base # 저기요, 저는 애플리케이션 범위에 있다구요! set :foo, 42 @@ -2697,7 +2697,7 @@ end 접근하거나 `erb` 나 `haml` 같은 렌더링 메서드를 호출할 수 있습니다. 요청 범위 내에서 `settings` 헬퍼를 통해 애플리케이션 범위에 접근 가능합니다. -``` ruby +```ruby class MyApp < Sinatra::Base # 이봐요, 전 애플리케이션 범위에 있다구요! get '/define_route/:name' do @@ -2768,7 +2768,7 @@ _Konstantin의 [StackOverflow의 답변][so-answer]에서 가져왔습니다_ 이는 서버를 시작할 때, 서버에 따른 정확한 호출 방법을 사용했을 때의 이야기입니다. 밑의 예제는 다중 스레드 Thin 서버를 시작하는 방법입니다. -``` ruby +```ruby # app.rb require 'sinatra/base' @@ -2785,7 +2785,7 @@ App.run! 서버를 시작하는 명령어는 다음과 같습니다. -``` shell +```shell thin --threaded start ``` @@ -2869,7 +2869,7 @@ Sinatra의 가장 최근 코드를 사용하고자 한다면, 애플리케이션 주기적으로 사전배포(prerelease) 젬을 푸시하기 때문에, 최신 기능들을 얻기 위해 다음과 같이 할 수도 있습니다. -``` shell +```shell gem install sinatra --pre ``` @@ -2880,13 +2880,13 @@ gem install sinatra --pre 우선, 아직 설치하지 않았다면 bundler를 설치합니다. -``` shell +```shell gem install bundler ``` 그런 다음, 프로젝트 디렉터리에서, `Gemfile`을 만듭니다. -``` ruby +```ruby source 'https://rubygems.org' gem 'sinatra', :github => "sinatra/sinatra" @@ -2901,7 +2901,7 @@ Bundler가 자동으로 찾아서 추가할 것입니다. 이제 앱을 실행할 수 있습니다. -``` shell +```shell bundle exec ruby myapp.rb ``` @@ -2910,7 +2910,7 @@ bundle exec ruby myapp.rb 로컬 클론(clone)을 생성한 다음 `$LOAD_PATH`에 `sinatra/lib` 디렉터리를 주고 여러분 앱을 실행합니다. -``` shell +```shell cd myapp git clone git://github.com/sinatra/sinatra.git ruby -I sinatra/lib myapp.rb @@ -2918,7 +2918,7 @@ ruby -I sinatra/lib myapp.rb 이후에 Sinatra 소스를 업데이트하려면 이렇게 하세요. -``` shell +```shell cd myapp/sinatra git pull ``` @@ -2927,7 +2927,7 @@ git pull 젬을 직접 빌드할 수 있습니다. -``` shell +```shell git clone git://github.com/sinatra/sinatra.git cd sinatra rake sinatra.gemspec @@ -2936,7 +2936,7 @@ rake install 만약 젬을 루트로 설치한다면, 마지막 단계는 다음과 같이 해야 합니다. -``` shell +```shell sudo rake install ``` diff --git a/README.md b/README.md index 72bdeba7..8a184696 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Sinatra is a [DSL](http://en.wikipedia.org/wiki/Domain-specific_language) for quickly creating web applications in Ruby with minimal effort: -``` ruby +```ruby # myapp.rb require 'sinatra' @@ -14,13 +14,13 @@ end Install the gem: -``` shell +```shell gem install sinatra ``` And run with: -``` shell +```shell ruby myapp.rb ``` @@ -123,7 +123,7 @@ pick up if available. In Sinatra, a route is an HTTP method paired with a URL-matching pattern. Each route is associated with a block: -``` ruby +```ruby get '/' do .. show something .. end @@ -163,7 +163,7 @@ matches the request is invoked. Route patterns may include named parameters, accessible via the `params` hash: -``` ruby +```ruby get '/hello/:name' do # matches "GET /hello/foo" and "GET /hello/bar" # params['name'] is 'foo' or 'bar' @@ -173,7 +173,7 @@ end You can also access named parameters via block parameters: -``` ruby +```ruby get '/hello/:name' do |n| # matches "GET /hello/foo" and "GET /hello/bar" # params['name'] is 'foo' or 'bar' @@ -185,7 +185,7 @@ end Route patterns may also include splat (or wildcard) parameters, accessible via the `params['splat']` array: -``` ruby +```ruby get '/say/*/to/*' do # matches /say/hello/to/world params['splat'] # => ["hello", "world"] @@ -199,7 +199,7 @@ end Or with block parameters: -``` ruby +```ruby get '/download/*.*' do |path, ext| [path, ext] # => ["path/to/file", "xml"] end @@ -207,7 +207,7 @@ end Route matching with Regular Expressions: -``` ruby +```ruby get /\A\/hello\/([\w]+)\z/ do "Hello, #{params['captures'].first}!" end @@ -215,7 +215,7 @@ end Or with a block parameter: -``` ruby +```ruby get %r{/hello/([\w]+)} do |c| # Matches "GET /meta/hello/world", "GET /hello/world/1234" etc. "Hello, #{c}!" @@ -224,7 +224,7 @@ end Route patterns may have optional parameters: -``` ruby +```ruby get '/posts.?:format?' do # matches "GET /posts" and any extension "GET /posts.json", "GET /posts.xml" etc. end @@ -232,7 +232,7 @@ end Routes may also utilize query parameters: -``` ruby +```ruby get '/posts' do # matches "GET /posts?title=foo&author=bar" title = params['title'] @@ -248,7 +248,7 @@ the request path might be modified before matching against your routes. Routes may include a variety of matching conditions, such as the user agent: -``` ruby +```ruby get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do "You're using Songbird version #{params['agent'][0]}" end @@ -260,7 +260,7 @@ end Other available conditions are `host_name` and `provides`: -``` ruby +```ruby get '/', :host_name => /^admin\./ do "Admin Area, Access denied!" end @@ -277,7 +277,7 @@ end You can easily define your own conditions: -``` ruby +```ruby set(:probability) { |value| condition { rand <= value } } get '/win_a_car', :probability => 0.1 do @@ -291,7 +291,7 @@ end For a condition that takes multiple values use a splat: -``` ruby +```ruby set(:auth) do |*roles| # <- notice the splat here condition do unless logged_in? && roles.any? {|role| current_user.in_role? role } @@ -329,7 +329,7 @@ body object or HTTP status code: That way we can, for instance, easily implement a streaming example: -``` ruby +```ruby class Stream def each 100.times { |i| yield "#{i}\n" } @@ -348,7 +348,7 @@ As shown above, Sinatra ships with built-in support for using String patterns and regular expressions as route matches. However, it does not stop there. You can easily define your own matchers: -``` ruby +```ruby class AllButPattern Match = Struct.new(:captures) @@ -374,7 +374,7 @@ end Note that the above example might be over-engineered, as it can also be expressed as: -``` ruby +```ruby get // do pass if request.path_info == "/index" # ... @@ -383,7 +383,7 @@ end Or, using negative look ahead: -``` ruby +```ruby get %r{^(?!/index$)} do # ... end @@ -394,7 +394,7 @@ end Static files are served from the `./public` directory. You can specify a different location by setting the `:public_folder` option: -``` ruby +```ruby set :public_folder, File.dirname(__FILE__) + '/static' ``` @@ -410,7 +410,7 @@ Use the `:static_cache_control` setting (see below) to add Each template language is exposed via its own rendering method. These methods simply return a string: -``` ruby +```ruby get '/' do erb :index end @@ -421,7 +421,7 @@ This renders `views/index.erb`. Instead of a template name, you can also just pass in the template content directly: -``` ruby +```ruby get '/' do code = "<%= Time.now %>" erb code @@ -430,7 +430,7 @@ end Templates take a second argument, the options hash: -``` ruby +```ruby get '/' do erb :index, :layout => :post end @@ -442,7 +442,7 @@ This will render `views/index.erb` embedded in the Any options not understood by Sinatra will be passed on to the template engine: -``` ruby +```ruby get '/' do haml :index, :format => :html5 end @@ -450,7 +450,7 @@ end You can also set options per template language in general: -``` ruby +```ruby set :haml, :format => :html5 get '/' do @@ -515,7 +515,7 @@ Available Options: Templates are assumed to be located directly under the `./views` directory. To use a different views directory: -``` ruby +```ruby set :views, settings.root + '/templates' ``` @@ -528,7 +528,7 @@ directly. ### Literal Templates -``` ruby +```ruby get '/' do haml '%div.title Hello World' end @@ -541,7 +541,7 @@ Renders the template string. Some languages have multiple implementations. To specify what implementation to use (and to be thread-safe), you should simply require it first: -``` ruby +```ruby require 'rdiscount' # or require 'bluecloth' get('/') { markdown :index } ``` @@ -722,13 +722,13 @@ It is not possible to call methods from markdown, nor to pass locals to it. You therefore will usually use it in combination with another rendering engine: -``` ruby +```ruby erb :overview, :locals => { :text => markdown(:introduction) } ``` Note that you may also call the `markdown` method from within other templates: -``` ruby +```ruby %h1 Hello From Haml! %p= markdown(:greetings) ``` @@ -757,13 +757,13 @@ template than for the layout by passing the `:layout_engine` option. It is not possible to call methods from textile, nor to pass locals to it. You therefore will usually use it in combination with another rendering engine: -``` ruby +```ruby erb :overview, :locals => { :text => textile(:introduction) } ``` Note that you may also call the `textile` method from within other templates: -``` ruby +```ruby %h1 Hello From Haml! %p= textile(:greetings) ``` @@ -792,13 +792,13 @@ template than for the layout by passing the `:layout_engine` option. It is not possible to call methods from rdoc, nor to pass locals to it. You therefore will usually use it in combination with another rendering engine: -``` ruby +```ruby erb :overview, :locals => { :text => rdoc(:introduction) } ``` Note that you may also call the `rdoc` method from within other templates: -``` ruby +```ruby %h1 Hello From Haml! %p= rdoc(:greetings) ``` @@ -920,13 +920,13 @@ It also takes a block for inline templates (see example). It is not possible to call methods from creole, nor to pass locals to it. You therefore will usually use it in combination with another rendering engine: -``` ruby +```ruby erb :overview, :locals => { :text => creole(:introduction) } ``` Note that you may also call the `creole` method from within other templates: -``` ruby +```ruby %h1 Hello From Haml! %p= creole(:greetings) ``` @@ -956,13 +956,13 @@ It is not possible to call methods from MediaWiki markup, nor to pass locals to it. You therefore will usually use it in combination with another rendering engine: -``` ruby +```ruby erb :overview, :locals => { :text => mediawiki(:introduction) } ``` Note that you may also call the `mediawiki` method from within other templates: -``` ruby +```ruby %h1 Hello From Haml! %p= mediawiki(:greetings) ``` @@ -1022,7 +1022,7 @@ template than for the layout by passing the `:layout_engine` option. Before being able to use Stylus templates, you need to load `stylus` and `stylus/tilt` first: -``` ruby +```ruby require 'sinatra' require 'stylus' require 'stylus/tilt' @@ -1060,7 +1060,7 @@ end The template source is evaluated as a Ruby string, and the resulting json variable is converted using `#to_json`: -``` ruby +```ruby json = { :foo => 'bar' } json[:baz] = key ``` @@ -1068,7 +1068,7 @@ json[:baz] = key The `:callback` and `:variable` options can be used to decorate the rendered object: -``` javascript +```javascript var resource = {"foo":"bar","baz":"qux"}; present(resource); ``` @@ -1098,7 +1098,7 @@ pass locals to it. Layouts written in WLang and `yield` are supported, though. Templates are evaluated within the same context as route handlers. Instance variables set in route handlers are directly accessible by templates: -``` ruby +```ruby get '/:id' do @foo = Foo.find(params['id']) haml '%h1= @foo.name' @@ -1107,7 +1107,7 @@ end Or, specify an explicit Hash of local variables: -``` ruby +```ruby get '/:id' do foo = Foo.find(params['id']) haml '%h1= bar.name', :locals => { :bar => foo } @@ -1123,7 +1123,7 @@ A layout is usually just a template that calls `yield`. Such a template can be used either through the `:template` option as described above, or it can be rendered with a block as follows: -``` ruby +```ruby erb :post, :layout => false do erb :index end @@ -1133,7 +1133,7 @@ This code is mostly equivalent to `erb :index, :layout => :post`. Passing blocks to rendering methods is most useful for creating nested layouts: -``` ruby +```ruby erb :main_layout, :layout => false do erb :admin_layout do erb :user @@ -1143,7 +1143,7 @@ end This can also be done in fewer lines of code with: -``` ruby +```ruby erb :admin_layout, :layout => :main_layout do erb :user end @@ -1156,7 +1156,7 @@ Currently, the following rendering methods accept a block: `erb`, `haml`, Templates may be defined at the end of the source file: -``` ruby +```ruby require 'sinatra' get '/' do @@ -1181,7 +1181,7 @@ have inline templates in other source files. Templates may also be defined using the top-level `template` method: -``` ruby +```ruby template :layout do "%html\n =yield\n" end @@ -1200,7 +1200,7 @@ is rendered. You can individually disable layouts by passing `:layout => false` or disable them by default via `set :haml, :layout => false`: -``` ruby +```ruby get '/' do haml :index, :layout => !request.xhr? end @@ -1212,7 +1212,7 @@ To associate a file extension with a template engine, use `Tilt.register`. For instance, if you like to use the file extension `tt` for Textile templates, you can do the following: -``` ruby +```ruby Tilt.register :tt, Tilt[:textile] ``` @@ -1220,7 +1220,7 @@ Tilt.register :tt, Tilt[:textile] First, register your engine with Tilt, then create a rendering method: -``` ruby +```ruby Tilt.register :myat, MyAwesomeTemplateEngine helpers do @@ -1240,7 +1240,7 @@ learn more about Tilt. To implement your own template lookup mechanism you can write your own `#find_template` method: -``` ruby +```ruby configure do set :views [ './views/a', './views/b' ] end @@ -1258,7 +1258,7 @@ Before filters are evaluated before each request within the same context as the routes will be and can modify the request and response. Instance variables set in filters are accessible by routes and templates: -``` ruby +```ruby before do @note = 'Hi!' request.path_info = '/foo/bar/baz' @@ -1274,7 +1274,7 @@ After filters are evaluated after each request within the same context as the routes will be and can also modify the request and response. Instance variables set in before filters and routes are accessible by after filters: -``` ruby +```ruby after do puts response.status end @@ -1287,7 +1287,7 @@ generated later on. Filters optionally take a pattern, causing them to be evaluated only if the request path matches that pattern: -``` ruby +```ruby before '/protected/*' do authenticate! end @@ -1299,7 +1299,7 @@ end Like routes, filters also take conditions: -``` ruby +```ruby before :agent => /Songbird/ do # ... end @@ -1314,7 +1314,7 @@ end Use the top-level `helpers` method to define helper methods for use in route handlers and templates: -``` ruby +```ruby helpers do def bar(name) "#{name}bar" @@ -1328,7 +1328,7 @@ end Alternatively, helper methods can be separately defined in a module: -``` ruby +```ruby module FooUtils def foo(name) "#{name}foo" end end @@ -1347,7 +1347,7 @@ The effect is the same as including the modules in the application class. A session is used to keep state during requests. If activated, you have one session hash per user session: -``` ruby +```ruby enable :sessions get '/' do @@ -1365,7 +1365,7 @@ traffic, for instance). You can use any Rack session middleware: in order to do so, do **not** call `enable :sessions`, but instead pull in your middleware of choice as you would any other middleware: -``` ruby +```ruby use Rack::Session::Pool, :expire_after => 2592000 get '/' do @@ -1382,21 +1382,21 @@ secret. A random secret is generated for you by Sinatra. However, since this secret will change with every start of your application, you might want to set the secret yourself, so all your application instances share it: -``` ruby +```ruby set :session_secret, 'super secret' ``` If you want to configure it further, you may also store a hash with options in the `sessions` setting: -``` ruby +```ruby set :sessions, :domain => 'foo.com' ``` To share your session across other apps on subdomains of foo.com, prefix the domain with a *.* like this instead: -``` ruby +```ruby set :sessions, :domain => '.foo.com' ``` @@ -1404,37 +1404,37 @@ set :sessions, :domain => '.foo.com' To immediately stop a request within a filter or route use: -``` ruby +```ruby halt ``` You can also specify the status when halting: -``` ruby +```ruby halt 410 ``` Or the body: -``` ruby +```ruby halt 'this will be the body' ``` Or both: -``` ruby +```ruby halt 401, 'go away!' ``` With headers: -``` ruby +```ruby halt 402, {'Content-Type' => 'text/plain'}, 'revenge' ``` It is of course possible to combine a template with `halt`: -``` ruby +```ruby halt erb(:error) ``` @@ -1442,7 +1442,7 @@ halt erb(:error) A route can punt processing to the next matching route using `pass`: -``` ruby +```ruby get '/guess/:who' do pass unless params['who'] == 'Frank' 'You got me!' @@ -1461,7 +1461,7 @@ matching route. If no matching route is found, a 404 is returned. Sometimes `pass` is not what you want, instead you would like to get the result of calling another route. Simply use `call` to achieve this: -``` ruby +```ruby get '/foo' do status, headers, body = call env.merge("PATH_INFO" => '/bar') [status, headers, body.map(&:upcase)] @@ -1488,7 +1488,7 @@ set the body at an arbitrary point in the execution flow. You can do so with the `body` helper method. If you do so, you can use that method from there on to access the body: -``` ruby +```ruby get '/foo' do body "bar" end @@ -1503,7 +1503,7 @@ Rack handler (this can be used to implement streaming, see "Return Values"). Similar to the body, you can also set the status code and headers: -``` ruby +```ruby get '/foo' do status 418 headers \ @@ -1523,7 +1523,7 @@ the response body. In extreme examples, you want to keep sending data until the client closes the connection. You can use the `stream` helper to avoid creating your own wrapper: -``` ruby +```ruby get '/' do stream do |out| out << "It's gonna be legen -\n" @@ -1552,7 +1552,7 @@ the stream object, allowing you to close it at any later point in the execution flow. This only works on evented servers, like Thin and Rainbows. Other servers will still close the stream: -``` ruby +```ruby # long polling set :server, :thin @@ -1585,7 +1585,7 @@ end In the request scope, the `logger` helper exposes a `Logger` instance: -``` ruby +```ruby get '/' do logger.info "loading data" # ... @@ -1599,7 +1599,7 @@ you do not have to worry about it in your routes and filters. Note that logging is only enabled for `Sinatra::Application` by default, so if you inherit from `Sinatra::Base`, you probably want to enable it yourself: -``` ruby +```ruby class MyApp < Sinatra::Base configure :production, :development do enable :logging @@ -1617,7 +1617,7 @@ whatever it will find in `env['rack.logger']`. When using `send_file` or static files you may have mime types Sinatra doesn't understand. Use `mime_type` to register them by file extension: -``` ruby +```ruby configure do mime_type :foo, 'text/foo' end @@ -1625,7 +1625,7 @@ end You can also use it with the `content_type` helper: -``` ruby +```ruby get '/' do content_type :foo "foo foo foo" @@ -1637,7 +1637,7 @@ end For generating URLs you should use the `url` helper method, for instance, in Haml: -``` ruby +```ruby %a{:href => url('/foo')} foo ``` @@ -1649,7 +1649,7 @@ This method is also aliased to `to` (see below for an example). You can trigger a browser redirect with the `redirect` helper method: -``` ruby +```ruby get '/foo' do redirect to('/bar') end @@ -1657,7 +1657,7 @@ end Any additional parameters are handled like arguments passed to `halt`: -``` ruby +```ruby redirect to('/bar'), 303 redirect 'http://google.com', 'wrong place, buddy' ``` @@ -1665,7 +1665,7 @@ redirect 'http://google.com', 'wrong place, buddy' You can also easily redirect back to the page the user came from with `redirect back`: -``` ruby +```ruby get '/foo' do "do something" end @@ -1678,13 +1678,13 @@ end To pass arguments with a redirect, either add them to the query: -``` ruby +```ruby redirect to('/bar?sum=42') ``` Or use a session: -``` ruby +```ruby enable :sessions get '/foo' do @@ -1703,7 +1703,7 @@ Setting your headers correctly is the foundation for proper HTTP caching. You can easily set the Cache-Control header like this: -``` ruby +```ruby get '/' do cache_control :public "cache it!" @@ -1712,7 +1712,7 @@ end Pro tip: Set up caching in a before filter: -``` ruby +```ruby before do cache_control :public, :must_revalidate, :max_age => 60 end @@ -1721,7 +1721,7 @@ end If you are using the `expires` helper to set the corresponding header, `Cache-Control` will be set automatically for you: -``` ruby +```ruby before do expires 500, :public, :must_revalidate end @@ -1732,7 +1732,7 @@ It is recommended to call those helpers *before* doing any heavy lifting, as they will immediately flush a response if the client already has the current version in its cache: -``` ruby +```ruby get "/article/:id" do @article = Article.find params['id'] last_modified @article.updated_at @@ -1744,7 +1744,7 @@ end It is also possible to use a [weak ETag](http://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation): -``` ruby +```ruby etag @article.sha1, :weak ``` @@ -1752,7 +1752,7 @@ These helpers will not do any caching for you, but rather feed the necessary information to your cache. If you are looking for a quick reverse-proxy caching solution, try [rack-cache](https://github.com/rtomayko/rack-cache): -``` ruby +```ruby require "rack/cache" require "sinatra" @@ -1775,7 +1775,7 @@ and idempotent (like put) requests are already in existence, whereas other resources (for instance post requests) are treated as new resources. You can change this behavior by passing in a `:new_resource` option: -``` ruby +```ruby get '/create' do etag '', :new_resource => true Article.create @@ -1785,7 +1785,7 @@ end If you still want to use a weak ETag, pass in a `:kind` option: -``` ruby +```ruby etag '', :new_resource => true, :kind => :weak ``` @@ -1794,7 +1794,7 @@ etag '', :new_resource => true, :kind => :weak To return the contents of a file as the response, you can use the `send_file` helper method: -``` ruby +```ruby get '/' do send_file 'foo.png' end @@ -1802,7 +1802,7 @@ end It also takes options: -``` ruby +```ruby send_file 'foo.png', :type => :jpg ``` @@ -1843,7 +1843,7 @@ The options are: The incoming request object can be accessed from request level (filter, routes, error handlers) through the `request` method: -``` ruby +```ruby # app running on http://example.com/example get '/foo' do t = %w[text/css text/html application/javascript] @@ -1878,7 +1878,7 @@ end Some options, like `script_name` or `path_info`, can also be written: -``` ruby +```ruby before { request.path_info = "/" } get "/" do @@ -1888,7 +1888,7 @@ end The `request.body` is an IO or StringIO object: -``` ruby +```ruby post "/api" do request.body.rewind # in case someone already read it data = JSON.parse request.body.read @@ -1901,7 +1901,7 @@ end You can use the `attachment` helper to tell the browser the response should be stored on disk rather than displayed in the browser: -``` ruby +```ruby get '/' do attachment "store it!" @@ -1910,7 +1910,7 @@ end You can also pass it a file name: -``` ruby +```ruby get '/' do attachment "info.txt" "store it!" @@ -1922,7 +1922,7 @@ end Sinatra offers a `time_for` helper method that generates a Time object from the given value. It is also able to convert `DateTime`, `Date` and similar classes: -``` ruby +```ruby get '/' do pass if Time.now > time_for('Dec 23, 2012') "still time" @@ -1933,7 +1933,7 @@ This method is used internally by `expires`, `last_modified` and akin. You can therefore easily extend the behavior of those methods by overriding `time_for` in your application: -``` ruby +```ruby helpers do def time_for(value) case value @@ -1955,7 +1955,7 @@ end The `find_template` helper is used to find template files for rendering: -``` ruby +```ruby find_template settings.views, 'foo', Tilt[:haml] do |file| puts "could be #{file}" end @@ -1965,7 +1965,7 @@ This is not really useful. But it is useful that you can actually override this method to hook in your own lookup mechanism. For instance, if you want to be able to use more than one view directory: -``` ruby +```ruby set :views, ['views', 'templates'] helpers do @@ -1977,7 +1977,7 @@ end Another example would be using different directories for different engines: -``` ruby +```ruby set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views' helpers do @@ -2002,7 +2002,7 @@ method. Run once, at startup, in any environment: -``` ruby +```ruby configure do # setting one option set :option, 'value' @@ -2024,7 +2024,7 @@ end Run only when the environment (`RACK_ENV` environment variable) is set to `:production`: -``` ruby +```ruby configure :production do ... end @@ -2040,7 +2040,7 @@ end You can access those options via `settings`: -``` ruby +```ruby configure do set :foo, 'bar' end @@ -2060,18 +2060,18 @@ your application against common, opportunistic attacks. You can easily disable this behavior (which will open up your application to tons of common vulnerabilities): -``` ruby +```ruby disable :protection ``` To skip a single defense layer, set `protection` to an options hash: -``` ruby +```ruby set :protection, :except => :path_traversal ``` You can also hand in an array in order to disable a list of protections: -``` ruby +```ruby set :protection, :except => [:path_traversal, :session_hijacking] ``` @@ -2080,7 +2080,7 @@ has been enabled. Sometimes you want to set up sessions on your own, though. In that case you can get it to set up session based protections by passing the `:session` option: -``` ruby +```ruby use Rack::Session::Pool set :protection, :session => true ``` @@ -2272,14 +2272,14 @@ handlers display stack traces in your browser. In the `"production"` and To run different environments, set the `RACK_ENV` environment variable: -``` shell +```shell RACK_ENV=production ruby my_app.rb ``` You can use predefined methods: `development?`, `test?` and `production?` to check the current environment setting: -``` ruby +```ruby get '/' do if settings.development? "development!" @@ -2300,7 +2300,7 @@ means you get all the goodies it has to offer, like `haml`, When a `Sinatra::NotFound` exception is raised, or the response's status code is 404, the `not_found` handler is invoked: -``` ruby +```ruby not_found do 'This is nowhere to be found.' end @@ -2318,7 +2318,7 @@ set :show_exceptions, :after_handler The exception object can be obtained from the `sinatra.error` Rack variable: -``` ruby +```ruby error do 'Sorry there was a nasty error - ' + env['sinatra.error'].message end @@ -2326,7 +2326,7 @@ end Custom errors: -``` ruby +```ruby error MyCustomError do 'So what happened was...' + env['sinatra.error'].message end @@ -2334,7 +2334,7 @@ end Then, if this happens: -``` ruby +```ruby get '/' do raise MyCustomError, 'something bad' end @@ -2348,7 +2348,7 @@ So what happened was... something bad Alternatively, you can install an error handler for a status code: -``` ruby +```ruby error 403 do 'Access forbidden' end @@ -2360,7 +2360,7 @@ end Or a range: -``` ruby +```ruby error 400..510 do 'Boom' end @@ -2381,7 +2381,7 @@ HTTP request/response to provide various types of common functionality. Sinatra makes building Rack middleware pipelines a cinch via a top-level `use` method: -``` ruby +```ruby require 'sinatra' require 'my_custom_middleware' @@ -2398,7 +2398,7 @@ The semantics of `use` are identical to those defined for the (most frequently used from rackup files). For example, the `use` method accepts multiple/variable args as well as blocks: -``` ruby +```ruby use Rack::Auth::Basic do |username, password| username == 'admin' && password == 'secret' end @@ -2420,7 +2420,7 @@ Sinatra tests can be written using any Rack-based testing library or framework. [Rack::Test](http://rdoc.info/github/brynary/rack-test/master/frames) is recommended: -``` ruby +```ruby require 'my_sinatra_app' require 'minitest/autorun' require 'rack/test' @@ -2462,7 +2462,7 @@ Sinatra extensions. The top-level assumes a micro-app style configuration directories, logging, exception detail page, etc.). That's where `Sinatra::Base` comes into play: -``` ruby +```ruby require 'sinatra/base' class MyApp < Sinatra::Base @@ -2493,7 +2493,7 @@ behavior more similar to when you define your app at the top level (also known as Classic style), you can subclass `Sinatra::Application`. -``` ruby +```ruby require 'sinatra/base' class MyApp < Sinatra::Application @@ -2572,7 +2572,7 @@ different default settings: There are two common options for starting a modular app, actively starting with `run!`: -``` ruby +```ruby # my_app.rb require 'sinatra/base' @@ -2586,13 +2586,13 @@ end Start with: -``` shell +```shell ruby my_app.rb ``` Or with a `config.ru` file, which allows using any Rack handler: -``` ruby +```ruby # config.ru (run with rackup) require './my_app' run MyApp @@ -2600,7 +2600,7 @@ run MyApp Run: -``` shell +```shell rackup -p 4567 ``` @@ -2608,7 +2608,7 @@ rackup -p 4567 Write your app file: -``` ruby +```ruby # app.rb require 'sinatra' @@ -2619,7 +2619,7 @@ end And a corresponding `config.ru`: -``` ruby +```ruby require './app' run Sinatra::Application ``` @@ -2644,7 +2644,7 @@ can in turn be added in front of any Rack endpoint as middleware itself. This endpoint could be another Sinatra application, or any other Rack-based application (Rails/Ramaze/Camping/...): -``` ruby +```ruby require 'sinatra/base' class LoginScreen < Sinatra::Base @@ -2680,7 +2680,7 @@ end Sometimes you want to create new applications at runtime without having to assign them to a constant. You can do this with `Sinatra.new`: -``` ruby +```ruby require 'sinatra/base' my_app = Sinatra.new { get('/') { "hi" } } my_app.run! @@ -2711,7 +2711,7 @@ your own library. This also makes using Sinatra as middleware extremely easy: -``` ruby +```ruby require 'sinatra/base' use Sinatra do @@ -2737,7 +2737,7 @@ single application class for all requests. Options created via `set` are methods at class level: -``` ruby +```ruby class MyApp < Sinatra::Base # Hey, I'm in the application scope! set :foo, 42 @@ -2770,7 +2770,7 @@ can access the `request` and `session` objects or call rendering methods like `erb` or `haml`. You can access the application scope from within the request scope via the `settings` helper: -``` ruby +```ruby class MyApp < Sinatra::Base # Hey, I'm in the application scope! get '/define_route/:name' do @@ -2843,7 +2843,7 @@ the server, you'd have to specify the correct invocation method for the specific Rack handler. The following example is a demonstration of how to start a multi-threaded Thin server: -``` ruby +```ruby # app.rb require 'sinatra/base' @@ -2860,7 +2860,7 @@ App.run! To start the server, the command would be: -``` shell +```shell thin --threaded start ``` @@ -2944,7 +2944,7 @@ application against the master branch, it should be rather stable. We also push out prerelease gems from time to time, so you can do a -``` shell +```shell gem install sinatra --pre ``` @@ -2957,7 +2957,7 @@ If you want to run your application with the latest Sinatra, using First, install bundler, if you haven't: -``` shell +```shell gem install bundler ``` @@ -2978,7 +2978,7 @@ fetched and added by Bundler. Now you can run your app like this: -``` shell +```shell bundle exec ruby myapp.rb ``` @@ -2987,7 +2987,7 @@ bundle exec ruby myapp.rb Create a local clone and run your app with the `sinatra/lib` directory on the `$LOAD_PATH`: -``` shell +```shell cd myapp git clone git://github.com/sinatra/sinatra.git ruby -I sinatra/lib myapp.rb @@ -2995,7 +2995,7 @@ ruby -I sinatra/lib myapp.rb To update the Sinatra sources in the future: -``` shell +```shell cd myapp/sinatra git pull ``` @@ -3004,7 +3004,7 @@ git pull You can build the gem on your own: -``` shell +```shell git clone git://github.com/sinatra/sinatra.git cd sinatra rake sinatra.gemspec @@ -3013,7 +3013,7 @@ rake install If you install gems as root, the last step should be: -``` shell +```shell sudo rake install ``` diff --git a/README.pt-br.md b/README.pt-br.md index 20562d74..bfeea902 100644 --- a/README.pt-br.md +++ b/README.pt-br.md @@ -12,7 +12,7 @@ Alguns dos trechos de código a seguir utilizam caracteres UTF-8. Então, caso e Sinatra é uma [DSL](http://pt.wikipedia.org/wiki/Linguagem_de_domínio_específico) para criar aplicações web em Ruby com o mínimo de esforço e rapidez: -``` ruby +```ruby # minha_app.rb require 'sinatra' @@ -23,13 +23,13 @@ end Instale a gem: -``` shell +```shell gem install sinatra ``` Em seguida execute: -``` shell +```shell ruby minha_app.rb ``` @@ -102,7 +102,7 @@ Sinatra irá utilizá-la. No Sinatra, uma rota é um método HTTP emparelhado com um padrão de URL. Cada rota possui um bloco de execução: -``` ruby +```ruby get '/' do .. mostrando alguma coisa .. end @@ -134,7 +134,7 @@ rota encontrada responde a requisição. Padrões de rota podem conter parâmetros nomeados, acessíveis por meio do hash `params`: -``` ruby +```ruby get '/ola/:nome' do # corresponde a "GET /ola/foo" e "GET /ola/bar" # params['nome'] é 'foo' ou 'bar' @@ -145,7 +145,7 @@ end Você também pode acessar parâmetros nomeados por meio dos parâmetros de um bloco: -``` ruby +```ruby get '/ola/:nome' do |n| # corresponde a "GET /ola/foo" e "GET /ola/bar" # params['nome'] é 'foo' ou 'bar' @@ -157,7 +157,7 @@ end Padrões de rota também podem conter parâmetros splat (curinga), acessível por meio do array `params['splat']`: -``` ruby +```ruby get '/diga/*/para/*' do # corresponde a /diga/ola/para/mundo params['splat'] # => ["ola", "mundo"] @@ -171,7 +171,7 @@ end Ou com parâmetros de um bloco: -``` ruby +```ruby get '/download/*.*' do |caminho, ext| [caminho, ext] # => ["caminho/do/arquivo", "xml"] end @@ -179,7 +179,7 @@ end Rotas podem casar com expressões regulares: -``` ruby +```ruby get /\A\/ola\/([\w]+)\z/ do "Olá, #{params['captures'].first}!" end @@ -187,7 +187,7 @@ end Ou com parâmetros de um bloco: -``` ruby +```ruby get %r{/ola/([\w]+)} do |c| # corresponde a "GET /meta/ola/mundo", "GET /ola/mundo/1234" etc. "Olá, #{c}!" @@ -196,7 +196,7 @@ end Padrões de rota podem contar com parâmetros opcionais: -``` ruby +```ruby get '/posts.?:formato?' do # corresponde a "GET /posts" e qualquer extensão "GET /posts.json", "GET /posts.xml", etc. end @@ -204,7 +204,7 @@ end Rotas também podem utilizar query strings: -``` ruby +```ruby get '/posts' do # corresponde a "GET /posts?titulo=foo&autor=bar" titulo = params['titulo'] @@ -221,7 +221,7 @@ comparação com as suas rotas. Rotas podem incluir uma variedade de condições, tal como o `user agent`: -``` ruby +```ruby get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do "Você está usando o Songbird versão #{params['agent'][0]}" end @@ -233,7 +233,7 @@ end Outras condições disponíveis são `host_name` e `provides`: -``` ruby +```ruby get '/', :host_name => /^admin\./ do "Área administrativa. Acesso negado!" end @@ -250,7 +250,7 @@ end Você pode facilmente definir suas próprias condições: -``` ruby +```ruby set(:probabilidade) { |valor| condition { rand <= valor } } get '/ganha_um_carro', :probabilidade => 0.1 do @@ -264,7 +264,7 @@ end Use splat, para uma condição que leva vários valores: -``` ruby +```ruby set(:auth) do |*roles| # <- observe o splat aqui condition do unless logged_in? && roles.any? {|role| current_user.in_role? role } @@ -306,7 +306,7 @@ retornar um código de status HTTP. Dessa forma, podemos implementar facilmente um exemplo de streaming: -``` ruby +```ruby class Stream def each 100.times { |i| yield "#{i}\n" } @@ -326,7 +326,7 @@ embutido para uso de padrões de String e expressões regulares como validadores de rota. No entanto, ele não pára por aí. Você pode facilmente definir os seus próprios validadores: -``` ruby +```ruby class AllButPattern Match = Struct.new(:captures) @@ -352,7 +352,7 @@ end Note que o exemplo acima pode ser robusto e complicado em excesso. Pode também ser implementado como: -``` ruby +```ruby get // do pass if request.path_info == "/index" # ... @@ -361,7 +361,7 @@ end Ou, usando algo mais denso à frente: -``` ruby +```ruby get %r{^(?!/index$)} do # ... end @@ -373,7 +373,7 @@ Arquivos estáticos são disponibilizados a partir do diretório `./public`. Você pode especificar um local diferente pela opção `:public_folder` -``` ruby +```ruby set :public_folder, File.dirname(__FILE__) + '/estatico' ``` @@ -385,7 +385,7 @@ Note que o nome do diretório público não é incluido na URL. Um arquivo Cada linguagem de template é exposta através de seu próprio método de renderização. Estes metodos simplesmente retornam uma string: -``` ruby +```ruby get '/' do erb :index end @@ -404,7 +404,7 @@ end Templates também aceitam um segundo argumento, um hash de opções: -``` ruby +```ruby get '/' do erb :index, :layout => :post end @@ -414,7 +414,7 @@ Isto irá renderizar a `views/index.erb` inclusa dentro da `views/post.erb` (o p Qualquer opção não reconhecida pelo Sinatra será passada adiante para o engine de template: -``` ruby +```ruby get '/' do haml :index, :format => :html5 end @@ -422,7 +422,7 @@ end Você também pode definir opções padrões para um tipo de template: -``` ruby +```ruby set :haml, :format => :html5 get '/' do @@ -477,7 +477,7 @@ Opções disponíveis:
A engine de template utilizada para renderizar seu layout. Útil para linguagens que não suportam templates de outra - forma. O padrão é a engine do template utilizado. Exemplo: + forma. O padrão é a engine do template utilizado. Exemplo: set :rdoc, :layout_engine => :erb
@@ -498,14 +498,14 @@ set :views, settings.root + '/templates' Uma coisa importante para se lembrar é que você sempre deve referenciar os templates utilizando *symbols*, mesmo que eles estejam em um subdiretório (neste caso use: -`:'subdir/template'` or `'subdir/template'.to_sym`). Você deve +`:'subdir/template'` or `'subdir/template'.to_sym`). Você deve utilizar um *symbol* porque senão o método de renderização irá renderizar qualquer outra string que você passe diretamente para ele ### Literal Templates -``` ruby +```ruby get '/' do haml '%div.title Olá Mundo' end @@ -517,7 +517,7 @@ Renderiza um template string. Algumas linguagens possuem multiplas implementações. Para especificar qual implementação deverá ser utilizada (e para ser *thread-safe*), você deve simplesmente requere-la primeiro: -``` ruby +```ruby require 'rdiscount' # ou require 'bluecloth' get('/') { markdown :index } ``` @@ -696,20 +696,20 @@ você quase sempre precisará passar o `locals` para ele. Não é possível chamar métodos por este template, nem passar *locals* para o mesmo. Portanto normalmente é utilizado junto a outra engine de renderização: -``` ruby +```ruby erb :overview, :locals => { :text => markdown(:introducao) } ``` Note que vcoê também pode chamar o método `markdown` dentro de outros templates: -``` ruby +```ruby %h1 Olá do Haml! %p= markdown(:saudacoes) ``` Já que você não pode chamar o Ruby pelo Markdown, você não pode utilizar um layout escrito em Markdown. Contudo é -possível utilizar outra engine de renderização como template, +possível utilizar outra engine de renderização como template, deve-se passar a `:layout_engine` como opção. @@ -729,20 +729,20 @@ deve-se passar a `:layout_engine` como opção. Não é possível chamar métodos por este template, nem passar *locals* para o mesmo. Portanto normalmente é utilizado junto a outra engine de renderização: -``` ruby +```ruby erb :overview, :locals => { :text => textile(:introducao) } ``` Note que vcoê também pode chamar o método `textile` dentro de outros templates: -``` ruby +```ruby %h1 Olá do Haml! %p= textile(:saudacoes) ``` Já que você não pode chamar o Ruby pelo Textile, você não pode utilizar um layout escrito em Textile. Contudo é -possível utilizar outra engine de renderização como template, +possível utilizar outra engine de renderização como template, deve-se passar a `:layout_engine` como opção. #### RDoc Templates @@ -764,20 +764,20 @@ deve-se passar a `:layout_engine` como opção. Não é possível chamar métodos por este template, nem passar *locals* para o mesmo. Portanto normalmente é utilizado junto a outra engine de renderização: -``` ruby +```ruby erb :overview, :locals => { :text => rdoc(:introducao) } ``` Note que vcoê também pode chamar o método `rdoc` dentro de outros templates: -``` ruby +```ruby %h1 Olá do Haml! %p= rdoc(:saudacoes) ``` Já que você não pode chamar o Ruby pelo RDoc, você não pode utilizar um layout escrito em RDoc. Contudo é -possível utilizar outra engine de renderização como template, +possível utilizar outra engine de renderização como template, deve-se passar a `:layout_engine` como opção. #### AsciiDoc Templates @@ -892,20 +892,20 @@ Este também recebe um bloco para templates (veja o exemplo). Não é possível chamar métodos por este template, nem passar *locals* para o mesmo. Portanto normalmente é utilizado junto a outra engine de renderização: -``` ruby +```ruby erb :overview, :locals => { :text => creole(:introduction) } ``` Note que vcoê também pode chamar o método `creole` dentro de outros templates: -``` ruby +```ruby %h1 Olá do Haml! %p= creole(:saudacoes) ``` Já que você não pode chamar o Ruby pelo Creole, você não pode utilizar um layout escrito em Creole. Contudo é -possível utilizar outra engine de renderização como template, +possível utilizar outra engine de renderização como template, deve-se passar a `:layout_engine` como opção. #### MediaWiki Templates @@ -929,20 +929,20 @@ It is not possible to call methods from MediaWiki markup, nor to pass locals to it. You therefore will usually use it in combination with another rendering engine: -``` ruby +```ruby erb :overview, :locals => { :text => mediawiki(:introduction) } ``` Note that you may also call the `mediawiki` method from within other templates: -``` ruby +```ruby %h1 Hello From Haml! %p= mediawiki(:greetings) ``` Já que você não pode chamar o Ruby pelo MediaWiki, você não pode utilizar um layout escrito em MediaWiki. Contudo é -possível utilizar outra engine de renderização como template, +possível utilizar outra engine de renderização como template, deve-se passar a `:layout_engine` como opção. #### CoffeeScript Templates @@ -995,7 +995,7 @@ deve-se passar a `:layout_engine` como opção. Antes que vcoê possa utilizar o template Stylus primeiro você deve carregar `stylus` e `stylus/tilt`: -``` ruby +```ruby require 'sinatra' require 'stylus' require 'stylus/tilt' @@ -1031,14 +1031,14 @@ end O código-fonte do template é executado como uma string Ruby e a variável resultante em json é convertida utilizando `#to_json`: -``` ruby +```ruby json = { :foo => 'bar' } json[:baz] = key ``` O `:callback` e `:variable` são opções que podem ser utilizadas para o objeto de renderização: -``` javascript +```javascript var resource = {"foo":"bar","baz":"qux"}; present(resource); ``` @@ -1070,7 +1070,7 @@ Templates são avaliados dentro do mesmo contexto como manipuladores de rota. Variáveis de instância setadas em rotas manipuladas são diretamente acessadas por templates: -``` ruby +```ruby get '/:id' do @foo = Foo.find(params['id']) haml '%h1= @foo.nome' @@ -1079,7 +1079,7 @@ end Ou, especifique um hash explícito para variáveis locais: -``` ruby +```ruby get '/:id' do foo = Foo.find(params['id']) haml '%h1= foo.nome', :locals => { :foo => foo } @@ -1091,10 +1091,10 @@ partials dentro de outros templates. ### Templates com `yield` e layouts aninhados -O layout geralmente é apenas um template que executa `yield`. +O layout geralmente é apenas um template que executa `yield`. Tal template pode ser utilizado pela opção `:template` descrita acima ou pode ser renderizado através de um bloco, como a seguir: -``` ruby +```ruby erb :post, :layout => false do erb :index end @@ -1104,7 +1104,7 @@ Este código é quase equivalente a `erb :index, :layout => :post` Passando blocos para os métodos de renderização é útil para criar layouts aninhados: -``` ruby +```ruby erb :main_layout, :layout => false do erb :admin_layout do erb :user @@ -1114,7 +1114,7 @@ end Também pode ser feito com menos linhas de código: -``` ruby +```ruby erb :admin_layout, :layout => :main_layout do erb :user end @@ -1127,7 +1127,7 @@ Atualmente os métodos listados aceitam blocos: `erb`, `haml`, Templates podem ser definidos no final do arquivo fonte(.rb): -``` ruby +```ruby require 'sinatra' get '/' do @@ -1153,7 +1153,7 @@ tem templates inline no outro arquivo fonte. Templates também podem ser definidos utilizando o método top-level `template`: -``` ruby +```ruby template :layout do "%html\n =yield\n" end @@ -1171,7 +1171,7 @@ Se existir um template com nome “layout”, ele será utilizado toda vez que um template for renderizado. Você pode desabilitar layouts passando `:layout => false`. -``` ruby +```ruby get '/' do haml :index, :layout => !request.xhr? end @@ -1181,7 +1181,7 @@ end Para associar uma extensão de arquivo com um engine de template use o método `Tilt.register`. Por exemplo, se você quiser usar a extensão `tt` para os templates Textile você pode fazer o seguinte: -``` ruby +```ruby Tilt.register :tt, Tilt[:textile] ``` @@ -1189,7 +1189,7 @@ Tilt.register :tt, Tilt[:textile] Primeiro registre seu engine utilizando o Tilt, e então crie um método de renderização: -``` ruby +```ruby Tilt.register :myat, MyAwesomeTemplateEngine helpers do @@ -1208,7 +1208,7 @@ https://github.com/rtomayko/tilt para saber mais sobre Tilt. Para implementar sua própria lógica para busca de templates você pode escrever seu próprio método `#find_template` -``` ruby +```ruby configure do set :views [ './views/a', './views/b' ] end @@ -1227,7 +1227,7 @@ da requisição e podem modificar a requisição e a reposta. Variáveis de instância setadas nos filtros são acessadas através de rotas e templates: -``` ruby +```ruby before do @nota = 'Oi!' request.path_info = '/foo/bar/baz' @@ -1244,7 +1244,7 @@ requisição e também podem modificar a requisição e a resposta. Variáveis d instância e rotas definidas nos filtros before são acessadas através dos filtros after: -``` ruby +```ruby after do puts response.status end @@ -1253,7 +1253,7 @@ end Filtros opcionalmente têm um padrão, fazendo com que sejam avaliados somente se o caminho do pedido coincidir com esse padrão: -``` ruby +```ruby before '/protected/*' do authenticate! end @@ -1268,7 +1268,7 @@ end Use o método de alto nível `helpers` para definir métodos auxiliares para utilizar em manipuladores de rotas e modelos: -``` ruby +```ruby helpers do def bar(nome) "#{nome}bar" @@ -1284,7 +1284,7 @@ end Sessões são usadas para manter um estado durante uma requisição. Se ativa, você terá disponível um hash de sessão para cada sessão de usuário: -``` ruby +```ruby enable :sessions get '/' do @@ -1298,7 +1298,7 @@ end Note que `enable :sessions` utilizará um cookie para guardar todos os dados da sessão. Isso nem sempre pode ser o que você quer (guardar muitos dados irá aumentar o seu tráfego, por exemplo). Você pode utilizar qualquer Rack middleware de sessão: para fazer isso **não** utilize o método `enable :sessions`, ao invés disso utilize seu middleware de sessão como utilizaria qualquer outro: -``` ruby +```ruby use Rack::Session::Pool, :expire_after => 2592000 get '/' do @@ -1312,19 +1312,19 @@ end Para melhorar a segurança, os dados da sessão guardados no cookie é assinado com uma chave secreta da sessão. Uma chave aleatória é gerada para você pelo Sinatra. Contudo, já que a chave mudará cada vez que você inicia sua aplicação, você talvez queira defini-la você mesmo para que todas as instâncias da aplicação compartilhe-a: -``` ruby +```ruby set :session_secret, 'super secret' ``` Se você quiser fazer outras configurações, você também pode guardar um hash com as opções nas configurações da `session`: -``` ruby +```ruby set :sessions, :domain => 'foo.com' ``` Para compartilhar sua sessão entre outros aplicativos em um subdomínio de foo.com, utilize o prefixo *.*: -``` ruby +```ruby set :sessions, :domain => '.foo.com' ``` @@ -1332,37 +1332,37 @@ set :sessions, :domain => '.foo.com' Para parar imediatamente uma requisição com um filtro ou rota utilize: -``` ruby +```ruby halt ``` Você também pode especificar o status quando parar… -``` ruby +```ruby halt 410 ``` Ou com corpo de texto… -``` ruby +```ruby halt 'isso será o corpo do texto' ``` Ou também… -``` ruby +```ruby halt 401, 'vamos embora!' ``` Com cabeçalhos… -``` ruby +```ruby halt 402, {'Content-Type' => 'text/plain'}, 'revanche' ``` É obviamente possivel combinar um template com o `halt`: -``` ruby +```ruby halt erb(:error) ``` @@ -1371,7 +1371,7 @@ halt erb(:error) Uma rota pode processar aposta para a próxima rota correspondente usando `pass`: -``` ruby +```ruby get '/adivinhar/:quem' do pass unless params['quem'] == 'Frank' 'Você me pegou!' @@ -1390,7 +1390,7 @@ próxima rota de parâmetro. Se o parâmetro da rota não for encontrado, um As vezes o `pass` não é o que você quer, ao invés dele talvez você queira obter o resultado chamando outra rota. Utilize o método `call` neste caso: -``` ruby +```ruby get '/foo' do status, headers, body = call env.merge("PATH_INFO" => '/bar') [status, headers, body.map(&:upcase)] @@ -1411,7 +1411,7 @@ Veja a especificação do Rack se você quer aprender mais sobre o `call`. Rodando uma vez, na inicialização, em qualquer ambiente: -``` ruby +```ruby configure do ... end @@ -1420,7 +1420,7 @@ end Rodando somente quando o ambiente (`RACK_ENV` environment variável) é setado para `:production`: -``` ruby +```ruby configure :production do ... end @@ -1428,7 +1428,7 @@ end Rodando quando o ambiente é setado para `:production` ou `:test`: -``` ruby +```ruby configure :production, :test do ... end @@ -1445,7 +1445,7 @@ oferecer, como `haml`, `erb`, `halt`, etc. Quando um `Sinatra::NotFound` exception é levantado, ou o código de status da reposta é 404, o manipulador `not_found` é invocado: -``` ruby +```ruby not_found do 'Isto está longe de ser encontrado' end @@ -1457,7 +1457,7 @@ O manipulador `error` é invocado toda a vez que uma exceção é lançada a partir de um bloco de rota ou um filtro. O objeto da exceção pode ser obtido a partir da variável Rack `sinatra.error`: -``` ruby +```ruby error do 'Desculpe, houve um erro desagradável - ' + env['sinatra.error'].message end @@ -1465,7 +1465,7 @@ end Erros customizados: -``` ruby +```ruby error MeuErroCustomizado do 'Então que aconteceu foi...' + env['sinatra.error'].message end @@ -1473,7 +1473,7 @@ end Então, se isso acontecer: -``` ruby +```ruby get '/' do raise MeuErroCustomizado, 'alguma coisa ruim' end @@ -1486,7 +1486,7 @@ Você receberá isso: Alternativamente, você pode instalar manipulador de erro para um código de status: -``` ruby +```ruby error 403 do 'Accesso negado' end @@ -1498,7 +1498,7 @@ end Ou um range: -``` ruby +```ruby error 400..510 do 'Boom' end @@ -1513,13 +1513,13 @@ Quando utilizamos `send_file` ou arquivos estáticos você pode ter mime types Sinatra não entendidos. Use `mime_type` para registrar eles por extensão de arquivos: -``` ruby +```ruby mime_type :foo, 'text/foo' ``` Você também pode utilizar isto com o helper `content_type`: -``` ruby +```ruby content_type :foo ``` @@ -1535,7 +1535,7 @@ vários tipos de funcionalidades comuns. O Sinatra faz construtores pipelines do middleware Rack facilmente em um nível superior utilizando o método `use`: -``` ruby +```ruby require 'sinatra' require 'meu_middleware_customizado' @@ -1552,7 +1552,7 @@ A semântica de `use` é idêntica aquela definida para a DSL (mais frequentemente utilizada para arquivos rackup). Por exemplo, o método `use` aceita múltiplos argumentos/variáveis bem como blocos: -``` ruby +```ruby use Rack::Auth::Basic do |usuario, senha| usuario == 'admin' && senha == 'secreto' end @@ -1569,7 +1569,7 @@ Testes no Sinatra podem ser escritos utilizando qualquer biblioteca ou framework de teste baseados no Rack. [Rack::Test](http://gitrdoc.com/brynary/rack-test) é recomendado: -``` ruby +```ruby require 'minha_aplicacao_sinatra' require 'rack/test' @@ -1611,7 +1611,7 @@ estilo de configuração de micro aplicativos (exemplo: uma simples arquivo de aplicação, diretórios `./public` e `./views`, logs, página de detalhes de exceção, etc.). É onde o `Sinatra::Base` entra em jogo: -``` ruby +```ruby require 'sinatra/base' class MinhaApp < Sinatra::Base @@ -1629,7 +1629,7 @@ um middleware Rack, uma aplicação Rack, ou metal Rails. Você pode utilizar ou executar esta classe com um arquivo rackup `config.ru`; ou, controlar um componente de servidor fornecendo como biblioteca: -``` ruby +```ruby MinhaApp.run! :host => 'localhost', :port => 9090 ``` @@ -1664,7 +1664,7 @@ principal](http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854 Aplicações Sinatra podem ser executadas diretamente: -``` shell +```shell ruby minhaapp.rb [-h] [-x] [-e AMBIENTE] [-p PORTA] [-o HOST] [-s SERVIDOR] ``` @@ -1690,7 +1690,7 @@ significaria que ao iniciar o servidor, você teria que espeficiar o método de para o Rack handler específico. Os seguintes exemplos é uma demonstração de como iniciar um servidor Thin multi-thread: -``` ruby +```ruby # app.rb require 'sinatra/base' @@ -1706,7 +1706,7 @@ App.run! Para iniciar o servidor seria: -``` shell +```shell thin --threaded start ``` @@ -1718,7 +1718,7 @@ Se você gostaria de utilizar o código da última versão do Sinatra, crie um clone local e execute sua aplicação com o diretório `sinatra/lib` no `LOAD_PATH`: -``` shell +```shell cd minhaapp git clone git://github.com/sinatra/sinatra.git ruby -I sinatra/lib minhaapp.rb @@ -1727,7 +1727,7 @@ ruby -I sinatra/lib minhaapp.rb Alternativamente, você pode adicionar o diretório do `sinatra/lib` no `LOAD_PATH` do seu aplicativo: -``` ruby +```ruby $LOAD_PATH.unshift File.dirname(__FILE__) + '/sinatra/lib' require 'rubygems' require 'sinatra' @@ -1739,7 +1739,7 @@ end Para atualizar o código do Sinatra no futuro: -``` shell +```shell cd meuprojeto/sinatra git pull ``` diff --git a/README.pt-pt.md b/README.pt-pt.md index 474d50ab..23915e0a 100644 --- a/README.pt-pt.md +++ b/README.pt-pt.md @@ -7,7 +7,7 @@ Sinatra é uma [DSL](http://pt.wikipedia.org/wiki/Linguagem_de_domínio_específico) para criar rapidamente aplicações web em Ruby com o mínimo de esforço: -``` ruby +```ruby # minhaapp.rb require 'rubygems' require 'sinatra' @@ -18,7 +18,7 @@ end Instale a gem e execute com: -``` shell +```shell sudo gem install sinatra ruby minhaapp.rb ``` @@ -30,7 +30,7 @@ Aceda em: [localhost:4567](http://localhost:4567) No Sinatra, uma rota é um metodo HTTP associado a uma URL correspondente padrão. Cada rota é associada a um bloco: -``` ruby +```ruby get '/' do .. mostrar algo .. end @@ -54,7 +54,7 @@ Rotas são encontradas na ordem em que são definidas. A primeira rota que Padrões de rota podem incluir parâmetros nomeados, acessíveis através da hash `params`: -``` ruby +```ruby get '/ola/:nome' do # corresponde a "GET /ola/foo" e "GET /ola/bar" # params['nome'] é 'foo' ou 'bar' @@ -64,7 +64,7 @@ end Pode também aceder a parâmetros nomeados através do bloco de parâmetros: -``` ruby +```ruby get '/ola/:nome' do |n| "Olá #{n}!" end @@ -73,7 +73,7 @@ end Padrões de rota podem também incluir parâmetros splat (asteriscos), acessíveis através do array `params['splat']`. -``` ruby +```ruby get '/diga/*/ao/*' do # corresponde a /diga/ola/ao/mundo params['splat'] # => ["ola", "mundo"] @@ -87,7 +87,7 @@ end Rotas correspondem-se com expressões regulares: -``` ruby +```ruby get /\A\/ola\/([\w]+)\z/ do "Olá, #{params['captures'].first}!" end @@ -95,7 +95,7 @@ end Ou com um bloco de parâmetro: -``` ruby +```ruby get %r{/ola/([\w]+)} do |c| "Olá, #{c}!" end @@ -104,7 +104,7 @@ end Rotas podem incluir uma variedade de condições correspondentes, por exemplo, o agente usuário: -``` ruby +```ruby get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do "Você está a utilizar a versão #{params['agent'][0]} do Songbird." end @@ -120,7 +120,7 @@ Arquivos estáticos são disponibilizados a partir do directório `./public`. Você pode especificar um local diferente através da opção `:public_folder` -``` ruby +```ruby set :public_folder, File.dirname(__FILE__) + '/estatico' ``` @@ -133,7 +133,7 @@ Note que o nome do directório público não é incluido no URL. Um arquivo Templates presumem-se estar localizados sob o directório `./views`. Para utilizar um directório de views diferente: -``` ruby +```ruby set :views, File.dirname(__FILE__) + '/modelo' ``` @@ -146,7 +146,7 @@ processar qualquer string passada directamente para elas. A gem/biblioteca haml é necessária para renderizar templates HAML: -``` ruby +```ruby # É necessário requerir 'haml' na aplicação. require 'haml' @@ -164,7 +164,7 @@ veja [Opções e Configurações](http://www.sinatrarb.com/configuration.html), e substitua em uma requisição individual. -``` ruby +```ruby set :haml, {:format => :html5 } # o formato padrão do Haml é :xhtml get '/' do @@ -174,7 +174,7 @@ end ### Erb Templates -``` ruby +```ruby # É necessário requerir 'erb' na aplicação. require 'erb' @@ -189,7 +189,7 @@ Renderiza `./views/index.erb` A gem/biblioteca erubis é necessária para renderizar templates erubis: -``` ruby +```ruby # É necessário requerir 'erubis' na aplicação. require 'erubis' @@ -204,7 +204,7 @@ Renderiza `./views/index.erubis` A gem/biblioteca builder é necessária para renderizar templates builder: -``` ruby +```ruby # É necessário requerir 'builder' na aplicação. require 'builder' @@ -220,7 +220,7 @@ Renderiza `./views/index.builder`. A gem/biblioteca sass é necessária para renderizar templates sass: -``` ruby +```ruby # É necessário requerir 'haml' ou 'sass' na aplicação. require 'sass' @@ -239,7 +239,7 @@ veja [Opções e Configurações](http://www.sinatrarb.com/configuration.html), e substitua em uma requisição individual. -``` ruby +```ruby set :sass, {:style => :compact } # o estilo padrão do Sass é :nested get '/stylesheet.css' do @@ -252,7 +252,7 @@ end A gem/biblioteca less é necessária para renderizar templates Less: -``` ruby +```ruby # É necessário requerir 'less' na aplicação. require 'less' @@ -266,7 +266,7 @@ Renderiza `./views/stylesheet.less`. ### Templates Inline -``` ruby +```ruby get '/' do haml '%div.title Olá Mundo' end @@ -280,7 +280,7 @@ Templates são avaliados dentro do mesmo contexto que os manipuladores de rota. Variáveis de instância definidas em rotas manipuladas são directamente acedidas por templates: -``` ruby +```ruby get '/:id' do @foo = Foo.find(params['id']) haml '%h1= @foo.nome' @@ -289,7 +289,7 @@ end Ou, especifique um hash explícito para variáveis locais: -``` ruby +```ruby get '/:id' do foo = Foo.find(params['id']) haml '%h1= foo.nome', :locals => { :foo => foo } @@ -303,7 +303,7 @@ Isso é tipicamente utilizado quando renderizamos templates parciais Templates podem ser definidos no final do arquivo fonte(.rb): -``` ruby +```ruby require 'rubygems' require 'sinatra' @@ -330,7 +330,7 @@ templates inline no outro arquivo fonte. Templates também podem ser definidos utilizando o método top-level `template`: -``` ruby +```ruby template :layout do "%html\n =yield\n" end @@ -348,7 +348,7 @@ Se existir um template com nome “layout”, ele será utilizado sempre que um template for renderizado. Pode desactivar layouts usando `:layout => false`. -``` ruby +```ruby get '/' do haml :index, :layout => !request.xhr? end @@ -359,7 +359,7 @@ end Use o método de alto nível `helpers` para definir métodos auxiliares para utilizar em manipuladores de rotas e modelos: -``` ruby +```ruby helpers do def bar(nome) "#{nome}bar" @@ -378,7 +378,7 @@ da requisição e podem modificar a requisição e a reposta. Variáveis de instância definidas nos filtros são acedidas através de rotas e templates: -``` ruby +```ruby before do @nota = 'Olá!' request.path_info = '/foo/bar/baz' @@ -395,7 +395,7 @@ requisição e também podem modificar o pedido e a resposta. Variáveis de instância definidas nos filtros before e rotas são acedidas através dos filtros after: -``` ruby +```ruby after do puts response.status end @@ -404,7 +404,7 @@ end Filtros opcionalmente têm um padrão, fazendo com que sejam avaliados somente se o caminho do pedido coincidir com esse padrão: -``` ruby +```ruby before '/protected/*' do autenticar! end @@ -419,31 +419,31 @@ end Para parar imediatamente uma requisição dentro de um filtro ou rota utilize: -``` ruby +```ruby halt ``` Pode também especificar o status ao parar… -``` ruby +```ruby halt 410 ``` Ou com um corpo de texto… -``` ruby +```ruby halt 'isto será o corpo de texto' ``` Ou também… -``` ruby +```ruby halt 401, 'vamos embora!' ``` Com cabeçalhos… -``` ruby +```ruby halt 402, {'Content-Type' => 'text/plain'}, 'revanche' ``` @@ -452,7 +452,7 @@ halt 402, {'Content-Type' => 'text/plain'}, 'revanche' Dentro de uma rota, pode passar para a próxima rota correspondente usando `pass`: -``` ruby +```ruby get '/adivinhar/:quem' do pass unless params['quem'] == 'Frank' 'Apanhaste-me!' @@ -471,7 +471,7 @@ próxima rota de parâmetro. Se o parâmetro da rota não for encontrado, um Correndo uma vez, na inicialização, em qualquer ambiente: -``` ruby +```ruby configure do ... end @@ -480,7 +480,7 @@ end Correndo somente quando o ambiente (`RACK_ENV` environment variável) é definido para `:production`: -``` ruby +```ruby configure :production do ... end @@ -488,7 +488,7 @@ end Correndo quando o ambiente é definido para `:production` ou `:test`: -``` ruby +```ruby configure :production, :test do ... end @@ -504,7 +504,7 @@ signifca que `haml`, `erb`, etc, estão disponíveis. Quando um `Sinatra::NotFound` exception é levantado, ou o código de status da reposta é 404, o manipulador `not_found` é invocado: -``` ruby +```ruby not_found do 'Isto está longe de ser encontrado' end @@ -516,7 +516,7 @@ O manipulador `error` é invocado sempre que uma exceção é lançada a partir de um bloco de rota ou um filtro. O objecto da exceção pode ser obtido a partir da variável Rack `sinatra.error`: -``` ruby +```ruby error do 'Peço desculpa, houve um erro desagradável - ' + env['sinatra.error'].message end @@ -524,7 +524,7 @@ end Erros personalizados: -``` ruby +```ruby error MeuErroPersonalizado do 'O que aconteceu foi...' + env['sinatra.error'].message end @@ -532,7 +532,7 @@ end Então, se isso acontecer: -``` ruby +```ruby get '/' do raise MeuErroPersonalizado, 'alguma coisa desagradável' end @@ -547,7 +547,7 @@ O que aconteceu foi...alguma coisa desagradável Alternativamente, pode definir um manipulador de erro para um código de status: -``` ruby +```ruby error 403 do 'Accesso negado' end @@ -559,7 +559,7 @@ end Ou um range (alcance): -``` ruby +```ruby error 400..510 do 'Boom' end @@ -574,13 +574,13 @@ Quando utilizamos `send_file` ou arquivos estáticos pode ter mime types Sinatra não entendidos. Use `mime_type` para os registar por extensão de arquivos: -``` ruby +```ruby mime_type :foo, 'text/foo' ``` Pode também utilizar isto com o helper `content_type`: -``` ruby +```ruby content_type :foo ``` @@ -596,7 +596,7 @@ para providenciar varios tipos de funcionalidades comuns. O Sinatra torna a construção de pipelines do middleware Rack fácil a um nível superior utilizando o método `use`: -``` ruby +```ruby require 'sinatra' require 'meu_middleware_personalizado' @@ -613,7 +613,7 @@ A semântica de `use` é idêntica aquela definida para a DSL (mais frequentemente utilizada para arquivos rackup). Por exemplo, o método `use` aceita múltiplos argumentos/variáveis, bem como blocos: -``` ruby +```ruby use Rack::Auth::Basic do |utilizador, senha| utilizador == 'admin' && senha == 'secreto' end @@ -631,7 +631,7 @@ Testes no Sinatra podem ser escritos utilizando qualquer biblioteca ou framework de teste baseados no Rack. [Rack::Test](http://gitrdoc.com/brynary/rack-test) é recomendado: -``` ruby +```ruby require 'minha_aplicacao_sinatra' require 'rack/test' @@ -673,7 +673,7 @@ estilo de configuração de micro aplicativos (exemplo: um simples arquivo de aplicação, directórios `./public` e `./views`, logs, página de detalhes de excepção, etc.). É onde o Sinatra::Base entra em jogo: -``` ruby +```ruby require 'sinatra/base' class MinhaApp < Sinatra::Base @@ -691,7 +691,7 @@ como um middleware Rack, uma aplicação Rack, ou metal Rails. Pode utilizar ou executar esta classe com um arquivo rackup `config.ru`; ou, controlar um componente de servidor fornecendo como biblioteca: -``` ruby +```ruby MinhaApp.run! :host => 'localhost', :port => 9090 ``` @@ -726,7 +726,7 @@ principal](http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854 As aplicações Sinatra podem ser executadas directamente: -``` shell +```shell ruby minhaapp.rb [-h] [-x] [-e AMBIENTE] [-p PORTA] [-o HOST] [-s SERVIDOR] ``` @@ -747,7 +747,7 @@ Se gostaria de utilizar o código da última versão do Sinatra, crie um clone local e execute sua aplicação com o directório `sinatra/lib` no `LOAD_PATH`: -``` shell +```shell cd minhaapp git clone git://github.com/sinatra/sinatra.git ruby -I sinatra/lib minhaapp.rb @@ -756,7 +756,7 @@ ruby -I sinatra/lib minhaapp.rb Alternativamente, pode adicionar o directório do `sinatra/lib` no `LOAD_PATH` do seu aplicativo: -``` ruby +```ruby $LOAD_PATH.unshift File.dirname(__FILE__) + '/sinatra/lib' require 'rubygems' require 'sinatra' @@ -768,7 +768,7 @@ end Para actualizar o código do Sinatra no futuro: -``` shell +```shell cd meuprojeto/sinatra git pull ``` diff --git a/README.ru.md b/README.ru.md index ad29f3af..703c4530 100644 --- a/README.ru.md +++ b/README.ru.md @@ -105,13 +105,13 @@ end Установите gem: -``` shell +```shell gem install sinatra ``` и запустите приложение с помощью: -``` shell +```shell ruby myapp.rb ``` @@ -1016,7 +1016,7 @@ erb :overview, :locals => { :text => mediawiki(:introduction) } Перед тем, как использовать шаблоны стилус, загрузите `stylus` и `stylus/tilt`: -``` ruby +```ruby require 'sinatra' require 'stylus' require 'stylus/tilt' @@ -1380,7 +1380,7 @@ set :sessions, :domain => 'foo.com' Чтобы сделать сессию доступной другим приложениям, размещенным на поддоменах foo.com, добавьте *.* перед доменом: -``` ruby +```ruby set :sessions, :domain => '.foo.com' ``` diff --git a/README.zh.md b/README.zh.md index 6ed584db..9cfe93b8 100644 --- a/README.zh.md +++ b/README.zh.md @@ -6,7 +6,7 @@ Sinatra是一个基于Ruby语言的[DSL](http://en.wikipedia.org/wiki/Domain-specific_language)( 领域专属语言),可以轻松、快速的创建web应用。 -~~~~ ruby +~~~~ruby # myapp.rb require 'sinatra' @@ -17,7 +17,7 @@ end 安装gem,然后运行: -~~~~ shell +~~~~shell gem install sinatra ruby myapp.rb ~~~~ @@ -26,7 +26,7 @@ ruby myapp.rb 这个时候访问地址将绑定到 127.0.0.1 和 localhost ,如果使用 vagrant 进行开发,访问会失败,此时就需要进行 ip 绑定了: -~~~~ shell +~~~~shell ruby myapp.rb -o 0.0.0.0 ~~~~ @@ -39,7 +39,7 @@ ruby myapp.rb -o 0.0.0.0 在Sinatra中,一个路由分为两部分:HTTP方法(GET, POST等)和URL匹配范式。 每个路由都有一个要执行的代码块: -~~~~ ruby +~~~~ruby get '/' do .. 显示内容 .. end @@ -75,7 +75,7 @@ end 路由范式可以包括具名参数,可通过`params`哈希表获得: -~~~~ ruby +~~~~ruby get '/hello/:name' do # 匹配 "GET /hello/foo" 和 "GET /hello/bar" # params['name'] 的值是 'foo' 或者 'bar' @@ -85,7 +85,7 @@ end 你同样可以通过代码块参数获得具名参数: -~~~~ ruby +~~~~ruby get '/hello/:name' do |n| "Hello #{n}!" end @@ -93,7 +93,7 @@ end 路由范式也可以包含通配符参数, 可以通过`params['splat']`数组获得。 -~~~~ ruby +~~~~ruby get '/say/*/to/*' do # 匹配 /say/hello/to/world params['splat'] # => ["hello", "world"] @@ -107,7 +107,7 @@ end 通过正则表达式匹配的路由: -~~~~ ruby +~~~~ruby get /\A\/hello\/([\w]+)\z/ do "Hello, #{params['captures'].first}!" end @@ -115,7 +115,7 @@ end 或者使用代码块参数: -~~~~ ruby +~~~~ruby get %r{/hello/([\w]+)} do |c| "Hello, #{c}!" end @@ -125,7 +125,7 @@ end 路由也可以包含多样的匹配条件,比如user agent: -~~~~ ruby +~~~~ruby get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do "你正在使用Songbird,版本是 #{params['agent'][0]}" end @@ -137,7 +137,7 @@ end 其他可选的条件是 `host_name` 和 `provides`: -~~~~ ruby +~~~~ruby get '/', :host_name => /^admin\./ do "管理员区域,无权进入!" end @@ -153,7 +153,7 @@ end 你也可以自定义条件: -~~~~ ruby +~~~~ruby set(:probability) { |value| condition { rand <= value } } get '/win_a_car', :probability => 0.1 do @@ -186,7 +186,7 @@ body对象或者HTTP状态码: 那样,我们可以轻松的实现例如流式传输的例子: -~~~~ ruby +~~~~ruby class Stream def each 100.times { |i| yield "#{i}\n" } @@ -201,7 +201,7 @@ get('/') { Stream.new } 如上显示,Sinatra内置了对于使用字符串和正则表达式作为路由匹配的支持。 但是,它并没有只限于此。 你可以非常容易地定义你自己的匹配器: -~~~~ ruby +~~~~ruby class AllButPattern Match = Struct.new(:captures) @@ -226,7 +226,7 @@ end 上面的例子可能太繁琐了, 因为它也可以用更简单的方式表述: -~~~~ ruby +~~~~ruby get // do pass if request.path_info == "/index" # ... @@ -235,7 +235,7 @@ end 或者,使用消极向前查找: -~~~~ ruby +~~~~ruby get %r{^(?!/index$)} do # ... end @@ -246,7 +246,7 @@ end 静态文件是从 `./public_folder` 目录提供服务。你可以通过设置`:public` 选项设定一个不同的位置: -~~~~ ruby +~~~~ruby set :public_folder, File.dirname(__FILE__) + '/static' ~~~~ @@ -258,7 +258,7 @@ set :public_folder, File.dirname(__FILE__) + '/static' 模板被假定直接位于`./views`目录。 要使用不同的视图目录: -~~~~ ruby +~~~~ruby set :views, File.dirname(__FILE__) + '/templates' ~~~~ @@ -270,7 +270,7 @@ set :views, File.dirname(__FILE__) + '/templates' 需要引入 `haml` gem/library以填充 HAML 模板: -~~~~ ruby +~~~~ruby # 你需要在你的应用中引入 haml require 'haml' @@ -286,7 +286,7 @@ end [选项和配置](http://www.sinatrarb.com/configuration.html), 也可以个别的被覆盖。 -~~~~ ruby +~~~~ruby set :haml, {:format => :html5 } # 默认的Haml输出格式是 :xhtml get '/' do @@ -296,7 +296,7 @@ end ### Erb模板 -~~~~ ruby +~~~~ruby # 你需要在你的应用中引入 erb require 'erb' @@ -311,7 +311,7 @@ end 需要引入 `erubis` gem/library以填充 erubis 模板: -~~~~ ruby +~~~~ruby # 你需要在你的应用中引入 erubis require 'erubis' @@ -324,7 +324,7 @@ end 使用Erubis代替Erb也是可能的: -~~~~ ruby +~~~~ruby require 'erubis' Tilt.register :erb, Tilt[:erubis] @@ -339,7 +339,7 @@ end 需要引入 `builder` gem/library 以填充 builder templates: -~~~~ ruby +~~~~ruby # 需要在你的应用中引入builder require 'builder' @@ -354,7 +354,7 @@ end 需要引入 `nokogiri` gem/library 以填充 nokogiri 模板: -~~~~ ruby +~~~~ruby # 需要在你的应用中引入 nokogiri require 'nokogiri' @@ -369,7 +369,7 @@ end 需要引入 `haml` 或者 `sass` gem/library 以填充 Sass 模板: -~~~~ ruby +~~~~ruby # 需要在你的应用中引入 haml 或者 sass require 'sass' @@ -386,7 +386,7 @@ end [选项和配置(英文)](http://www.sinatrarb.com/configuration.html), 也可以在个体的基础上覆盖。 -~~~~ ruby +~~~~ruby set :sass, {:style => :compact } # 默认的 Sass 样式是 :nested get '/stylesheet.css' do @@ -398,7 +398,7 @@ end 需要引入 `haml` 或者 `sass` gem/library 来填充 Scss templates: -~~~~ ruby +~~~~ruby # 需要在你的应用中引入 haml 或者 sass require 'sass' @@ -414,7 +414,7 @@ end [选项和配置(英文)](http://www.sinatrarb.com/configuration.html), 也可以在个体的基础上覆盖。 -~~~~ ruby +~~~~ruby set :scss, :style => :compact # default Scss style is :nested get '/stylesheet.css' do @@ -426,7 +426,7 @@ end 需要引入 `less` gem/library 以填充 Less 模板: -~~~~ ruby +~~~~ruby # 需要在你的应用中引入 less require 'less' @@ -441,7 +441,7 @@ end 需要引入 `liquid` gem/library 来填充 Liquid 模板: -~~~~ ruby +~~~~ruby # 需要在你的应用中引入 liquid require 'liquid' @@ -455,7 +455,7 @@ end 因为你不能在Liquid 模板中调用 Ruby 方法 (除了 `yield`) , 你几乎总是需要传递locals给它: -~~~~ ruby +~~~~ruby liquid :index, :locals => { :key => 'value' } ~~~~ @@ -463,7 +463,7 @@ liquid :index, :locals => { :key => 'value' } 需要引入 `rdiscount` gem/library 以填充 Markdown 模板: -~~~~ ruby +~~~~ruby # 需要在你的应用中引入rdiscount require "rdiscount" @@ -477,13 +477,13 @@ end 在markdown中是不可以调用方法的,也不可以传递 locals给它。 你因此一般会结合其他的填充引擎来使用它: -~~~~ ruby +~~~~ruby erb :overview, :locals => { :text => markdown(:introduction) } ~~~~ 请注意你也可以从其他模板中调用 markdown 方法: -~~~~ ruby +~~~~ruby %h1 Hello From Haml! %p= markdown(:greetings) ~~~~ @@ -492,7 +492,7 @@ erb :overview, :locals => { :text => markdown(:introduction) } 不过,使用其他填充引擎作为模版的布局是可能的, 通过传递`:layout_engine`选项: -~~~~ ruby +~~~~ruby get '/' do markdown :index, :layout_engine => :erb end @@ -502,7 +502,7 @@ end 请记住你可以全局设定这个选项: -~~~~ ruby +~~~~ruby set :markdown, :layout_engine => :haml, :layout => :post get '/' do @@ -515,7 +515,7 @@ end 也可能使用BlueCloth而不是RDiscount来解析Markdown文件: -~~~~ ruby +~~~~ruby require 'bluecloth' Tilt.register 'markdown', BlueClothTemplate @@ -533,7 +533,7 @@ end 需要引入 `RedCloth` gem/library 以填充 Textile 模板: -~~~~ ruby +~~~~ruby # 在你的应用中引入redcloth require "redcloth" @@ -547,13 +547,13 @@ end 在textile中是不可以调用方法的,也不可以传递 locals给它。 你因此一般会结合其他的填充引擎来使用它: -~~~~ ruby +~~~~ruby erb :overview, :locals => { :text => textile(:introduction) } ~~~~ 请注意你也可以从其他模板中调用`textile`方法: -~~~~ ruby +~~~~ruby %h1 Hello From Haml! %p= textile(:greetings) ~~~~ @@ -562,7 +562,7 @@ erb :overview, :locals => { :text => textile(:introduction) } 不过,使用其他填充引擎作为模版的布局是可能的, 通过传递`:layout_engine`选项: -~~~~ ruby +~~~~ruby get '/' do textile :index, :layout_engine => :erb end @@ -573,7 +573,7 @@ end 请记住你可以全局设定这个选项: -~~~~ ruby +~~~~ruby set :textile, :layout_engine => :haml, :layout => :post get '/' do @@ -588,7 +588,7 @@ end 需要引入 `RDoc` gem/library 以填充RDoc模板: -~~~~ ruby +~~~~ruby # 需要在你的应用中引入rdoc/markup/to_html require "rdoc" require "rdoc/markup/to_html" @@ -603,13 +603,13 @@ end 在rdoc中是不可以调用方法的,也不可以传递locals给它。 你因此一般会结合其他的填充引擎来使用它: -~~~~ ruby +~~~~ruby erb :overview, :locals => { :text => rdoc(:introduction) } ~~~~ 请注意你也可以从其他模板中调用`rdoc`方法: -~~~~ ruby +~~~~ruby %h1 Hello From Haml! %p= rdoc(:greetings) ~~~~ @@ -618,7 +618,7 @@ erb :overview, :locals => { :text => rdoc(:introduction) } 不过,使用其他填充引擎作为模版的布局是可能的, 通过传递`:layout_engine`选项: -~~~~ ruby +~~~~ruby get '/' do rdoc :index, :layout_engine => :erb end @@ -628,7 +628,7 @@ end 请记住你可以全局设定这个选项: -~~~~ ruby +~~~~ruby set :rdoc, :layout_engine => :haml, :layout => :post get '/' do @@ -643,7 +643,7 @@ end 需要引入 `radius` gem/library 以填充 Radius 模板: -~~~~ ruby +~~~~ruby # 需要在你的应用中引入radius require 'radius' @@ -657,7 +657,7 @@ end 因为你不能在Radius 模板中调用 Ruby 方法 (除了 `yield`) , 你几乎总是需要传递locals给它: -~~~~ ruby +~~~~ruby radius :index, :locals => { :key => 'value' } ~~~~ @@ -665,7 +665,7 @@ radius :index, :locals => { :key => 'value' } 需要引入`markaby` gem/library以填充Markaby模板: -~~~~ ruby +~~~~ruby #需要在你的应用中引入 markaby require 'markaby' @@ -678,7 +678,7 @@ end 你也可以使用嵌入的 Markaby: -~~~~ ruby +~~~~ruby get '/' do markaby { h1 "Welcome!" } end @@ -688,7 +688,7 @@ end 需要引入 `slim` gem/library 来填充 Slim 模板: -~~~~ ruby +~~~~ruby # 需要在你的应用中引入 slim require 'slim' @@ -703,7 +703,7 @@ end 需要引入 `creole` gem/library 来填充 Creole 模板: -~~~~ ruby +~~~~ruby # 需要在你的应用中引入 creole require 'creole' @@ -731,7 +731,7 @@ end 现在你可以调用 CoffeeScript 模版了: -~~~~ ruby +~~~~ruby # 需要在你的应用中引入coffee-script require 'coffee-script' @@ -744,7 +744,7 @@ end ### 嵌入模板字符串 -~~~~ ruby +~~~~ruby get '/' do haml '%div.title Hello World' end @@ -757,7 +757,7 @@ end 模板和路由执行器在同样的上下文求值。 在路由执行器中赋值的实例变量可以直接被模板访问。 -~~~~ ruby +~~~~ruby get '/:id' do @foo = Foo.find(params['id']) haml '%h1= @foo.name' @@ -766,7 +766,7 @@ end 或者,显式地指定一个本地变量的哈希: -~~~~ ruby +~~~~ruby get '/:id' do foo = Foo.find(params['id']) haml '%h1= foo.name', :locals => { :foo => foo } @@ -779,7 +779,7 @@ end 模板可以在源文件的末尾定义: -~~~~ ruby +~~~~ruby require 'sinatra' get '/' do @@ -804,7 +804,7 @@ __END__ 模板可以通过使用顶层 `template` 方法定义: -~~~~ ruby +~~~~ruby template :layout do "%html\n =yield\n" end @@ -822,7 +822,7 @@ end 你可以单独地通过传送 `:layout => false`来禁用, 或者通过`set :haml, :layout => false`来禁用他们。 -~~~~ ruby +~~~~ruby get '/' do haml :index, :layout => !request.xhr? end @@ -834,7 +834,7 @@ end `Tilt.register`。比如,如果你喜欢使用 `tt` 作为Textile模版的扩展名,你可以这样做: -~~~~ ruby +~~~~ruby Tilt.register :tt, Tilt[:textile] ~~~~ @@ -842,7 +842,7 @@ Tilt.register :tt, Tilt[:textile] 首先,通过Tilt注册你自己的引擎,然后创建一个填充方法: -~~~~ ruby +~~~~ruby Tilt.register :myat, MyAwesomeTemplateEngine helpers do @@ -863,7 +863,7 @@ end 前置过滤器在每个请求前,在请求的上下文环境中被执行, 而且可以修改请求和响应。 在过滤器中设定的实例变量可以被路由和模板访问: -~~~~ ruby +~~~~ruby before do @note = 'Hi!' request.path_info = '/foo/bar/baz' @@ -879,7 +879,7 @@ end 而且可以修改请求和响应。 在前置过滤器和路由中设定的实例变量可以被后置过滤器访问: -~~~~ ruby +~~~~ruby after do puts response.status end @@ -890,7 +890,7 @@ end 过滤器可以可选地带有范式, 只有请求路径满足该范式时才会执行: -~~~~ ruby +~~~~ruby before '/protected/*' do authenticate! end @@ -902,7 +902,7 @@ end 和路由一样,过滤器也可以带有条件: -~~~~ ruby +~~~~ruby before :agent => /Songbird/ do # ... end @@ -916,7 +916,7 @@ end 使用顶层的 `helpers` 方法来定义辅助方法, 以便在路由处理器和模板中使用: -~~~~ ruby +~~~~ruby helpers do def bar(name) "#{name}bar" @@ -933,7 +933,7 @@ end Session被用来在请求之间保持状态。如果被激活,每一个用户会话 对应有一个session哈希: -~~~~ ruby +~~~~ruby enable :sessions get '/' do @@ -950,7 +950,7 @@ end 你可以使用任何的Rack session中间件,为了这么做, \*不要\*调用 `enable :sessions`,而是 按照自己的需要引入你的中间件: -~~~~ ruby +~~~~ruby use Rack::Session::Pool, :expire_after => 2592000 get '/' do @@ -966,31 +966,31 @@ end 要想直接地停止请求,在过滤器或者路由中使用: -~~~~ ruby +~~~~ruby halt ~~~~ 你也可以指定挂起时的状态码: -~~~~ ruby +~~~~ruby halt 410 ~~~~ 或者消息体: -~~~~ ruby +~~~~ruby halt 'this will be the body' ~~~~ 或者两者; -~~~~ ruby +~~~~ruby halt 401, 'go away!' ~~~~ 也可以带消息头: -~~~~ ruby +~~~~ruby halt 402, {'Content-Type' => 'text/plain'}, 'revenge' ~~~~ @@ -998,7 +998,7 @@ halt 402, {'Content-Type' => 'text/plain'}, 'revenge' 一个路由可以放弃处理,将处理让给下一个匹配的路由,使用 `pass`: -~~~~ ruby +~~~~ruby get '/guess/:who' do pass unless params['who'] == 'Frank' 'You got me!' @@ -1017,7 +1017,7 @@ end 有些时候,`pass` 并不是你想要的,你希望得到的是另一个路由的结果 。简单的使用 `call` 可以做到这一点: -~~~~ ruby +~~~~ruby get '/foo' do status, headers, body = call env.merge("PATH_INFO" => '/bar') [status, headers, body.map(&:upcase)] @@ -1046,7 +1046,7 @@ end `body` 辅助方法这么做。 如果你这样做了, 你可以在那以后使用该方法获得消息体: -~~~~ ruby +~~~~ruby get '/foo' do body "bar" end @@ -1061,7 +1061,7 @@ end 和消息体类似,你也可以设定状态码和消息头: -~~~~ ruby +~~~~ruby get '/foo' do status 418 headers \ @@ -1079,13 +1079,13 @@ end 使用 `send_file` 或者静态文件的时候,Sinatra可能不能识别你的媒体类型。 使用 `mime_type` 通过文件扩展名来注册它们: -~~~~ ruby +~~~~ruby mime_type :foo, 'text/foo' ~~~~ 你也可以使用 `content_type` 辅助方法: -~~~~ ruby +~~~~ruby get '/' do content_type :foo "foo foo foo" @@ -1096,7 +1096,7 @@ end 为了生成URL,你需要使用 `url` 辅助方法, 例如,在Haml中: -~~~~ ruby +~~~~ruby %a{:href => url('/foo')} foo ~~~~ @@ -1108,7 +1108,7 @@ end 你可以通过 `redirect` 辅助方法触发浏览器重定向: -~~~~ ruby +~~~~ruby get '/foo' do redirect to('/bar') end @@ -1116,14 +1116,14 @@ end 其他参数的用法,与 `halt`相同: -~~~~ ruby +~~~~ruby redirect to('/bar'), 303 redirect 'http://google.com', 'wrong place, buddy' ~~~~ 用 `redirect back`可以把用户重定向到原始页面: -~~~~ ruby +~~~~ruby get '/foo' do "do something" end @@ -1136,13 +1136,13 @@ end 如果想传递参数给redirect,可以用query string: -~~~~ ruby +~~~~ruby redirect to('/bar?sum=42') ~~~~ 或者用session: -~~~~ ruby +~~~~ruby enable :sessions get '/foo' do @@ -1161,7 +1161,7 @@ end 你可以这样设定 Cache-Control 消息头: -~~~~ ruby +~~~~ruby get '/' do cache_control :public "cache it!" @@ -1170,7 +1170,7 @@ end 核心提示: 在前置过滤器中设定缓存. -~~~~ ruby +~~~~ruby before do cache_control :public, :must_revalidate, :max_age => 60 end @@ -1179,7 +1179,7 @@ end 如果你正在用 `expires` 辅助方法设定对应的消息头 `Cache-Control` 会自动设定: -~~~~ ruby +~~~~ruby before do expires 500, :public, :must_revalidate end @@ -1190,7 +1190,7 @@ end 如果客户端在缓存中已经有相关内容,就会立即得到显示。 -~~~~ ruby +~~~~ruby get '/article/:id' do @article = Article.find params['id'] last_modified @article.updated_at @@ -1203,7 +1203,7 @@ end ETag](http://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation) 也是有可能的: -~~~~ ruby +~~~~ruby etag @article.sha1, :weak ~~~~ @@ -1211,7 +1211,7 @@ etag @article.sha1, :weak 如果你在寻找缓存的快速解决方案,试试 [rack-cache](https://github.com/rtomayko/rack-cache): -~~~~ ruby +~~~~ruby require "rack/cache" require "sinatra" @@ -1228,7 +1228,7 @@ end 为了发送文件,你可以使用 `send_file` 辅助方法: -~~~~ ruby +~~~~ruby get '/' do send_file 'foo.png' end @@ -1236,7 +1236,7 @@ end 也可以带一些选项: -~~~~ ruby +~~~~ruby send_file 'foo.png', :type => :jpg ~~~~ @@ -1270,7 +1270,7 @@ send_file 'foo.png', :type => :jpg 传入的请求对象可以在请求层(过滤器,路由,错误处理) 通过 `request` 方法被访问: -~~~~ ruby +~~~~ruby # 在 http://example.com/example 上运行的应用 get '/foo' do request.body # 被客户端设定的请求体(见下) @@ -1301,7 +1301,7 @@ end 一些选项,例如 `script_name` 或者 `path_info` 也是可写的: -~~~~ ruby +~~~~ruby before { request.path_info = "/" } get "/" do @@ -1311,7 +1311,7 @@ end `request.body` 是一个IO或者StringIO对象: -~~~~ ruby +~~~~ruby post "/api" do request.body.rewind # 如果已经有人读了它 data = JSON.parse request.body.read @@ -1324,7 +1324,7 @@ end 你可以使用 `attachment` 辅助方法来告诉浏览器响应 应当被写入磁盘而不是在浏览器中显示。 -~~~~ ruby +~~~~ruby get '/' do attachment "store it!" @@ -1333,7 +1333,7 @@ end 你也可以传递一个文件名: -~~~~ ruby +~~~~ruby get '/' do attachment "info.txt" "store it!" @@ -1344,7 +1344,7 @@ end `find_template` 辅助方法被用于在填充时查找模板文件: -~~~~ ruby +~~~~ruby find_template settings.views, 'foo', Tilt[:haml] do |file| puts "could be #{file}" end @@ -1353,7 +1353,7 @@ end 这并不是很有用。但是在你需要重载这个方法 来实现你自己的查找机制的时候有用。 比如,如果你想支持多于一个视图目录: -~~~~ ruby +~~~~ruby set :views, ['views', 'templates'] helpers do @@ -1365,7 +1365,7 @@ end 另一个例子是为不同的引擎使用不同的目录: -~~~~ ruby +~~~~ruby set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views' helpers do @@ -1389,7 +1389,7 @@ end 运行一次,在启动的时候,在任何环境下: -~~~~ ruby +~~~~ruby configure do # setting one option set :option, 'value' @@ -1410,7 +1410,7 @@ end 只当环境 (RACK\_ENV environment 变量) 被设定为 `:production`的时候运行: -~~~~ ruby +~~~~ruby configure :production do ... end @@ -1418,7 +1418,7 @@ end 当环境被设定为 `:production` 或者 `:test`的时候运行: -~~~~ ruby +~~~~ruby configure :production, :test do ... end @@ -1426,7 +1426,7 @@ end 你可以使用 `settings` 获得这些配置: -~~~~ ruby +~~~~ruby configure do set :foo, 'bar' end @@ -1598,7 +1598,7 @@ end 当一个 `Sinatra::NotFound` 错误被抛出的时候, 或者响应状态码是404,`not_found` 处理器会被调用: -~~~~ ruby +~~~~ruby not_found do 'This is nowhere to be found' end @@ -1609,7 +1609,7 @@ end `error` 处理器,在任何路由代码块或者过滤器抛出异常的时候会被调用。 异常对象可以通过`sinatra.error` Rack 变量获得: -~~~~ ruby +~~~~ruby error do 'Sorry there was a nasty error - ' + env['sinatra.error'].message end @@ -1617,7 +1617,7 @@ end 自定义错误: -~~~~ ruby +~~~~ruby error MyCustomError do 'So what happened was...' + env['sinatra.error'].message end @@ -1625,7 +1625,7 @@ end 那么,当这个发生的时候: -~~~~ ruby +~~~~ruby get '/' do raise MyCustomError, 'something bad' end @@ -1637,7 +1637,7 @@ end 另一种替代方法是,为一个状态码安装错误处理器: -~~~~ ruby +~~~~ruby error 403 do 'Access forbidden' end @@ -1649,7 +1649,7 @@ end 或者一个范围: -~~~~ ruby +~~~~ruby error 400..510 do 'Boom' end @@ -1667,7 +1667,7 @@ Rack的一个最有趣的面向应用开发者的能力是支持“中间件” Sinatra 让建立Rack中间件管道异常简单, 通过顶层的 `use` 方法: -~~~~ ruby +~~~~ruby require 'sinatra' require 'my_custom_middleware' @@ -1684,7 +1684,7 @@ end DSL(在rack文件中最频繁使用)中定义的完全一样。例如,`use` 方法接受 多个/可变 参数,包括代码块: -~~~~ ruby +~~~~ruby use Rack::Auth::Basic do |username, password| username == 'admin' && password == 'secret' end @@ -1699,7 +1699,7 @@ Rack中分布有多样的标准中间件,针对日志, Sinatra的测试可以使用任何基于Rack的测试程序库或者框架来编写。 [Rack::Test](http://gitrdoc.com/brynary/rack-test) 是推荐候选: -~~~~ ruby +~~~~ruby require 'my_sinatra_app' require 'minitest/autorun' require 'rack/test' @@ -1741,7 +1741,7 @@ metal,带有服务器组件的简单程序库, ./views 目录,日志,异常细节页面,等等)。 这时应该让 Sinatra::Base 走到台前了: -~~~~ ruby +~~~~ruby require 'sinatra/base' class MyApp < Sinatra::Base @@ -1797,7 +1797,7 @@ Sinatra::Base子类可用的方法实际上就是通过顶层 DSL 可用的方 有两种方式运行一个模块化应用,使用 `run!`来运行: -~~~~ ruby +~~~~ruby # my_app.rb require 'sinatra/base' @@ -1815,7 +1815,7 @@ end 或者使用一个 `config.ru`,允许你使用任何Rack处理器: -~~~~ ruby +~~~~ruby # config.ru require './my_app' run MyApp @@ -1829,7 +1829,7 @@ run MyApp 编写你的应用: -~~~~ ruby +~~~~ruby # app.rb require 'sinatra' @@ -1840,7 +1840,7 @@ end 加入相应的 `config.ru`: -~~~~ ruby +~~~~ruby require './app' run Sinatra::Application ~~~~ @@ -1865,7 +1865,7 @@ run Sinatra::Application 这个端点可以是任何Sinatra应用,或者任何基于Rack的应用程序 (Rails/Ramaze/Camping/…)。 -~~~~ ruby +~~~~ruby require 'sinatra/base' class LoginScreen < Sinatra::Base @@ -1911,7 +1911,7 @@ Sinatra::Application,或者这个类就是你显式创建的子类。 通过 \`set\` 创建的选项是类层面的方法: -~~~~ ruby +~~~~ruby class MyApp < Sinatra::Base # 嘿,我在应用变量域! set :foo, 42 @@ -1947,7 +1947,7 @@ end \`haml\`。你可以在请求变量域当中通过\`settings\`辅助方法 访问应用变量域: -~~~~ ruby +~~~~ruby class MyApp < Sinatra::Base # 嘿,我在应用变量域! get '/define_route/:name' do @@ -2097,7 +2097,7 @@ Sinatra应该会运行在任何支持上述Ruby实现的操作系统。 然后,在你的项目目录下,创建一个 `Gemfile`: -~~~~ ruby +~~~~ruby source :rubygems gem 'sinatra', :git => "git://github.com/sinatra/sinatra.git"