diff --git a/AUTHORS.md b/AUTHORS.md index c32a1e65..c516ca30 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -4,14 +4,16 @@ Sinatra was designed and developed by Blake Mizerany in California. * **Konstantin Haase** (maintainer) * **Zachary Scott** -* **Katrina Owen** +* **Kashyap Kondamudi** * **Ashley Williams** +* **Trevor Bramble** ### Alumni * **Blake Mizerany** (creator) * **Ryan Tomayko** * **Simon Rozet** +* **Katrina Owen** ### Thanks diff --git a/README.de.md b/README.de.md index bdaf28e8..0ce1bffb 100644 --- a/README.de.md +++ b/README.de.md @@ -4,7 +4,7 @@ Umständen nicht auf dem aktuellen Stand (aktuell Sinatra 1.4.5).* Sinatra ist eine -[DSL](http://de.wikipedia.org/wiki/Domänenspezifische_Sprache), die das +[DSL](https://de.wikipedia.org/wiki/Domänenspezifische_Sprache), die das schnelle Erstellen von Webanwendungen in Ruby mit minimalem Aufwand ermöglicht: @@ -220,9 +220,9 @@ end Routen-Muster können auch mit optionalen Parametern ausgestattet werden: ```ruby -get '/posts.?:format?' do - # passt auf "GET /posts" sowie jegliche Erweiterung - # wie "GET /posts.json", "GET /posts.xml" etc. +get '/posts/:format?' do + # passt auf "GET /posts/" sowie jegliche Erweiterung + # wie "GET /posts/json", "GET /posts/xml" etc. end ``` @@ -608,7 +608,7 @@ Nimmt ebenso einen Block für Inline-Templates entgegen (siehe Beispiel). - + @@ -663,7 +663,7 @@ Nimmt ebenso einen Block für Inline-Templates entgegen (siehe Beispiel).
Abhängigkeitnokogirinokogiri
Dateierweiterung
- + @@ -681,7 +681,7 @@ Nimmt ebenso einen Block für Inline-Templates entgegen (siehe Beispiel).
Abhängigkeitlessless
Dateierweiterung
- + @@ -703,7 +703,7 @@ denen man Variablen weitergibt.
Abhängigkeitliquidliquid
Dateierweiterung
Abhängigkeit Eine der folgenden Bibliotheken: - RDiscount, + RDiscount, RedCarpet, BlueCloth, kramdown oder @@ -863,7 +863,7 @@ man üblicherweise locals verwenden wollen, mit denen man Variablen weitergibt. - + @@ -1011,7 +1011,7 @@ Templates zu verwenden und einen anderen für das Layout, indem die - +
Abhängigkeitmarkabymarkaby
Dateierweiterung
Abhängigkeit - + Stylus und eine Möglichkeit @@ -1540,8 +1540,8 @@ end ``` Damit lassen sich Streaming-APIs realisieren, sog. -[Server Sent Events](http://dev.w3.org/html5/eventsource/), die als Basis für -[WebSockets](http://en.wikipedia.org/wiki/WebSocket) dienen. Ebenso können sie +[Server Sent Events](https://w3c.github.io/eventsource/), die als Basis für +[WebSockets](https://en.wikipedia.org/wiki/WebSocket) dienen. Ebenso können sie verwendet werden, um den Durchsatz zu erhöhen, wenn ein Teil der Daten von langsamen Ressourcen abhängig ist. @@ -1672,7 +1672,7 @@ Weitere Parameter werden wie Argumente der `halt`-Methode behandelt: ```ruby redirect to('/bar'), 303 -redirect 'http://google.com', 'Hier bist du falsch' +redirect 'http://www.google.com/', 'Hier bist du falsch' ``` Ebenso leicht lässt sich ein Schritt zurück mit dem Alias `redirect back` @@ -1757,7 +1757,7 @@ end ``` ebenso ist es möglich einen -[schwachen ETag](http://de.wikipedia.org/wiki/HTTP_ETag) zu verwenden: +[schwachen ETag](https://de.wikipedia.org/wiki/HTTP_ETag) zu verwenden: ```ruby etag @article.sha1, :weak @@ -2073,7 +2073,7 @@ end #### Einstellung des Angriffsschutzes Sinatra verwendet -[Rack::Protection](https://github.com/rkh/rack-protection#readme), um die +[Rack::Protection](https://github.com/sinatra/rack-protection#readme), um die Anwendung vor häufig vorkommenden Angriffen zu schützen. Diese Voreinstellung lässt sich selbstverständlich deaktivieren, der damit verbundene Geschwindigkeitszuwachs steht aber in keinem Verhätnis zu den möglichen @@ -2360,7 +2360,7 @@ end ``` Die Semantik von `use` entspricht der gleichnamigen Methode der -[Rack::Builder](http://rubydoc.info/github/rack/rack/master/Rack/Builder)-DSL +[Rack::Builder](http://www.rubydoc.info/github/rack/rack/master/Rack/Builder)-DSL (meist verwendet in Rackup-Dateien). Ein Beispiel dafür ist, dass die `use`-Methode mehrere/verschiedene Argumente und auch Blöcke entgegennimmt: @@ -2383,7 +2383,7 @@ oder im [Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware). ## Testen Sinatra-Tests können mit jedem auf Rack aufbauendem Test-Framework geschrieben -werden. [Rack::Test](http://rdoc.info/github/brynary/rack-test/master/frames) +werden. [Rack::Test](http://www.rubydoc.info/github/brynary/rack-test/master/frames) wird empfohlen: ```ruby @@ -2464,7 +2464,7 @@ Veränderungen zu `Sinatra::Base` konvertiert werden: `Sinatra::Base` ist ein unbeschriebenes Blatt. Die meisten Optionen sind per Standard deaktiviert. Das betrifft auch den eingebauten Server. Siehe -[Optionen und Konfiguration](http://sinatra.github.com/configuration.html) für +[Optionen und Konfiguration](http://www.sinatrarb.com/configuration.html) für Details über mögliche Optionen. Damit eine App sich ähnlich wie eine klassische App verhält, kann man @@ -2541,7 +2541,7 @@ werden:
static truefalseFile.exist?(public_folder) true
@@ -2926,7 +2926,7 @@ gem install sinatra --pre ### Mit Bundler Wenn die Applikation mit der neuesten Version von Sinatra und -[Bundler](http://gembundler.com/) genutzt werden soll, empfehlen wir den +[Bundler](http://bundler.io) genutzt werden soll, empfehlen wir den nachfolgenden Weg. Soweit Bundler noch nicht installiert ist: @@ -3013,12 +3013,12 @@ SemVer und SemVerTag. ## Mehr -* [Projekt-Website](http://sinatra.github.com/) - Ergänzende Dokumentation, +* [Projekt-Website](http://www.sinatrarb.com/) - Ergänzende Dokumentation, News und Links zu anderen Ressourcen. -* [Mitmachen](http://sinatra.github.com/contributing.html) - Einen Fehler +* [Mitmachen](http://www.sinatrarb.com/contributing.html) - Einen Fehler gefunden? Brauchst du Hilfe? Hast du einen Patch? -* [Issue-Tracker](http://github.com/sinatra/sinatra/issues) -* [Twitter](http://twitter.com/sinatra) +* [Issue-Tracker](https://github.com/sinatra/sinatra/issues) +* [Twitter](https://twitter.com/sinatra) * [Mailing-Liste](http://groups.google.com/group/sinatrarb) * [#sinatra](irc://chat.freenode.net/#sinatra) auf http://freenode.net Es gibt dort auch immer wieder deutschsprachige Entwickler, die gerne weiterhelfen. @@ -3026,6 +3026,6 @@ SemVer und SemVerTag. * [Sinatra Recipes](http://recipes.sinatrarb.com/) Sinatra-Rezepte aus der Community * API Dokumentation für die [aktuelle - Version](http://rubydoc.info/gems/sinatra) oder für - [HEAD](http://rubydoc.info/github/sinatra/sinatra) auf http://rubydoc.info -* [CI Server](http://travis-ci.org/sinatra/sinatra) + Version](http://www.rubydoc.info//gems/sinatra) oder für + [HEAD](http://www.rubydoc.info/github/sinatra/sinatra) auf http://rubydoc.info +* [CI Server](https://travis-ci.org/sinatra/sinatra) diff --git a/README.es.md b/README.es.md index efd4aa37..3270dc44 100644 --- a/README.es.md +++ b/README.es.md @@ -3,7 +3,7 @@ *Atención: Este documento es una traducción de la versión en inglés y puede estar desactualizado.* Sinatra es un -[DSL](http://es.wikipedia.org/wiki/Lenguaje_específico_del_dominio) para +[DSL](https://es.wikipedia.org/wiki/Lenguaje_específico_del_dominio) para crear aplicaciones web rápidamente en Ruby con un mínimo esfuerzo: ```ruby @@ -22,7 +22,7 @@ gem install sinatra ruby miapp.rb ``` -Ver en . +Ver en [http://localhost:4567](http://localhost:4567). Se recomienda ejecutar `gem install thin`, porque Sinatra lo utilizará si está disponible. @@ -133,9 +133,9 @@ end Los patrones de ruta pueden contener parámetros opcionales: ```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. +get '/posts/:formato?' do + # coincide con "GET /posts/" y además admite cualquier extensión, por + # ejemplo, "GET /posts/json", "GET /posts/xml", etc. end ``` @@ -503,7 +503,7 @@ Además, acepta un bloque con la definición de la plantilla (ver ejemplo). - + @@ -556,7 +556,7 @@ Además, acepta un bloque con la definición de la plantilla (ver ejemplo).
Dependenciasnokogirinokogiri
Extensiones de Archivo
- + @@ -573,7 +573,7 @@ Además, acepta un bloque con la definición de la plantilla (ver ejemplo).
Dependenciaslessless
Extensiones de Archivo
- + @@ -594,7 +594,7 @@ plantilla Liquid, casi siempre va a querer pasarle locales.
Dependenciasliquidliquid
Extensiones de Archivo
Dependencias - RDiscount, + RDiscount, RedCarpet, BlueCloth, kramdown o @@ -727,7 +727,7 @@ plantilla Radius, casi siempre se necesita pasar locales. - + @@ -841,7 +841,7 @@ distinto al de la plantilla pasando la opción `:layout_engine`. - +
DependenciasMarkabyMarkaby
Extensiones de Archivo
Dependencias - + Stylus y un @@ -1324,8 +1324,8 @@ end ``` Podés implementar APIs de streaming, -[Server-Sent Events](http://dev.w3.org/html5/eventsource/) y puede ser usado -como base para [WebSockets](http://es.wikipedia.org/wiki/WebSockets). También +[Server-Sent Events](https://w3c.github.io/eventsource/) y puede ser usado +como base para [WebSockets](https://es.wikipedia.org/wiki/WebSockets). También puede ser usado para incrementar el throughput si solo una parte del contenido depende de un recurso lento. @@ -1441,7 +1441,7 @@ pasados a `halt`: ```ruby redirect to('/bar'), 303 -redirect 'http://google.com', 'te confundiste de lugar, compañero' +redirect 'http://www.google.com/', 'te confundiste de lugar, compañero' ``` También podés redireccionar fácilmente de vuelta hacia la página desde donde @@ -1526,7 +1526,7 @@ end ``` También es posible usar una -[weak ETag](http://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation): +[weak ETag](https://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation): ```ruby etag @articulo.sha1, :weak @@ -1841,7 +1841,7 @@ end ### Configurando la Protección de Ataques -Sinatra usa [Rack::Protection](https://github.com/rkh/rack-protection#readme) +Sinatra usa [Rack::Protection](https://github.com/sinatra/rack-protection#readme) para defender a tu aplicación de los ataques más comunes. Si por algún motivo, 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 @@ -2187,7 +2187,7 @@ end ``` La semántica de `use` es idéntica a la definida para el DSL -Rack::Builder[http://rubydoc.info/github/rack/rack/master/Rack/Builder] (más +Rack::Builder[http://www.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: @@ -2211,7 +2211,7 @@ o en la [Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware). 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): +[Rack::Test](http://www.rubydoc.info/github/brynary/rack-test/master/frames): ```ruby require 'mi_app_sinatra' @@ -2279,7 +2279,7 @@ aplicaciones top-level se pueden convertir en componentes `Sinatra::Base` es una pizarra en blanco. La mayoría de las opciones están desactivadas por defecto, incluyendo el servidor incorporado. Mirá -[Opciones y Configuraciones](http://sinatra.github.com/configuration.html) +[Opciones y Configuraciones](http://www.sinatrarb.com/configuration.html) para detalles sobre las opciones disponibles y su comportamiento. ### Estilo Modular vs. Clásico @@ -2336,7 +2336,7 @@ de ambos estilos:
static truefalseFile.exist?(public_folder)
@@ -2732,7 +2732,7 @@ Para obtener algunas de las últimas características. ### Con Bundler Esta es la manera recomendada para ejecutar tu aplicación sobre la última -versión de Sinatra usando [Bundler](http://gembundler.com/). +versión de Sinatra usando [Bundler](http://bundler.io). Primero, instalá Bundler si no lo hiciste todavía: @@ -2807,15 +2807,15 @@ siguiendo las especificaciones SemVer y SemVerTag. adicional, noticias, y enlaces a otros recursos. * [Contribuyendo](http://www.sinatrarb.com/contributing) - ¿Encontraste un error?. ¿Necesitás ayuda?. ¿Tenés un parche?. -* [Seguimiento de problemas](http://github.com/sinatra/sinatra/issues) -* [Twitter](http://twitter.com/sinatra) +* [Seguimiento de problemas](https://github.com/sinatra/sinatra/issues) +* [Twitter](https://twitter.com/sinatra) * [Lista de Correo](http://groups.google.com/group/sinatrarb/topics) * [IRC: #sinatra](irc://chat.freenode.net/#sinatra) en http://freenode.net * [Sinatra Book](https://github.com/sinatra/sinatra-book/) Tutorial (en inglés). * [Sinatra Recipes](http://recipes.sinatrarb.com/) Recetas contribuidas por la comunidad (en inglés). * Documentación de la API para la - [última versión liberada](http://rubydoc.info/gems/sinatra) o para la - [rama de desarrollo actual](http://rubydoc.info/github/sinatra/sinatra) - en http://rubydoc.info/ -* [Servidor de CI](http://travis-ci.org/sinatra/sinatra) + [última versión liberada](http://www.rubydoc.info/gems/sinatra) o para la + [rama de desarrollo actual](http://www.rubydoc.info/github/sinatra/sinatra) + en http://www.rubydoc.info/ +* [Servidor de CI](https://travis-ci.org/sinatra/sinatra) diff --git a/README.fr.md b/README.fr.md index b5504543..c2231534 100644 --- a/README.fr.md +++ b/README.fr.md @@ -2,7 +2,7 @@ *Attention : Ce document correspond à la traduction de la version anglaise et il n'est peut-être plus à jour.* -Sinatra est un [DSL](http://fr.wikipedia.org/wiki/Langage_dédié) pour +Sinatra est un [DSL](https://fr.wikipedia.org/wiki/Langage_dédié) pour créer rapidement et facilement des applications web en Ruby : ```ruby @@ -26,7 +26,8 @@ Puis lancez votre programme : ruby mon_application.rb ``` -Le résultat est visible sur : http://localhost:4567 +Le résultat est visible sur : +[http://localhost:4567](http://localhost:4567) Il est recommandé d'exécuter également `gem install thin`, pour que Sinatra utilise le server Thin quand il est disponible. @@ -225,8 +226,8 @@ end Les routes peuvent aussi comporter des paramètres optionnels : ```ruby -get '/articles.?:format?' do - # répond à "GET /articles" ou avec une extension "GET /articles.json", "GET /articles.xml" etc... +get '/articles/:format?' do + # répond à "GET /articles/" ou avec une extension "GET /articles/json", "GET /articles/xml" etc... end ``` @@ -616,7 +617,7 @@ exemple). - + @@ -672,7 +673,7 @@ exemple).
Dépendancesnokogirinokogiri
Extensions de fichier
- + @@ -690,7 +691,7 @@ exemple).
Dépendanceslessless
Extensions de fichier
- + @@ -713,7 +714,7 @@ locales.
Dépendancesliquidliquid
Extensions de fichier

Dépendances

Au choix : - RDiscount, + RDiscount, RedCarpet, BlueCloth, kramdown, @@ -849,7 +850,7 @@ Radius, vous aurez sûrement à lui passer des variables locales. - + @@ -966,7 +967,7 @@ en utilisant l'option `:layout_engine`. - +
DépendancesMarkabyMarkaby
Extensions de fichier
Dépendances - + Stylus et un @@ -1503,8 +1504,8 @@ end ``` Cela permet d'implémenter des API de streaming ou de -[Server Sent Events](http://dev.w3.org/html5/eventsource/) et peut servir de -base pour des [WebSockets](http://en.wikipedia.org/wiki/WebSocket). Vous +[Server Sent Events](https://w3c.github.io/eventsource/) et peut servir de +base pour des [WebSockets](https://en.wikipedia.org/wiki/WebSocket). Vous pouvez aussi l'employer pour augmenter le débit quand une partie du contenu provient d'une ressource lente. @@ -1635,7 +1636,7 @@ Tout paramètre additionnel sera utilisé comme argument pour la méthode ```ruby redirect to('/bar'), 303 -redirect 'http://google.com', 'mauvais endroit mon pote' +redirect 'http://www.google.com/', 'mauvais endroit mon pote' ``` Vous pouvez aussi rediriger vers la page dont l'utilisateur venait au moyen de @@ -1718,7 +1719,7 @@ end ``` Il est également possible d'utiliser un -[weak ETag](http://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation) : +[weak ETag](https://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation) : ```ruby etag @article.sha1, :weak @@ -2047,7 +2048,7 @@ end ### Se protéger des attaques -Sinatra utilise [Rack::Protection](https://github.com/rkh/rack-protection#readme) +Sinatra utilise [Rack::Protection](https://github.com/sinatra/rack-protection#readme) 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) : @@ -2356,7 +2357,7 @@ end ``` La sémantique de `use` est identique à celle définie dans le DSL de -[Rack::Builder](http://rubydoc.info/github/rack/rack/master/Rack/Builder) +[Rack::Builder](http://www.rubydoc.info/github/rack/rack/master/Rack/Builder) (le plus souvent utilisé dans un fichier `rackup`). Par exemple, la méthode `use` accepte divers arguments ainsi que des blocs : @@ -2447,7 +2448,7 @@ pour transformer la plupart des applications de haut niveau en un composant `Sinatra::Base` est une page blanche. La plupart des options sont désactivées par défaut, y compris le serveur intégré. Reportez-vous à -[Options et Configuration](http://sinatra.github.com/configuration.html) +[Options et Configuration](http://www.sinatrarb.com/configuration.html) pour plus d'informations sur les options et leur fonctionnement. Si vous 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 @@ -2523,7 +2524,7 @@ mineures en ce qui concerne les paramètres par défaut :
static truefalseFile.exist?(public_folder) true
@@ -2922,7 +2923,7 @@ Ce qui permet de bénéficier des toutes dernières fonctionnalités. ### Installer avec Bundler -Il est cependant conseillé de passer par [Bundler](http://gembundler.com/) pour +Il est cependant conseillé de passer par [Bundler](http://bundler.io) pour faire tourner votre application avec la dernière version de Sinatra. Pour commencer, installez bundler si nécessaire : @@ -3000,14 +3001,14 @@ SemVer que SemVerTag. de news, et des liens vers d'autres ressources. * [Contribuer](http://www.sinatrarb.com/contributing) - Vous avez trouvé un bug ? Besoin d'aide ? Vous avez un patch ? -* [Suivi des problèmes](http://github.com/sinatra/sinatra/issues) -* [Twitter](http://twitter.com/sinatra) +* [Suivi des problèmes](https://github.com/sinatra/sinatra/issues) +* [Twitter](https://twitter.com/sinatra) * [Mailing List](http://groups.google.com/group/sinatrarb/topics) * IRC : [#sinatra](irc://chat.freenode.net/#sinatra) sur http://freenode.net * [Sinatra Book](https://github.com/sinatra/sinatra-book/) Tutoriels et recettes * [Sinatra Recipes](http://recipes.sinatrarb.com/) trucs et astuces rédigés par la communauté -* Documentation API de la [dernière version](http://rubydoc.info/gems/sinatra) - ou du [HEAD courant](http://rubydoc.info/github/sinatra/sinatra) sur - http://rubydoc.info -* [CI server](http://travis-ci.org/sinatra/sinatra) +* Documentation API de la [dernière version](http://www.rubydoc.info/gems/sinatra) + ou du [HEAD courant](http://www.rubydoc.info/github/sinatra/sinatra) sur + http://www.rubydoc.info/ +* [CI server](https://travis-ci.org/sinatra/sinatra) diff --git a/README.hu.md b/README.hu.md index ff67ac2d..c12ad000 100644 --- a/README.hu.md +++ b/README.hu.md @@ -2,7 +2,7 @@ *Fontos megjegyzés: Ez a dokumentum csak egy fordítása az angol nyelvű változatnak, és lehet, hogy nem naprakész.* -A Sinatra egy [DSL](http://en.wikipedia.org/wiki/Domain-specific_language) +A Sinatra egy [DSL](https://en.wikipedia.org/wiki/Domain-specific_language) webalkalmazások Ruby nyelven történő fejlesztéséhez, minimális energiabefektetéssel: @@ -21,7 +21,7 @@ Telepítsd a gem-et és indítsd el az alkalmazást a következőképpen: ruby myapp.rb ``` -Az alkalmazás elérhető lesz itt: `http://localhost:4567` +Az alkalmazás elérhető lesz itt: [http://localhost:4567](http://localhost:4567) ## Útvonalak (routes) @@ -518,7 +518,7 @@ A Sinatra keretrendszerben gyerekjáték a Rack middleware-ek behúzása a ``` A `use` metódus szemantikája megegyezik a -[Rack::Builder](http://rubydoc.info/github/rack/rack/master/Rack/Builder) DSL-ben +[Rack::Builder](http://www.rubydoc.info/github/rack/rack/master/Rack/Builder) DSL-ben használt +use+ metóduséval (az említett DSL-t leginkább rackup állományokban használják). Hogy egy példát említsünk, a `use` metódus elfogad változókat és blokkokat egyaránt, akár kombinálva is ezeket: @@ -621,7 +621,7 @@ alkalmazás átalakítható Sinatra::Base alapú komponensekké két lépésben: A `Sinatra::Base` osztály igazából egy üres lap: a legtöbb funkció alapból ki van kapcsolva, beleértve a beépített szervert is. A beállításokkal és az egyes kapcsolók hatásával az -[Options and Configuration](http://sinatra.github.com/configuration.html) lap +[Options and Configuration](http://www.sinatrarb.com/configuration.html) lap foglalkozik. Széljegyzet: A Sinatra felső szintű DSL-je egy egyszerű delegációs @@ -684,11 +684,11 @@ A Sinatra frissítését később így végezheted el: ## További információk -* [A projekt weboldala](http://sinatra.github.com/) - Kiegészítő dokumentáció, +* [A projekt weboldala](http://www.sinatrarb.com/) - Kiegészítő dokumentáció, hírek, hasznos linkek -* [Közreműködés](http://sinatra.github.com/contributing.html) - Hibát találtál? +* [Közreműködés](http://www.sinatrarb.com/contributing.html) - Hibát találtál? Segítségre van szükséged? Foltot küldenél be? * [Lighthouse](http://sinatra.lighthouseapp.com) - Hibakövetés és kiadások -* [Twitter](http://twitter.com/sinatra) +* [Twitter](https://twitter.com/sinatra) * [Levelezőlista](http://groups.google.com/group/sinatrarb) * [IRC: #sinatra](irc://chat.freenode.net/#sinatra) a http://freenode.net címen diff --git a/README.ja.md b/README.ja.md index 077665cd..ee33d76f 100644 --- a/README.ja.md +++ b/README.ja.md @@ -3,7 +3,7 @@ *注) 本文書は英語から翻訳したものであり、その内容が最新でない場合もあります。最新の情報はオリジナルの英語版を参照して下さい。* -Sinatraは最小の労力でRubyによるWebアプリケーションを手早く作るための[DSL](http://ja.wikipedia.org/wiki/ドメイン固有言語)です。 +Sinatraは最小の労力でRubyによるWebアプリケーションを手早く作るための[DSL](https://ja.wikipedia.org/wiki/メインページドメイン固有言語)です。 ```ruby # myapp.rb @@ -26,7 +26,7 @@ gem install sinatra ruby myapp.rb ``` -[localhost:4567](http://localhost:4567) を開きます。 +[http://localhost:4567](http://localhost:4567) を開きます。 ThinがあればSinatraはこれを利用するので、`gem install thin`することをお薦めします。 @@ -224,8 +224,8 @@ end ルーティングパターンは、オプショナルパラメータを取ることもできます。 ```ruby -get '/posts.?:format?' do - # "GET /posts" と "GET /posts.json", "GET /posts.xml" の拡張子などにマッチ +get '/posts/:format?' do + # "GET /posts/" と "GET /posts/json", "GET /posts/xml" の拡張子などにマッチ end ``` @@ -578,7 +578,7 @@ get('/') { markdown :index } - + @@ -633,7 +633,7 @@ get('/') { markdown :index }
依存nokogirinokogiri
ファイル拡張子
- + @@ -650,7 +650,7 @@ get('/') { markdown :index }
依存lessless
ファイル拡張子
- + @@ -671,7 +671,7 @@ LiquidテンプレートからRubyのメソッド(`yield`を除く)を呼び出
依存liquidliquid
ファイル拡張子依存 次の何れか: - RDiscount, + RDiscount, RedCarpet, BlueCloth, kramdown, @@ -816,7 +816,7 @@ RadiusテンプレートからRubyのメソッドを直接呼び出すことが - + @@ -952,7 +952,7 @@ erb :overview, :locals => { :text => mediawiki(:introduction) } - +
依存MarkabyMarkaby
ファイル拡張子
依存 - + Stylus および @@ -1426,7 +1426,7 @@ get '/' do end ``` -これはストリーミングAPI、[Server Sent Events](http://dev.w3.org/html5/eventsource/)の実装を可能にし、[WebSockets](http://en.wikipedia.org/wiki/WebSocket)の土台に使うことができます。また、一部のコンテンツが遅いリソースに依存しているときに、スループットを上げるために使うこともできます。 +これはストリーミングAPI、[Server Sent Events](https://w3c.github.io/eventsource/)の実装を可能にし、[WebSockets](https://en.wikipedia.org/wiki/WebSocket)の土台に使うことができます。また、一部のコンテンツが遅いリソースに依存しているときに、スループットを上げるために使うこともできます。 ノート: ストリーミングの挙動、特に並行リクエスト(cuncurrent requests)の数は、アプリケーションを提供するのに使われるWebサーバに強く依存します。いくつかのサーバは、ストリーミングを全くサポートしません。サーバがストリーミングをサポートしない場合、ボディは`stream`に渡されたブロックの実行が終了した後、一度に全部送られることになります。ストリーミングは、Shotgunを使った場合は全く動作しません。 @@ -1532,7 +1532,7 @@ end ```ruby redirect to('/bar'), 303 -redirect 'http://google.com', 'wrong place, buddy' +redirect 'http://www.google.com/', 'wrong place, buddy' ``` また、`redirect back`を使えば、簡単にユーザが来たページへ戻るリダイレクトを作れます。 @@ -1610,7 +1610,7 @@ get '/article/:id' do end ``` -また、[weak ETag](http://ja.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation)を使うこともできます。 +また、[weak ETag](https://ja.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation)を使うこともできます。 ```ruby etag @article.sha1, :weak @@ -1900,7 +1900,7 @@ end ### 攻撃防御に対する設定 -Sinatraは、[Rack::Protection](https://github.com/rkh/rack-protection#readme)を使って、アプリケーションを多発する日和見的攻撃から守っています。この挙動は簡単に無効化できます(これはアプリケーションを大量の脆弱性攻撃に晒すことになります)。 +Sinatraは、[Rack::Protection](https://github.com/sinatra/rack-protection#readme)を使って、アプリケーションを多発する日和見的攻撃から守っています。この挙動は簡単に無効化できます(これはアプリケーションを大量の脆弱性攻撃に晒すことになります)。 ```ruby disable :protection @@ -2177,7 +2177,7 @@ get '/hello' do end ``` -`use`の文法は、[Rack::Builder](http://rubydoc.info/github/rack/rack/master/Rack/Builder)DSLで定義されているそれ(rackupファイルで最もよく使われる)と同じです。例えば `use`メソッドは複数の引数、そしてブロックも取ることができます。 +`use`の文法は、[Rack::Builder](http://www.rubydoc.info/github/rack/rack/master/Rack/Builder)DSLで定義されているそれ(rackupファイルで最もよく使われる)と同じです。例えば `use`メソッドは複数の引数、そしてブロックも取ることができます。 ```ruby use Rack::Auth::Basic do |username, password| @@ -2195,7 +2195,7 @@ Rackは、ロギング、デバッギング、URLルーティング、認証、 ## テスト(Testing) -SinatraでのテストはRackベースのテストライブラリまたはフレームワークを使って書くことができます。[Rack::Test](http://rdoc.info/github/brynary/rack-test/master/frames)をお薦めします。 +SinatraでのテストはRackベースのテストライブラリまたはフレームワークを使って書くことができます。[Rack::Test](http://www.rubydoc.info/github/brynary/rack-test/master/frames)をお薦めします。 ```ruby require 'my_sinatra_app' @@ -2251,7 +2251,7 @@ end (そうしない場合、SinatraのDSLメソッドの全てがmainの名前空間にインポートされます) * ルーティング、エラーハンドラ、フィルタ、オプションを`Sinatra::Base`のサブクラスに書く -`Sinatra::Base`はまっさらです。ビルトインサーバを含む、ほとんどのオプションがデフォルトで無効になっています。利用可能なオプションとその挙動の詳細については[Configuring Settings](http://sinatra.github.com/configuration.html)(英語)をご覧下さい。 +`Sinatra::Base`はまっさらです。ビルトインサーバを含む、ほとんどのオプションがデフォルトで無効になっています。利用可能なオプションとその挙動の詳細については[Configuring Settings](http://www.sinatrarb.com/configuration.html)(英語)をご覧下さい。 もしもクラシックスタイルと同じような挙動のアプリケーションをトップレベルで定義させる必要があれば、`Sinatra::Application`をサブクラス化させてください。 @@ -2319,7 +2319,7 @@ end
static truefalseFile.exist?(public_folder) true
@@ -2676,7 +2676,7 @@ gem install sinatra --pre ### Bundlerを使う場合 -最新のSinatraでアプリケーションを動作させたい場合には、[Bundler](http://gembundler.com/)を使うのがお薦めのやり方です。 +最新のSinatraでアプリケーションを動作させたい場合には、[Bundler](http://bundler.io)を使うのがお薦めのやり方です。 まず、Bundlerがなければそれをインストールします。 @@ -2743,14 +2743,14 @@ Sinatraは、[Semantic Versioning](http://semver.org/)におけるSemVerおよ ## 参考文献 -* [プロジェクトサイト](http://sinatra.github.com/) - ドキュメント、ニュース、他のリソースへのリンクがあります。 -* [プロジェクトに参加(貢献)する](http://sinatra.github.com/contributing.html) - バグレポート パッチの送信、サポートなど -* [Issue tracker](http://github.com/sinatra/sinatra/issues) -* [Twitter](http://twitter.com/sinatra) +* [プロジェクトサイト](http://www.sinatrarb.com/) - ドキュメント、ニュース、他のリソースへのリンクがあります。 +* [プロジェクトに参加(貢献)する](http://www.sinatrarb.com/contributing.html) - バグレポート パッチの送信、サポートなど +* [Issue tracker](https://github.com/sinatra/sinatra/issues) +* [Twitter](https://twitter.com/sinatra) * [メーリングリスト](http://groups.google.com/group/sinatrarb/topics) * http://freenode.net上のIRC: [#sinatra](irc://chat.freenode.net/#sinatra) * [Sinatra Book](https://github.com/sinatra/sinatra-book/) クックブック、チュートリアル * [Sinatra Recipes](http://recipes.sinatrarb.com/) コミュニティによるレシピ集 -* http://rubydoc.info上のAPIドキュメント: [最新版(latest release)用](http://rubydoc.info/gems/sinatra)または[現在のHEAD用](http://rubydoc.info/github/sinatra/sinatra) -* [CIサーバ](http://travis-ci.org/sinatra/sinatra) +* http://www.rubydoc.info/上のAPIドキュメント: [最新版(latest release)用](http://www.rubydoc.info/gems/sinatra)または[現在のHEAD用](http://www.rubydoc.info/github/sinatra/sinatra) +* [CIサーバ](https://travis-ci.org/sinatra/sinatra) * [Greenbear Laboratory Rack日本語マニュアル](http://route477.net/w/RackReferenceJa.html) diff --git a/README.ko.md b/README.ko.md index a3a347f8..b95f9d66 100644 --- a/README.ko.md +++ b/README.ko.md @@ -3,7 +3,7 @@ *주의: 이 문서는 영문판의 번역본이며 최신판 문서와 다를 수 있습니다.* Sinatra는 최소한의 노력으로 루비 기반 웹 애플리케이션을 신속하게 만들 수 있게 -해 주는 [DSL](http://en.wikipedia.org/wiki/Domain-specific_language)입니다. +해 주는 [DSL](https://en.wikipedia.org/wiki/Domain-specific_language)입니다. ```ruby # myapp.rb @@ -14,19 +14,19 @@ get '/' do end ``` -젬을 설치합니다. +아래의 명령어로 젬을 설치합니다. ```shell gem install sinatra ``` -실행합니다. +아래의 명령어로 실행합니다. ```shell ruby myapp.rb ``` -`http://localhost:4567`를 확인해 보세요. +[http://localhost:4567](http://localhost:4567) 를 확인해 보세요. `gem install thin`도 함께 실행하기를 권장합니다. thin이 설치되어 있을 경우 Sinatra는 thin을 통해 실행합니다. @@ -224,8 +224,8 @@ end 라우터 패턴에는 선택적인(optional) 매개변수도 올 수 있습니다. ```ruby -get '/posts.?:format?' do - # "GET /posts" 는 물론 "GET /posts.json", "GET /posts.xml" 와 같은 어떤 확장자와도 매칭 +get '/posts/:format?' do + # "GET /posts/" 는 물론 "GET /posts/json", "GET /posts/xml" 와 같은 어떤 확장자와도 매칭 end ``` @@ -583,7 +583,7 @@ get('/') { markdown :index } - + @@ -636,7 +636,7 @@ get('/') { markdown :index }
의존성nokogirinokogiri
파일 확장자
- + @@ -653,7 +653,7 @@ get('/') { markdown :index }
의존성lessless
파일 확장자
- + @@ -674,7 +674,7 @@ Liquid 템플릿에서는 루비 메서드(`yield` 제외)를 호출할 수 없
의존성liquidliquid
파일 확장자
의존성 - RDiscount, + RDiscount, RedCarpet, BlueCloth, kramdown, @@ -825,7 +825,7 @@ Radius 템플릿에서는 루비 메서드를 호출할 수 없기 - + @@ -973,7 +973,7 @@ MediaWiki에서 루비를 호출할 수 없기 때문에, MediaWiki으로 작성 - +
의존성markabymarkaby
파일확장
의존성 - + Stylus @@ -1506,8 +1506,8 @@ end ``` 이렇게 스트리밍 API나 [서버 발송 이벤트Server Sent -Events](http://dev.w3.org/html5/eventsource/)를 구현할 수 있고, 이 방법은 -[WebSockets](http://en.wikipedia.org/wiki/WebSocket)을 위한 기반으로 사용됩니다. +Events](https://w3c.github.io/eventsource/)를 구현할 수 있고, 이 방법은 +[WebSockets](https://en.wikipedia.org/wiki/WebSocket)을 위한 기반으로 사용됩니다. 이 방법은 일부 콘텐츠가 느린 자원에 의존하는 경우에 스로풋(throughtput)을 높이기 위해 사용되기도 합니다. @@ -1631,7 +1631,7 @@ end ```ruby redirect to('/bar'), 303 -redirect 'http://google.com', 'wrong place, buddy' +redirect 'http://www.google.com/', 'wrong place, buddy' ``` `redirect back`을 사용하면 쉽게 사용자가 왔던 페이지로 다시 돌아가게 @@ -1713,7 +1713,7 @@ get "/article/:id" do end ``` -[약한 ETag](http://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation)를 +[약한 ETag](https://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation)를 사용할 수 도 있습니다. ```ruby @@ -2023,7 +2023,7 @@ end ### 공격 방어 설정하기(Configuring attack protection) -Sinatra는 [Rack::Protection](https://github.com/rkh/rack-protection#readme)을 사용하여 +Sinatra는 [Rack::Protection](https://github.com/sinatra/rack-protection#readme)을 사용하여 일반적이고 일어날 수 있는 공격에 대비합니다. 이 모듈은 간단하게 비활성시킬 수 있습니다. (하지만 애플리케이션에 엄청나게 많은 취약성을 야기합니다.) @@ -2353,7 +2353,7 @@ get '/hello' do end ``` -`use`문법은 [Rack::Builder](http://rubydoc.info/github/rack/rack/master/Rack/Builder) DSL +`use`문법은 [Rack::Builder](http://www.rubydoc.info/github/rack/rack/master/Rack/Builder) DSL (rackup 파일에서 가장 많이 사용)에서 정의한 것과 동일합니다. 예를 들어, `use` 메서드는 블록이나 여러 개의/가변적인 인자도 받을 수 있습니다. @@ -2376,7 +2376,7 @@ Rack은 로깅, 디버깅, URL 라우팅, 인증, 그리고 세센 핸들링을 ## 테스팅(Testing) Sinatra 테스트는 많은 Rack 기반 테스팅 라이브러리, 프레임워크를 사용하여 작성가능합니다. -그 중 [Rack::Test](http://rdoc.info/github/brynary/rack-test/master/frames)를 권장합니다. +그 중 [Rack::Test](http://www.rubydoc.info/github/brynary/rack-test/master/frames)를 권장합니다. ```ruby require 'my_sinatra_app' @@ -2444,7 +2444,7 @@ end `Sinatra::Base`는 백지상태(blank slate)입니다. 빌트인 서버를 비롯한 대부분의 옵션들이 기본값으로 꺼져 있습니다. 가능한 옵션들과 그 작동에 대한 상세는 [옵션과 -설정](http://sinatra.github.com/configuration.html)을 참조하세요. +설정](http://www.sinatrarb.com/configuration.html)을 참조하세요. ### 모듈(Modular) vs. 전통적 방식(Classic Style) @@ -2492,7 +2492,7 @@ end
static truefalseFile.exist?(public_folder)
@@ -2847,8 +2847,8 @@ thin --threaded start * MacRuby, Maglev, IronRuby * Ruby 1.9.0 및 1.9.1 (이 버전들은 사용하지 말 것을 권합니다) -공식적으로 지원하지 않는다는 것의 의미는 무언가가 그 플랫폼에서만 잘못되고 -지원되는 플랫폼에서는 그러지 않을 경우, 우리의 문제가 아니라 그 플랫폼의 문제로 +공식적으로 지원하지 않는다는 것의 의미는 무언가가 그 플랫폼에서만 잘못 동작하고, +지원되는 플랫폼에서는 정상적으로 동작할 경우, 우리의 문제가 아니라 그 플랫폼의 문제로 간주한다는 뜻입니다. 또한 우리는 CI를 ruby-head (MRI의 이후 릴리즈) 브랜치에 맞춰 실행하지만, @@ -2858,6 +2858,8 @@ thin --threaded start Sinatra는 선택한 루비 구현체가 지원하는 어떠한 운영체제에서도 작동해야 합니다. +MacRuby를 사용한다면, gem install control_tower 를 실행해 주세요. + 현재 Cardinal, SmallRuby, BlueRuby 또는 1.8.7 이전의 루비 버전에서는 Sinatra를 실행할 수 없을 것입니다. @@ -2876,7 +2878,7 @@ gem install sinatra --pre ### Bundler를 사용하여 여러분 애플리케이션을 최신 Sinatra로 실행하고자 한다면, -[Bundler](http://gembundler.com/)를 사용할 것을 권장합니다. +[Bundler](http://bundler.io)를 사용할 것을 권장합니다. 우선, 아직 설치하지 않았다면 bundler를 설치합니다. @@ -2952,14 +2954,14 @@ SemVerTag를 준수합니다. 그리고 다른 리소스들에 대한 링크. * [기여하기](http://www.sinatrarb.com/contributing) - 버그를 찾았나요? 도움이 필요한가요? 패치를 하셨나요? -* [이슈 트래커](http://github.com/sinatra/sinatra/issues) -* [트위터](http://twitter.com/sinatra) +* [이슈 트래커](https://github.com/sinatra/sinatra/issues) +* [트위터](https://twitter.com/sinatra) * [메일링 리스트](http://groups.google.com/group/sinatrarb/topics) * IRC: [#sinatra](irc://chat.freenode.net/#sinatra) http://freenode.net * 슬랙의 [Sinatra & Friends](https://sinatrarb.slack.com)입니다. [여기](https://sinatra-slack.herokuapp.com/)에서 가입가능합니다. * [Sinatra Book](https://github.com/sinatra/sinatra-book/) Cookbook 튜토리얼 * [Sinatra Recipes](http://recipes.sinatrarb.com/) 커뮤니티가 만드는 레시피 -* http://rubydoc.info에 있는 [최종 릴리스](http://rubydoc.info/gems/sinatra) - 또는 [current HEAD](http://rubydoc.info/github/sinatra/sinatra)에 대한 API 문서 -* [CI server](http://travis-ci.org/sinatra/sinatra) +* http://www.rubydoc.info/에 있는 [최종 릴리스](http://www.rubydoc.info/gems/sinatra) + 또는 [current HEAD](http://www.rubydoc.info/github/sinatra/sinatra)에 대한 API 문서 +* [CI server](https://travis-ci.org/sinatra/sinatra) diff --git a/README.md b/README.md index 3d10df77..0dad6c9b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Sinatra -Sinatra is a [DSL](http://en.wikipedia.org/wiki/Domain-specific_language) for +Sinatra is a [DSL](https://en.wikipedia.org/wiki/Domain-specific_language) for quickly creating web applications in Ruby with minimal effort: ```ruby @@ -24,7 +24,7 @@ And run with: ruby myapp.rb ``` -View at: http://localhost:4567 +View at: [http://localhost:4567](http://localhost:4567) It is recommended to also run `gem install thin`, which Sinatra will pick up if available. @@ -225,8 +225,8 @@ end Route patterns may have optional parameters: ```ruby -get '/posts.?:format?' do - # matches "GET /posts" and any extension "GET /posts.json", "GET /posts.xml" etc. +get '/posts/:format?' do + # matches "GET /posts/" and any extension "GET /posts/json", "GET /posts/xml" etc end ``` @@ -609,7 +609,7 @@ It also takes a block for inline templates (see example). - + @@ -662,7 +662,7 @@ It also takes a block for inline templates (see example).
Dependencynokogirinokogiri
File Extension
- + @@ -679,7 +679,7 @@ It also takes a block for inline templates (see example).
Dependencylessless
File Extension
- + @@ -701,7 +701,7 @@ template, you almost always want to pass locals to it.
Dependencyliquidliquid
File ExtensionDependency Anyone of: - RDiscount, + RDiscount, RedCarpet, BlueCloth, kramdown, @@ -852,7 +852,7 @@ always want to pass locals to it. - + @@ -1001,7 +1001,7 @@ template than for the layout by passing the `:layout_engine` option. - +
DependencyMarkabyMarkaby
File Extension
Dependency - + Stylus and a @@ -1536,8 +1536,8 @@ end ``` This allows you to implement streaming APIs, -[Server Sent Events](http://dev.w3.org/html5/eventsource/), and can be used as -the basis for [WebSockets](http://en.wikipedia.org/wiki/WebSocket). It can also be +[Server Sent Events](https://w3c.github.io/eventsource/), and can be used as +the basis for [WebSockets](https://en.wikipedia.org/wiki/WebSocket). It can also be used to increase throughput if some but not all content depends on a slow resource. @@ -1659,7 +1659,7 @@ Any additional parameters are handled like arguments passed to `halt`: ```ruby redirect to('/bar'), 303 -redirect 'http://google.com', 'wrong place, buddy' +redirect 'http://www.google.com/', 'wrong place, buddy' ``` You can also easily redirect back to the page the user came from with @@ -1742,7 +1742,7 @@ end ``` It is also possible to use a -[weak ETag](http://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation): +[weak ETag](https://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation): ```ruby etag @article.sha1, :weak @@ -2055,7 +2055,7 @@ end ### Configuring attack protection Sinatra is using -[Rack::Protection](https://github.com/rkh/rack-protection#readme) to defend +[Rack::Protection](https://github.com/sinatra/rack-protection#readme) to defend your application against common, opportunistic attacks. You can easily disable this behavior (which will open up your application to tons of common vulnerabilities): @@ -2138,7 +2138,7 @@ set :protection, :session => true Places a lock around every request, only running processing on request per Ruby process concurrently. -
Enabled if your app is not thread-safe. Disabled per default.
+
Enabled if your app is not thread-safe. Disabled by default.
method_override
@@ -2153,7 +2153,7 @@ set :protection, :session => true
Whether or not to insert request.script_name into redirects if no absolute path is given. That way redirect '/foo' would behave like - redirect to('/foo'). Disabled per default. + redirect to('/foo'). Disabled by default.
protection
@@ -2225,7 +2225,7 @@ set :protection, :session => true
Disable when using a server able to do this on its own.
Disabling will boost performance.
- Enabled per default in classic style, disabled for modular apps. + Enabled by default in classic style, disabled for modular apps.
static_cache_control
@@ -2394,7 +2394,7 @@ end ``` The semantics of `use` are identical to those defined for the -[Rack::Builder](http://rubydoc.info/github/rack/rack/master/Rack/Builder) DSL +[Rack::Builder](http://www.rubydoc.info/github/rack/rack/master/Rack/Builder) DSL (most frequently used from rackup files). For example, the `use` method accepts multiple/variable args as well as blocks: @@ -2417,7 +2417,7 @@ or in the [Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware). ## Testing Sinatra tests can be written using any Rack-based testing library or framework. -[Rack::Test](http://rdoc.info/github/brynary/rack-test/master/frames) +[Rack::Test](http://www.rubydoc.info/github/brynary/rack-test/master/frames) is recommended: ```ruby @@ -2487,7 +2487,7 @@ those available via the top-level DSL. Most top-level apps can be converted to `Sinatra::Base` is a blank slate. Most options are disabled by default, including the built-in server. See -[Configuring Settings](http://sinatra.github.com/configuration.html) +[Configuring Settings](http://www.sinatrarb.com/configuration.html) for details on available options and their behavior. If you want behavior more similar to when you define your app at the top level (also known as Classic style), you @@ -2562,7 +2562,7 @@ different default settings:
static truefalseFile.exist?(public_folder) true
@@ -2789,7 +2789,7 @@ end You have the request scope binding inside: -* get, head, post, put, delete, options, patch, link, and unlink blocks +* get, head, post, put, delete, options, patch, link and unlink blocks * before and after filters * helper methods * templates/views @@ -2934,7 +2934,7 @@ to get some of the latest features. ### With Bundler If you want to run your application with the latest Sinatra, using -[Bundler](http://gembundler.com/) is the recommended way. +[Bundler](http://bundler.io) is the recommended way. First, install bundler, if you haven't: @@ -3009,8 +3009,8 @@ SemVerTag. news, and links to other resources. * [Contributing](http://www.sinatrarb.com/contributing) - Find a bug? Need help? Have a patch? -* [Issue tracker](http://github.com/sinatra/sinatra/issues) -* [Twitter](http://twitter.com/sinatra) +* [Issue tracker](https://github.com/sinatra/sinatra/issues) +* [Twitter](https://twitter.com/sinatra) * [Mailing List](http://groups.google.com/group/sinatrarb/topics) * IRC: [#sinatra](irc://chat.freenode.net/#sinatra) on http://freenode.net * [Sinatra & Friends](https://sinatrarb.slack.com) on Slack and see @@ -3018,7 +3018,7 @@ SemVerTag. * [Sinatra Book](https://github.com/sinatra/sinatra-book/) Cookbook Tutorial * [Sinatra Recipes](http://recipes.sinatrarb.com/) Community contributed recipes -* API documentation for the [latest release](http://rubydoc.info/gems/sinatra) - or the [current HEAD](http://rubydoc.info/github/sinatra/sinatra) on - http://rubydoc.info -* [CI server](http://travis-ci.org/sinatra/sinatra) +* API documentation for the [latest release](http://www.rubydoc.info/gems/sinatra) + or the [current HEAD](http://www.rubydoc.info/github/sinatra/sinatra) on + http://www.rubydoc.info/ +* [CI server](https://travis-ci.org/sinatra/sinatra) diff --git a/README.pt-br.md b/README.pt-br.md index bfeea902..dd65f8e0 100644 --- a/README.pt-br.md +++ b/README.pt-br.md @@ -9,7 +9,7 @@ Alguns dos trechos de código a seguir utilizam caracteres UTF-8. Então, caso e # encoding: utf-8 ``` -Sinatra é uma [DSL](http://pt.wikipedia.org/wiki/Linguagem_de_domínio_específico) para +Sinatra é uma [DSL](https://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 @@ -33,7 +33,7 @@ Em seguida execute: ruby minha_app.rb ``` -Acesse: [localhost:4567](http://localhost:4567) +Acesse: [http://localhost:4567](http://localhost:4567) É recomendado também executar `gem install thin`. Caso esta gem esteja disponível, o Sinatra irá utilizá-la. @@ -197,8 +197,8 @@ end Padrões de rota podem contar com parâmetros opcionais: ```ruby -get '/posts.?:formato?' do - # corresponde a "GET /posts" e qualquer extensão "GET /posts.json", "GET /posts.xml", etc. +get '/posts/:formato?' do + # corresponde a "GET /posts/" e qualquer extensão "GET /posts/json", "GET /posts/xml", etc. end ``` @@ -585,7 +585,7 @@ It also takes a block for inline templates (see exemplo). - + @@ -638,7 +638,7 @@ It also takes a block for inline templates (see exemplo).
Dependencianokogirinokogiri
Extencao do Arquivo
- + @@ -655,7 +655,7 @@ It also takes a block for inline templates (see exemplo).
Dependencialessless
Extencao do Arquivo
- + @@ -677,7 +677,7 @@ você quase sempre precisará passar o `locals` para ele.
Dependencialiquidliquid
Extencao do ArquivoDependencia Anyone of: - RDiscount, + RDiscount, RedCarpet, BlueCloth, kramdown, @@ -825,7 +825,7 @@ você quase sempre precisará passar o `locals` para ele. - + @@ -975,7 +975,7 @@ deve-se passar a `:layout_engine` como opção.
DependenciaMarkabyMarkaby
Extencao do Arquivo
Dependencia - + Stylus and a @@ -1548,7 +1548,7 @@ end ``` A semântica de `use` é idêntica aquela definida para a DSL -[Rack::Builder](http://rubydoc.info/github/rack/rack/master/Rack/Builder) +[Rack::Builder](http://www.rubydoc.info/github/rack/rack/master/Rack/Builder) (mais frequentemente utilizada para arquivos rackup). Por exemplo, o método `use` aceita múltiplos argumentos/variáveis bem como blocos: @@ -1647,7 +1647,7 @@ modificações: `Sinatra::Base` é um quadro branco. Muitas opções são desabilitadas por padrão, incluindo o servidor embutido. Veja [Opções e -Configurações](http://sinatra.github.com/configuration.html) para +Configurações](http://www.sinatrarb.com/configuration.html) para detalhes de opções disponíveis e seus comportamentos. SIDEBAR: A DSL de alto nível do Sinatra é implementada utilizando um simples @@ -1750,11 +1750,11 @@ git pull adicional, novidades e links para outros recursos. * [Contribuir](http://www.sinatrarb.com/contributing) - Encontrar um bug? Precisa de ajuda? Tem um patch? -* [Acompanhar Questões](http://github.com/sinatra/sinatra/issues) -* [Twitter](http://twitter.com/sinatra) +* [Acompanhar Questões](https://github.com/sinatra/sinatra/issues) +* [Twitter](https://twitter.com/sinatra) * [Lista de Email](http://groups.google.com/group/sinatrarb/topics) * [Sinatra Book](https://github.com/sinatra/sinatra-book/) Livro de Receitas -* Documentação da API para a [última release](http://rubydoc.info/gems/sinatra) +* Documentação da API para a [última release](http://www.rubydoc.info/gems/sinatra) * [IRC: \#sinatra](irc://chat.freenode.net/#sinatra) em [freenode.net](http://freenode.net) -* [Servidor de CI](http://travis-ci.org/sinatra/sinatra) +* [Servidor de CI](https://travis-ci.org/sinatra/sinatra) diff --git a/README.pt-pt.md b/README.pt-pt.md index 23915e0a..e1b7b007 100644 --- a/README.pt-pt.md +++ b/README.pt-pt.md @@ -4,7 +4,7 @@ pode estar desatualizado.* Sinatra é uma -[DSL](http://pt.wikipedia.org/wiki/Linguagem_de_domínio_específico) para +[DSL](https://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 @@ -23,7 +23,7 @@ sudo gem install sinatra ruby minhaapp.rb ``` -Aceda em: [localhost:4567](http://localhost:4567) +Aceda em: [http://localhost:4567](http://localhost:4567) ## Rotas @@ -158,7 +158,7 @@ end Renderiza `./views/index.haml`. [Opções -Haml](http://haml.info/docs/yardoc/file.HAML_REFERENCE.html#options) +Haml](http://haml.info/docs/yardoc/file.REFERENCE.html#options) podem ser definidas globalmente através das configurações do sinatra, veja [Opções e Configurações](http://www.sinatrarb.com/configuration.html), e substitua @@ -233,7 +233,7 @@ end Renderiza `./views/stylesheet.sass`. [Opções -Sass](http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#options) +Sass](http://sass-lang.com/documentation/file.SASS_REFERENCE.html#options) podem ser definidas globalmente através das configurações do sinatra, veja [Opções e Configurações](http://www.sinatrarb.com/configuration.html), e substitua @@ -609,7 +609,7 @@ end ``` A semântica de `use` é idêntica aquela definida para a DSL -[Rack::Builder](http://rubydoc.info/github/rack/rack/master/Rack/Builder) +[Rack::Builder](http://www.rubydoc.info/github/rack/rack/master/Rack/Builder) (mais frequentemente utilizada para arquivos rackup). Por exemplo, o método `use` aceita múltiplos argumentos/variáveis, bem como blocos: @@ -709,7 +709,7 @@ modificações: `Sinatra::Base` é um quadro branco. Muitas opções são desactivadas por padrão, incluindo o servidor embutido. Veja [Opções e -Configurações](http://sinatra.github.com/configuration.html) para +Configurações](http://www.sinatrarb.com/configuration.html) para detalhes de opções disponíveis e seus comportamentos. SIDEBAR: A DSL de alto nível do Sinatra é implementada utilizando um simples @@ -781,9 +781,9 @@ git pull - [Contribuir](http://www.sinatrarb.com/contributing) - Encontrou um bug? Precisa de ajuda? Tem um patch? -- [Acompanhar Questões](http://github.com/sinatra/sinatra/issues) +- [Acompanhar Questões](https://github.com/sinatra/sinatra/issues) -- [Twitter](http://twitter.com/sinatra) +- [Twitter](https://twitter.com/sinatra) - [Lista de Email](http://groups.google.com/group/sinatrarb/topics) diff --git a/README.ru.md b/README.ru.md index 3d9adfaf..77850bfb 100644 --- a/README.ru.md +++ b/README.ru.md @@ -91,7 +91,7 @@ устаревшим* Sinatra — это предметно-ориентированный каркас -([DSL](http://ru.wikipedia.org/wiki/Предметно-ориентированный_язык_программирования)) +([DSL](https://ru.wikipedia.org/wiki/Предметно-ориентированный_язык)) для быстрого создания функциональных веб-приложений на Ruby с минимумом усилий: ```ruby @@ -115,7 +115,7 @@ gem install sinatra ruby myapp.rb ``` -Оцените результат: http://localhost:4567 +Оцените результат: [http://localhost:4567](http://localhost:4567) Рекомендуется также установить Thin, сделать это можно командой: `gem install thin`. Thin — это более производительный и функциональный сервер для @@ -225,8 +225,8 @@ end Шаблоны маршрутов могут иметь необязательные параметры: ```ruby -get '/posts.?:format?' do - # соответствует "GET /posts", "GET /posts.json", "GET /posts.xml" и т.д. +get '/posts/:format?' do + # соответствует "GET /posts/", "GET /posts/json", "GET /posts/xml" и т.д. end ``` @@ -595,7 +595,7 @@ get('/') { markdown :index } - + @@ -648,7 +648,7 @@ get('/') { markdown :index }
Зависимостиnokogirinokogiri
Расширения файлов
- + @@ -665,7 +665,7 @@ get('/') { markdown :index }
Зависимостиlessless
Расширения файлов
- + @@ -687,7 +687,7 @@ get('/') { markdown :index }
Зависимостиliquidliquid
Расширения файловЗависимости Любая из библиотек: - RDiscount, + RDiscount, RedCarpet, BlueCloth, kramdown, @@ -843,7 +843,7 @@ erb :overview, :locals => { :text => rdoc(:introduction) } - + @@ -995,7 +995,7 @@ erb :overview, :locals => { :text => mediawiki(:introduction) }
ЗависимостиMarkabyMarkaby
Расширения файлов
Зависимости - + Stylus и @@ -1526,8 +1526,8 @@ end ``` Что позволяет вам реализовать стриминговые API, -[Server Sent Events](http://dev.w3.org/html5/eventsource/), -и может служить основой для [WebSockets](http://en.wikipedia.org/wiki/WebSocket). +[Server Sent Events](https://w3c.github.io/eventsource/), +и может служить основой для [WebSockets](https://en.wikipedia.org/wiki/WebSocket). Также такой подход можно использовать для увеличения производительности в случае, когда какая-то часть контента зависит от медленного ресурса. @@ -1654,7 +1654,7 @@ end ```ruby redirect to('/bar'), 303 -redirect 'http://google.com', 'wrong place, buddy' +redirect 'http://www.google.com/', 'wrong place, buddy' ``` Вы также можете перенаправить пользователя обратно, на страницу, с которой он @@ -1738,7 +1738,7 @@ end ``` Также вы можете использовать -[weak ETag](http://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation): +[weak ETag](https://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation): ```ruby etag @article.sha1, :weak @@ -2055,7 +2055,7 @@ end ### Настройка защиты от атак Sinatra использует -[Rack::Protection](https://github.com/rkh/rack-protection#readme) для защиты +[Rack::Protection](https://github.com/sinatra/rack-protection#readme) для защиты приложения от простых атак. Вы можете легко выключить эту защиту (что сделает ваше приложение чрезвычайно уязвимым): @@ -2362,7 +2362,7 @@ end ``` Семантика `use` идентична той, что определена для -[Rack::Builder](http://rubydoc.info/github/rack/rack/master/Rack/Builder) DSL +[Rack::Builder](http://www.rubydoc.info/github/rack/rack/master/Rack/Builder) DSL (чаще всего используется в rackup файлах). Например, метод `use` принимает как множественные переменные, так и блоки: @@ -2387,7 +2387,7 @@ Rack распространяется с различными стандартн Тесты для Sinatra приложений могут быть написаны с помощью библиотек, фреймворков, поддерживающих тестирование Rack. -[Rack::Test](http://rdoc.info/github/brynary/rack-test/master/frames) +[Rack::Test](http://www.rubydoc.info/github/brynary/rack-test/master/frames) рекомендован: ```ruby @@ -2479,7 +2479,7 @@ end logging true false method_override true false inline_templates true false - static true false + static true File.exist?(public_folder) ### Запуск модульных приложений @@ -2868,7 +2868,7 @@ gem install sinatra --pre ### С помощью Bundler Если вы хотите запускать свое приложение с последней версией Sinatra, то -рекомендуем использовать [Bundler](http://gembundler.com/). +рекомендуем использовать [Bundler](http://bundler.io). Сначала установите Bundler, если у вас его еще нет: @@ -2944,15 +2944,15 @@ SemVerTag. документация, новости и ссылки на другие ресурсы. * [Участие в проекте](http://www.sinatrarb.com/contributing) — Обнаружили баг? Нужна помощь? Написали патч? -* [Отслеживание проблем/ошибок](http://github.com/sinatra/sinatra/issues) -* [Twitter](http://twitter.com/sinatra) +* [Отслеживание проблем/ошибок](https://github.com/sinatra/sinatra/issues) +* [Twitter](https://twitter.com/sinatra) * [Группы рассылки](http://groups.google.com/group/sinatrarb/topics) * IRC: [#sinatra](irc://chat.freenode.net/#sinatra) на http://freenode.net * [Sinatra и Друзья](https://sinatrarb.slack.com) на Slack, а так же [ссылка](https://sinatra-slack.herokuapp.com/) для инвайта. * [Sinatra Book](https://github.com/sinatra/sinatra-book/) учебник и сборник рецептов * [Sinatra Recipes](http://recipes.sinatrarb.com/) сборник рецептов -* API документация к [последнему релизу](http://rubydoc.info/gems/sinatra) - или [текущему HEAD](http://rubydoc.info/github/sinatra/sinatra) на - http://rubydoc.info -* [Сервер непрерывной интеграции](http://travis-ci.org/sinatra/sinatra) +* API документация к [последнему релизу](http://www.rubydoc.info/gems/sinatra) + или [текущему HEAD](http://www.rubydoc.info/github/sinatra/sinatra) на + http://www.rubydoc.info/ +* [Сервер непрерывной интеграции](https://travis-ci.org/sinatra/sinatra) diff --git a/README.zh.md b/README.zh.md index 9cfe93b8..6db169bb 100644 --- a/README.zh.md +++ b/README.zh.md @@ -1,45 +1,129 @@ # Sinatra -*注:本文档是英文版的翻译,内容更新有可能不及时。 -如有不一致的地方,请以英文版为准。* +*注:本文档是英文版的翻译,内容更新有可能不及时。如有不一致的地方,请以英文版为准。* -Sinatra是一个基于Ruby语言的[DSL](http://en.wikipedia.org/wiki/Domain-specific_language)( -领域专属语言),可以轻松、快速的创建web应用。 +Sinatra 是一门基于 +Ruby 的[领域专属语言](https://en.wikipedia.org/wiki/Domain-specific_language),致力于轻松、快速地创建网络应用: -~~~~ruby +```ruby # myapp.rb require 'sinatra' get '/' do 'Hello world!' end -~~~~ +``` -安装gem,然后运行: +安装 Sinatra 这个 gem: -~~~~shell +```shell gem install sinatra +``` + +然后运行 myapp.rb 中的代码: + +```shell ruby myapp.rb -~~~~ +``` -在该地址查看: http://localhost:4567 +在该地址查看: [http://localhost:4567](http://localhost:4567) -这个时候访问地址将绑定到 127.0.0.1 和 localhost ,如果使用 vagrant 进行开发,访问会失败,此时就需要进行 ip 绑定了: +推荐运行 `gem install thin` 安装 Thin。这样,Sinatra 会优先选择 Thin 作为服务器。 -~~~~shell -ruby myapp.rb -o 0.0.0.0 -~~~~ +## 目录 -```-o``` 这个参数就是进行 Listening 时候监听的绑定,能从通过 IP、127.0.0.1、localhost + 端口号进行访问。 +* [Sinatra](#sinatra) + * [目录](#目录) + * [路由](#路由) + * [条件](#条件) + * [返回值](#返回值) + * [自定义路由匹配器](#自定义路由匹配器) + * [静态文件](#静态文件) + * [视图 / 模板](#视图--模板) + * [字面量模板](#字面量模板) + * [可选的模板语言](#可选的模板语言) + * [Haml 模板](#haml-模板) + * [Erb 模板](#erb-模板) + * [Builder 模板](#builder-模板) + * [Nokogiri 模板](#nokogiri-模板) + * [Sass 模板](#sass-模板) + * [SCSS 模板](#scss-模板) + * [Less 模板](#less-模板) + * [Liquid 模板](#liquid-模板) + * [Markdown 模板](#markdown-模板) + * [Textile 模板](#textile-模板) + * [RDoc 模板](#rdoc-模板) + * [AsciiDoc 模板](#asciidoc-模板) + * [Radius 模板](#radius-模板) + * [Markaby 模板](#markaby-模板) + * [RABL 模板](#rabl-模板) + * [Slim 模板](#slim-模板) + * [Creole 模板](#creole-模板) + * [MediaWiki 模板](#mediawiki-模板) + * [CoffeeScript 模板](#coffeescript-模板) + * [Stylus 模板](#stylus-模板) + * [Yajl 模板](#yajl-模板) + * [WLang 模板](#wlang-模板) + * [在模板中访问变量](#在模板中访问变量) + * [带 `yield` 的模板和嵌套布局](#带-yield-的模板和嵌套布局) + * [内联模板](#内联模板) + * [具名模板](#具名模板) + * [关联文件扩展名](#关联文件扩展名) + * [添加自定义模板引擎](#添加自定义模板引擎) + * [自定义模板查找逻辑](#自定义模板查找逻辑) + * [过滤器](#过滤器) + * [辅助方法](#辅助方法) + * [使用会话](#使用会话) + * [中断请求](#中断请求) + * [传递请求](#传递请求) + * [触发另一个路由](#触发另一个路由) + * [设置响应主体、状态码和响应首部](#设置响应主体状态码和响应首部) + * [响应的流式传输](#响应的流式传输) + * [日志](#日志) + * [媒体类型](#媒体类型) + * [生成 URL](#生成-url) + * [浏览器重定向](#浏览器重定向) + * [缓存控制](#缓存控制) + * [发送文件](#发送文件) + * [访问请求对象](#访问请求对象) + * [附件](#附件) + * [处理日期和时间](#处理日期和时间) + * [查找模板文件](#查找模板文件) + * [配置](#配置) + * [配置攻击防护](#配置攻击防护) + * [可选的设置](#可选的设置) + * [环境](#环境) + * [错误处理](#错误处理) + * [未找到](#未找到) + * [错误](#错误) + * [Rack 中间件](#rack-中间件) + * [测试](#测试) + * [Sinatra::Base - 中间件、库和模块化应用](#sinatrabase---中间件库和模块化应用) + * [模块化风格 vs. 经典风格](#模块化风格-vs-经典风格) + * [运行一个模块化应用](#运行一个模块化应用) + * [使用 config.ru 运行经典风格的应用](#使用-configru-运行经典风格的应用) + * [何时使用 config.ru?](#何时使用-configru) + * [把 Sinatra 当作中间件使用](#把-sinatra-当作中间件使用) + * [创建动态应用](#创建动态应用) + * [作用域和绑定](#作用域和绑定) + * [应用/类作用域](#应用类作用域) + * [请求/实例作用域](#请求实例作用域) + * [代理作用域](#代理作用域) + * [命令行](#命令行) + * [多线程](#多线程) + * [必要条件](#必要条件) + * [紧跟前沿](#紧跟前沿) + * [通过 Bundler 使用 Sinatra](#通过-bundler-使用-sinatra) + * [使用自己本地的 Sinatra](#使用自己本地的-sinatra) + * [全局安装](#全局安装) + * [版本](#版本) + * [更多资料](#更多资料) -安装Sintra后,最好再运行`gem install thin`安装Thin。这样,Sinatra会优先选择Thin作为服务器。 +## 路由 -## 路由(route) +在 Sinatra 中,一个路由分为两部分:HTTP 方法和 URL 匹配范式。每个路由都有一个要执行的代码块: -在Sinatra中,一个路由分为两部分:HTTP方法(GET, POST等)和URL匹配范式。 -每个路由都有一个要执行的代码块: - -~~~~ruby +```ruby get '/' do .. 显示内容 .. end @@ -49,7 +133,11 @@ post '/' do end put '/' do - .. 更新内容 .. + .. 替换内容 .. +end + +patch '/' do + .. 修改内容 .. end delete '/' do @@ -67,77 +155,107 @@ end unlink '/' do .. 解除某种联系 .. end +``` +路由按照它们定义时的顺序进行匹配。第一个与请求匹配的路由会被调用。 -~~~~ +路由范式可以包括具名参数,具名参数可以通过 `params` hash 访问: -路由按照它们被定义的顺序进行匹配。 第一个与请求匹配的路由会被调用。 - -路由范式可以包括具名参数,可通过`params`哈希表获得: - -~~~~ruby +```ruby get '/hello/:name' do # 匹配 "GET /hello/foo" 和 "GET /hello/bar" # params['name'] 的值是 'foo' 或者 'bar' "Hello #{params['name']}!" end -~~~~ +``` -你同样可以通过代码块参数获得具名参数: +也可以通过代码块参数访问具名参数: -~~~~ruby +```ruby get '/hello/:name' do |n| + # 匹配 "GET /hello/foo" 和 "GET /hello/bar" + # params['name'] 的值是 'foo' 或者 'bar' + # n 存储 params['name'] 的值 "Hello #{n}!" end -~~~~ +``` -路由范式也可以包含通配符参数, 可以通过`params['splat']`数组获得。 +路由范式也可以包含通配符参数, 参数值可以通过 `params['splat']` 数组访问。 -~~~~ruby +```ruby get '/say/*/to/*' do - # 匹配 /say/hello/to/world + # 匹配 "GET /say/hello/to/world" params['splat'] # => ["hello", "world"] end get '/download/*.*' do - # 匹配 /download/path/to/file.xml + # 匹配 "GET /download/path/to/file.xml" params['splat'] # => ["path/to/file", "xml"] end -~~~~ +``` -通过正则表达式匹配的路由: +或者通过代码块参数访问: -~~~~ruby +```ruby +get '/download/*.*' do |path, ext| + [path, ext] # => ["path/to/file", "xml"] +end +``` + +通过正则表达式匹配路由: + +```ruby get /\A\/hello\/([\w]+)\z/ do "Hello, #{params['captures'].first}!" end -~~~~ +``` 或者使用代码块参数: -~~~~ruby +```ruby get %r{/hello/([\w]+)} do |c| + # 匹配 "GET /meta/hello/world"、"GET /hello/world/1234" 等 "Hello, #{c}!" end -~~~~ +``` + +路由范式可以包含可选参数: + +```ruby +get '/posts/:format?' do + # 匹配 "GET /posts/" 和任意扩展 "GET /posts/json"、"GET /posts/xml" 等 +end +``` + +路由也可以使用查询参数: + +```ruby +get '/posts' do + # 匹配 "GET /posts?title=foo&author=bar" + title = params['title'] + author = params['author'] + # 使用 title 和 author 变量;对于 /posts 路由来说,查询字符串是可选的 +end +``` +顺便一提,除非你禁用了路径遍历攻击防护(见下文),请求路径可能在匹配路由前发生改变。 ### 条件 -路由也可以包含多样的匹配条件,比如user agent: +路由可以包含各种匹配条件,比如 user agent: -~~~~ruby +```ruby get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do - "你正在使用Songbird,版本是 #{params['agent'][0]}" + "你正在使用 Songbird,版本是 #{params['agent'][0]}" end get '/foo' do - # 匹配除Songbird以外的浏览器 + # 匹配非 Songbird 浏览器 end -~~~~ +``` -其他可选的条件是 `host_name` 和 `provides`: +其它可以使用的条件有 `host_name` 和 `provides`: -~~~~ruby +```ruby get '/', :host_name => /^admin\./ do "管理员区域,无权进入!" end @@ -149,11 +267,13 @@ end get '/', :provides => ['rss', 'atom', 'xml'] do builder :feed end -~~~~ +``` -你也可以自定义条件: +`provides` 会搜索请求的 Accept 首部字段。 -~~~~ruby +也可以轻易地使用自定义条件: + +```ruby set(:probability) { |value| condition { rand <= value } } get '/win_a_car', :probability => 0.1 do @@ -163,30 +283,44 @@ end get '/win_a_car' do "Sorry, you lost." end -~~~~ +``` + +对于一个需要提供多个值的条件,可以使用 splat: + +```ruby +set(:auth) do |*roles| # <- 注意此处使用了 splat + condition do + unless logged_in? && roles.any? {|role| current_user.in_role? role } + redirect "/login/", 303 + end + end +end + +get "/my/account/", :auth => [:user, :admin] do + "Your Account Details" +end + +get "/only/admin/", :auth => :admin do + "Only admins are allowed here!" +end +``` ### 返回值 -路由代码块的返回值至少决定了返回给HTTP客户端的响应体, -或者至少决定了在Rack堆栈中的下一个中间件。 -大多数情况下,将是一个字符串,就像上面的例子中的一样。 -但是其他值也是可以接受的。 +路由代码块的返回值至少决定了返回给 +HTTP 客户端的响应主体,或者至少决定了在 +Rack 堆栈中的下一个中间件。大多数情况下,返回值是一个字符串,就像上面的例子中的一样。但是,其它类型的值也是可以接受的。 -你可以返回任何对象,或者是一个合理的Rack响应, Rack -body对象或者HTTP状态码: +你可以返回任何对象,该对象要么是一个合理的 Rack 响应,要么是一个 Rack body 对象,要么是 HTTP 状态码: -- 一个包含三个元素的数组: - `[状态 (Fixnum), 头 (Hash), 响应体 (回应 #each)]` +* 一个包含三个元素的数组: `[状态 (Fixnum), 响应首部 (Hash), 响应主体 (可以响应 #each 方法)]` +* 一个包含两个元素的数组: `[状态 (Fixnum), 响应主体 (可以响应 #each 方法)]` +* 一个响应 `#each` 方法,只传回字符串的对象 +* 一个代表状态码的数字 -- 一个包含两个元素的数组: `[状态 (Fixnum), 响应体 (回应 #each)]` +例如,我们可以轻松地实现流式传输: -- 一个能够回应 `#each` ,只传回字符串的对象 - -- 一个代表状态码的数字 - -那样,我们可以轻松的实现例如流式传输的例子: - -~~~~ruby +```ruby class Stream def each 100.times { |i| yield "#{i}\n" } @@ -194,14 +328,16 @@ class Stream end get('/') { Stream.new } -~~~~ +``` + +也可以使用 `stream` 辅助方法(见下文描述)以减少样板代码并在路由中直接使用流式传输。 ### 自定义路由匹配器 -如上显示,Sinatra内置了对于使用字符串和正则表达式作为路由匹配的支持。 -但是,它并没有只限于此。 你可以非常容易地定义你自己的匹配器: +如上文所示,Sinatra +本身支持使用字符串和正则表达式作为路由匹配。但不限于此,你可以轻松地定义自己的匹配器: -~~~~ruby +```ruby class AllButPattern Match = Struct.new(:captures) @@ -222,564 +358,758 @@ end get all_but("/index") do # ... end -~~~~ +``` -上面的例子可能太繁琐了, 因为它也可以用更简单的方式表述: +上面的例子可能太繁琐了, 因为它也可以用更简单的方式表述: -~~~~ruby +```ruby get // do pass if request.path_info == "/index" # ... end -~~~~ +``` 或者,使用消极向前查找: -~~~~ruby +```ruby get %r{^(?!/index$)} do # ... end -~~~~ +``` ## 静态文件 -静态文件是从 `./public_folder` 目录提供服务。你可以通过设置`:public` -选项设定一个不同的位置: +静态文件从 `./public` 目录提供服务。可以通过设置`:public_folder` 选项设定一个不同的位置: -~~~~ruby +```ruby set :public_folder, File.dirname(__FILE__) + '/static' -~~~~ +``` -请注意public目录名并没有被包含在URL之中。文件 -`./public/css/style.css`是通过 -`http://example.com/css/style.css`地址访问的。 +请注意 public 目录名并没有包含在 URL 中。文件 `./public/css/style.css` 可以通过 +`http://example.com/css/style.css` 访问。 + +可以使用 `:static_cache_control` 设置(见下文)添加 `Cache-Control` 首部信息。 ## 视图 / 模板 -模板被假定直接位于`./views`目录。 要使用不同的视图目录: +每一门模板语言都将自身的渲染方法暴露给 +Sinatra 调用。这些渲染方法只是简单地返回字符串。 -~~~~ruby -set :views, File.dirname(__FILE__) + '/templates' -~~~~ +```ruby +get '/' do + erb :index +end +``` -重要提示:你只可以通过符号引用模板, 即使它们在子目录下 -(在这种情况下,使用 `:'subdir/template'`)。 如果你不用符号、而用字符串的话, -填充方法会只把你传入的字符串当成内容显示出来,而不调用模板。 +这段代码会渲染 `views/index.erb` 文件。 -### Haml模板 +除了模板文件名,也可以直接传入模板内容: -需要引入 `haml` gem/library以填充 HAML 模板: +```ruby +get '/' do + code = "<%= Time.now %>" + erb code +end +``` -~~~~ruby -# 你需要在你的应用中引入 haml -require 'haml' +渲染方法接受第二个参数,即选项 hash: + +```ruby +get '/' do + erb :index, :layout => :post +end +``` + +这段代码会将 `views/index.erb` 嵌入在 `views/post.erb` +布局中并一起渲染(`views/layout.erb` 是默认的布局,如果它存在的话)。 + +任何 Sinatra 不能理解的选项都会传递给模板引擎。 + +```ruby +get '/' do + haml :index, :format => :html5 +end +``` + +也可以为每种模板语言设置通用的选项: + +```ruby +set :haml, :format => :html5 get '/' do haml :index end -~~~~ +``` -填充 `./views/index.haml`。 +在渲染方法中传入的选项会覆盖通过 `set` 设置的通用选项。 -[Haml的选项](http://haml.info/docs/yardoc/file.HAML_REFERENCE.html#options) -可以通过Sinatra的配置全局设定, 参见 -[选项和配置](http://www.sinatrarb.com/configuration.html), -也可以个别的被覆盖。 +可用的选项: -~~~~ruby -set :haml, {:format => :html5 } # 默认的Haml输出格式是 :xhtml +
+
locals
+
+ 传递给模板文档的 locals 对象列表。对于 partials + 很方便。例如:erb "<%= foo %>", :locals => {:foo => "bar"} +
-get '/' do - haml :index, :haml_options => {:format => :html4 } # 被覆盖,变成:html4 -end -~~~~ +
default_encoding
+
默认的字符编码。默认值为 settings.default_encoding
-### Erb模板 +
views
+
存放模板文件的目录。默认为 settings.views
-~~~~ruby -# 你需要在你的应用中引入 erb -require 'erb' +
layout
+
+ 是否使用布局 (truefalse)。 + 如果使用一个符号类型的值,则是用于明确使用的模板。例如: + erb :index, :layout => !request.xhr? +
-get '/' do - erb :index -end -~~~~ +
content_type
+
由模板生成的 Content-Type。默认值由模板语言决定。
-这里调用的是 `./views/index.erb` +
scope
+
+ 渲染模板时的作用域。默认值为应用类的实例对象。如果更改此项,实例变量和辅助方法将不可用。 +
-### Erubis +
layout_engine
+
+ 渲染布局所使用的模板引擎。用于不支持布局的模板语言。默认值为模板所使用的引擎。例如: + set :rdoc, :layout_engine => :erb +
-需要引入 `erubis` gem/library以填充 erubis 模板: +
layout_options
+
+ 渲染布局的特殊选项。例如: + set :rdoc, :layout_options => { :views => 'views/layouts' } +
+
-~~~~ruby -# 你需要在你的应用中引入 erubis -require 'erubis' +Sinatra 假定模板文件直接位于 `./views` 目录。要使用不同的视图目录: -get '/' do - erubis :index -end -~~~~ +```ruby +set :views, settings.root + '/templates' +``` -这里调用的是 `./views/index.erubis` -使用Erubis代替Erb也是可能的: +需要牢记的一点是,你必须通过符号引用模板, 即使它们存放在子目录下 +(在这种情况下,使用 `:'subdir/template'` 或 `'subdir/template'.to_sym`)。 +如果你不使用符号,渲染方法会直接渲染你传入的任何字符串。 -~~~~ruby -require 'erubis' -Tilt.register :erb, Tilt[:erubis] +### 字面量模板 -get '/' do - erb :index -end -~~~~ - -使用Erubis来填充 `./views/index.erb`。 - -### Builder 模板 - -需要引入 `builder` gem/library 以填充 builder templates: - -~~~~ruby -# 需要在你的应用中引入builder -require 'builder' - -get '/' do - builder :index -end -~~~~ - -这里调用的是 `./views/index.builder`。 - -### Nokogiri 模板 - -需要引入 `nokogiri` gem/library 以填充 nokogiri 模板: - -~~~~ruby -# 需要在你的应用中引入 nokogiri -require 'nokogiri' - -get '/' do - nokogiri :index -end -~~~~ - -这里调用的是 `./views/index.nokogiri`。 - -### Sass 模板 - -需要引入 `haml` 或者 `sass` gem/library 以填充 Sass 模板: - -~~~~ruby -# 需要在你的应用中引入 haml 或者 sass -require 'sass' - -get '/stylesheet.css' do - sass :stylesheet -end -~~~~ - -这里调用的是 `./views/stylesheet.sass`。 - -[Sass -的选项](http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#options) -可以通过Sinatra选项全局设定, 参考 -[选项和配置(英文)](http://www.sinatrarb.com/configuration.html), -也可以在个体的基础上覆盖。 - -~~~~ruby -set :sass, {:style => :compact } # 默认的 Sass 样式是 :nested - -get '/stylesheet.css' do - sass :stylesheet, :style => :expanded # 覆盖 -end -~~~~ - -### Scss 模板 - -需要引入 `haml` 或者 `sass` gem/library 来填充 Scss templates: - -~~~~ruby -# 需要在你的应用中引入 haml 或者 sass -require 'sass' - -get '/stylesheet.css' do - scss :stylesheet -end -~~~~ - -这里调用的是 `./views/stylesheet.scss`。 - -[Scss的选项](http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#options) -可以通过Sinatra选项全局设定, 参考 -[选项和配置(英文)](http://www.sinatrarb.com/configuration.html), -也可以在个体的基础上覆盖。 - -~~~~ruby -set :scss, :style => :compact # default Scss style is :nested - -get '/stylesheet.css' do - scss :stylesheet, :style => :expanded # overridden -end -~~~~ - -### Less 模板 - -需要引入 `less` gem/library 以填充 Less 模板: - -~~~~ruby -# 需要在你的应用中引入 less -require 'less' - -get '/stylesheet.css' do - less :stylesheet -end -~~~~ - -这里调用的是 `./views/stylesheet.less`。 - -### Liquid 模板 - -需要引入 `liquid` gem/library 来填充 Liquid 模板: - -~~~~ruby -# 需要在你的应用中引入 liquid -require 'liquid' - -get '/' do - liquid :index -end -~~~~ - -这里调用的是 `./views/index.liquid`。 - -因为你不能在Liquid 模板中调用 Ruby 方法 (除了 `yield`) , -你几乎总是需要传递locals给它: - -~~~~ruby -liquid :index, :locals => { :key => 'value' } -~~~~ - -### Markdown 模板 - -需要引入 `rdiscount` gem/library 以填充 Markdown 模板: - -~~~~ruby -# 需要在你的应用中引入rdiscount -require "rdiscount" - -get '/' do - markdown :index -end -~~~~ - -这里调用的是 `./views/index.markdown` (`md` 和 `mkd` 也是合理的文件扩展名)。 - -在markdown中是不可以调用方法的,也不可以传递 locals给它。 -你因此一般会结合其他的填充引擎来使用它: - -~~~~ruby -erb :overview, :locals => { :text => markdown(:introduction) } -~~~~ - -请注意你也可以从其他模板中调用 markdown 方法: - -~~~~ruby -%h1 Hello From Haml! -%p= markdown(:greetings) -~~~~ - -既然你不能在Markdown中调用Ruby,你不能使用Markdown编写的布局。 -不过,使用其他填充引擎作为模版的布局是可能的, -通过传递`:layout_engine`选项: - -~~~~ruby -get '/' do - markdown :index, :layout_engine => :erb -end -~~~~ - -这将会调用 `./views/index.md` 并使用 `./views/layout.erb` 作为布局。 - -请记住你可以全局设定这个选项: - -~~~~ruby -set :markdown, :layout_engine => :haml, :layout => :post - -get '/' do - markdown :index -end -~~~~ - -这将会调用 `./views/index.markdown` (和任何其他的 Markdown 模版) 并使用 -`./views/post.haml` 作为布局. - -也可能使用BlueCloth而不是RDiscount来解析Markdown文件: - -~~~~ruby -require 'bluecloth' - -Tilt.register 'markdown', BlueClothTemplate -Tilt.register 'mkd', BlueClothTemplate -Tilt.register 'md', BlueClothTemplate - -get '/' do - markdown :index -end -~~~~ - -使用BlueCloth来填充 `./views/index.md` 。 - -### Textile 模板 - -需要引入 `RedCloth` gem/library 以填充 Textile 模板: - -~~~~ruby -# 在你的应用中引入redcloth -require "redcloth" - -get '/' do - textile :index -end -~~~~ - -这里调用的是 `./views/index.textile`。 - -在textile中是不可以调用方法的,也不可以传递 locals给它。 -你因此一般会结合其他的填充引擎来使用它: - -~~~~ruby -erb :overview, :locals => { :text => textile(:introduction) } -~~~~ - -请注意你也可以从其他模板中调用`textile`方法: - -~~~~ruby -%h1 Hello From Haml! -%p= textile(:greetings) -~~~~ - -既然你不能在Textile中调用Ruby,你不能使用Textile编写的布局。 -不过,使用其他填充引擎作为模版的布局是可能的, -通过传递`:layout_engine`选项: - -~~~~ruby -get '/' do - textile :index, :layout_engine => :erb -end -~~~~ - -这将会填充 `./views/index.textile` 并使用 `./views/layout.erb` -作为布局。 - -请记住你可以全局设定这个选项: - -~~~~ruby -set :textile, :layout_engine => :haml, :layout => :post - -get '/' do - textile :index -end -~~~~ - -这将会调用 `./views/index.textile` (和任何其他的 Textile 模版) 并使用 -`./views/post.haml` 作为布局. - -### RDoc 模板 - -需要引入 `RDoc` gem/library 以填充RDoc模板: - -~~~~ruby -# 需要在你的应用中引入rdoc/markup/to_html -require "rdoc" -require "rdoc/markup/to_html" - -get '/' do - rdoc :index -end -~~~~ - -这里调用的是 `./views/index.rdoc`。 - -在rdoc中是不可以调用方法的,也不可以传递locals给它。 -你因此一般会结合其他的填充引擎来使用它: - -~~~~ruby -erb :overview, :locals => { :text => rdoc(:introduction) } -~~~~ - -请注意你也可以从其他模板中调用`rdoc`方法: - -~~~~ruby -%h1 Hello From Haml! -%p= rdoc(:greetings) -~~~~ - -既然你不能在RDoc中调用Ruby,你不能使用RDoc编写的布局。 -不过,使用其他填充引擎作为模版的布局是可能的, -通过传递`:layout_engine`选项: - -~~~~ruby -get '/' do - rdoc :index, :layout_engine => :erb -end -~~~~ - -这将会调用 `./views/index.rdoc` 并使用 `./views/layout.erb` 作为布局。 - -请记住你可以全局设定这个选项: - -~~~~ruby -set :rdoc, :layout_engine => :haml, :layout => :post - -get '/' do - rdoc :index -end -~~~~ - -这将会调用 `./views/index.rdoc` (和任何其他的 RDoc 模版) 并使用 -`./views/post.haml` 作为布局. - -### Radius 模板 - -需要引入 `radius` gem/library 以填充 Radius 模板: - -~~~~ruby -# 需要在你的应用中引入radius -require 'radius' - -get '/' do - radius :index -end -~~~~ - -这里调用的是 `./views/index.radius`。 - -因为你不能在Radius 模板中调用 Ruby 方法 (除了 `yield`) , -你几乎总是需要传递locals给它: - -~~~~ruby -radius :index, :locals => { :key => 'value' } -~~~~ - -### Markaby 模板 - -需要引入`markaby` gem/library以填充Markaby模板: - -~~~~ruby -#需要在你的应用中引入 markaby -require 'markaby' - -get '/' do - markaby :index -end -~~~~ - -这里调用的是 `./views/index.mab`。 - -你也可以使用嵌入的 Markaby: - -~~~~ruby -get '/' do - markaby { h1 "Welcome!" } -end -~~~~ - -### Slim 模板 - -需要引入 `slim` gem/library 来填充 Slim 模板: - -~~~~ruby -# 需要在你的应用中引入 slim -require 'slim' - -get '/' do - slim :index -end -~~~~ - -这里调用的是 `./views/index.slim`。 - -### Creole 模板 - -需要引入 `creole` gem/library 来填充 Creole 模板: - -~~~~ruby -# 需要在你的应用中引入 creole -require 'creole' - -get '/' do - creole :index -end -~~~~ - -这里调用的是 `./views/index.creole`。 - -### CoffeeScript 模板 - -需要引入 `coffee-script` gem/library 并至少满足下面条件一项 -以执行Javascript: - -- `node` (来自 Node.js) 在你的路径中 - -- 你正在运行 OSX - -- `therubyracer` gem/library - -请察看 -[github.com/josh/ruby-coffee-script](http://github.com/josh/ruby-coffee-script) -获取更新的选项。 - -现在你可以调用 CoffeeScript 模版了: - -~~~~ruby -# 需要在你的应用中引入coffee-script -require 'coffee-script' - -get '/application.js' do - coffee :application -end -~~~~ - -这里调用的是 `./views/application.coffee`。 - -### 嵌入模板字符串 - -~~~~ruby +```ruby get '/' do haml '%div.title Hello World' end -~~~~ +``` -调用嵌入模板字符串。 +这段代码直接渲染模板字符串。 + +### 可选的模板语言 + +一些语言有多种实现。为了确定使用哪种实现(以及保证线程安全),你应该首先引入该实现: + +```ruby +require 'rdiscount' # 或 require 'bluecloth' +get('/') { markdown :index } +``` + +#### Haml 模板 + + + + + + + + + + + + + + +
依赖项haml
文件扩展名.haml
例子haml :index, :format => :html5
+ +#### Erb 模板 + + + + + + + + + + + + + + +
依赖项 + erubis + 或 erb (Ruby 标准库中已经包含) +
文件扩展名.erb, .rhtml or .erubis (仅用于 Erubis)
例子erb :index
+ +#### Builder 模板 + + + + + + + + + + + + + + +
依赖项 + builder +
文件扩展名.builder
例子builder { |xml| xml.em "hi" }
+ +`builder` 渲染方法也接受一个代码块,用于内联模板(见例子)。 + +#### Nokogiri 模板 + + + + + + + + + + + + + + +
依赖项nokogiri
文件扩展名.nokogiri
例子nokogiri { |xml| xml.em "hi" }
+ +`nokogiri` 渲染方法也接受一个代码块,用于内联模板(见例子)。 + +#### Sass 模板 + + + + + + + + + + + + + + +
依赖项sass
文件扩展名.sass
例子sass :stylesheet, :style => :expanded
+ +#### SCSS 模板 + + + + + + + + + + + + + + +
依赖项sass
文件扩展名.scss
例子scss :stylesheet, :style => :expanded
+ +#### Less 模板 + + + + + + + + + + + + + + +
依赖项less
文件扩展名.less
例子less :stylesheet
+ +#### Liquid 模板 + + + + + + + + + + + + + + +
依赖项liquid
文件扩展名.liquid
例子liquid :index, :locals => { :key => 'value' }
+ +因为不能在 Liquid 模板中调用 Ruby 方法(除了 `yield`),你几乎总是需要传递 locals 对象给它。 + +#### Markdown 模板 + + + + + + + + + + + + + + +
依赖项 + 下列任一: + RDiscount, + RedCarpet, + BlueCloth, + kramdown, + maruku +
文件扩展名.markdown, .mkd and .md
例子markdown :index, :layout_engine => :erb
+ +不能在 markdown 中调用 Ruby 方法,也不能传递 locals 给它。 +因此,你一般会结合其它的渲染引擎来使用它: + +```ruby +erb :overview, :locals => { :text => markdown(:introduction) } +``` + +请注意你也可以在其它模板中调用 markdown 方法: + +```ruby +%h1 Hello From Haml! +%p= markdown(:greetings) +``` + +因为不能在 Markdown 中使用 Ruby 语言,你不能使用 Markdown 书写的布局。 +不过,使用其它渲染引擎作为模板的布局是可能的,这需要通过传入 `:layout_engine` 选项。 + +#### Textile 模板 + + + + + + + + + + + + + + +
依赖项RedCloth
文件扩展名.textile
例子textile :index, :layout_engine => :erb
+ +不能在 textile 中调用 Ruby 方法,也不能传递 locals 给它。 +因此,你一般会结合其它的渲染引擎来使用它: + +```ruby +erb :overview, :locals => { :text => textile(:introduction) } +``` + +请注意你也可以在其他模板中调用 `textile` 方法: + +```ruby +%h1 Hello From Haml! +%p= textile(:greetings) +``` + +因为不能在 Textile 中调用 Ruby 方法,你不能用 Textile 书写布局。 +不过,使用其它渲染引擎作为模版的布局是可能的,这需要通过传递 `:layout_engine` 选项。 + +#### RDoc 模板 + + + + + + + + + + + + + + +
依赖项RDoc
文件扩展名.rdoc
例子rdoc :README, :layout_engine => :erb
+ +不能在 rdoc 中调用 Ruby 方法,也不能传递 locals 给它。 +因此,你一般会结合其它的渲染引擎来使用它: + +```ruby +erb :overview, :locals => { :text => rdoc(:introduction) } +``` + +请注意你也可以在其他模板中调用 `rdoc` 方法: + +```ruby +%h1 Hello From Haml! +%p= rdoc(:greetings) +``` + +因为不能在 RDoc 中调用 Ruby 方法,你不能用 RDoc 书写布局。 +不过,使用其它渲染引擎作为模版的布局是可能的,这需要通过传递 `:layout_engine` 选项。 + +#### AsciiDoc 模板 + + + + + + + + + + + + + + +
依赖项Asciidoctor
文件扩展名.asciidoc, .adoc and .ad
例子asciidoc :README, :layout_engine => :erb
+ +因为不能在 AsciiDoc 模板中直接调用 Ruby 方法,你几乎总是需要传递 locals 对象给它。 + +#### Radius 模板 + + + + + + + + + + + + + + +
依赖项Radius
文件扩展名.radius
例子radius :index, :locals => { :key => 'value' }
+ +因为不能在 Radius 模板中直接调用 Ruby 方法,你几乎总是可以传递 locals 对象给它。 + +#### Markaby 模板 + + + + + + + + + + + + + + +
依赖项Markaby
文件扩展名.mab
例子markaby { h1 "Welcome!" }
+ +`markaby` 渲染方法也接受一个代码块,用于内联模板(见例子)。 + +#### RABL 模板 + + + + + + + + + + + + + + +
依赖项Rabl
文件扩展名.rabl
例子rabl :index
+ +#### Slim 模板 + + + + + + + + + + + + + + +
依赖项Slim Lang
文件扩展名.slim
例子slim :index
+ +#### Creole 模板 + + + + + + + + + + + + + + +
依赖项Creole
文件扩展名.creole
例子creole :wiki, :layout_engine => :erb
+ +不能在 creole 中调用 Ruby 方法,也不能传递 locals 对象给它。 +因此你一般会结合其它的渲染引擎来使用它: + +```ruby +erb :overview, :locals => { :text => creole(:introduction) } +``` + +注意你也可以在其它模板内调用 `creole` 方法: + +```ruby +%h1 Hello From Haml! +%p= creole(:greetings) +``` + +因为不能在 Creole 模板文件内调用 Ruby 方法,你不能用 Creole 书写布局文件。 +然而,使用其它渲染引擎作为模版的布局是可能的,这需要通过传递 `:layout_engine` 选项。 + +#### MediaWiki 模板 + + + + + + + + + + + + + + +
依赖项WikiCloth
文件扩展名.mediawiki and .mw
例子mediawiki :wiki, :layout_engine => :erb
+ +在 MediaWiki 标记文件内不能调用 Ruby 方法,也不能传递 locals 对象给它。 +因此你一般会结合其它的渲染引擎来使用它: + +```ruby +erb :overview, :locals => { :text => mediawiki(:introduction) } +``` + +注意你也可以在其它模板内调用 `mediawiki` 方法: + +```ruby +%h1 Hello From Haml! +%p= mediawiki(:greetings) +``` + +因为不能在 MediaWiki 文件内调用 Ruby 方法,你不能用 MediaWiki 书写布局文件。 +然而,使用其它渲染引擎作为模版的布局是可能的,这需要通过传递 `:layout_engine` 选项。 + +#### CoffeeScript 模板 + + + + + + + + + + + + + + +
依赖项 + + CoffeeScript + 以及一种 + + 执行 JavaScript 的方式 + +
文件扩展名.coffee
例子coffee :index
+ +#### Stylus 模板 + + + + + + + + + + + + + + +
依赖项 + + Stylus + 以及一种 + + 执行 JavaScript 的方式 + +
文件扩展名.styl
例子stylus :index
+ +在使用 Stylus 模板之前,你需要先加载 `stylus` 和 `stylus/tilt`: + +```ruby +require 'sinatra' +require 'stylus' +require 'stylus/tilt' + +get '/' do + stylus :example +end +``` + +#### Yajl 模板 + + + + + + + + + + + + + + +
依赖项yajl-ruby
文件扩展名.yajl
例子 + + yajl :index, + :locals => { :key => 'qux' }, + :callback => 'present', + :variable => 'resource' + +
+ +模板文件的源码作为一个 Ruby 字符串被求值,得到的 json 变量是通过 `#to_json` 方法转换的: + +```ruby +json = { :foo => 'bar' } +json[:baz] = key +``` + +可以使用 `:callback` 和 `:variable` 选项装饰被渲染的对象: + +```javascript +var resource = {"foo":"bar","baz":"qux"}; +present(resource); +``` + +#### WLang 模板 + + + + + + + + + + + + + + +
依赖项WLang
文件扩展名.wlang
例子wlang :index, :locals => { :key => 'value' }
+ +因为在 WLang 中调用 Ruby 方法不符合语言习惯,你几乎总是需要传递 locals 给 WLang 木板。 +然而,可以用 WLang 编写布局文件,也可以在 WLang 中使用 `yield` 方法。 ### 在模板中访问变量 -模板和路由执行器在同样的上下文求值。 -在路由执行器中赋值的实例变量可以直接被模板访问。 +模板的求值发生在路由处理器内部的上下文中。模板可以直接访问路由处理器中设置的实例变量。 -~~~~ruby +```ruby get '/:id' do @foo = Foo.find(params['id']) haml '%h1= @foo.name' end -~~~~ +``` -或者,显式地指定一个本地变量的哈希: +或者,也可以显式地指定一个由局部变量组成的 locals 哈希: -~~~~ruby +```ruby get '/:id' do foo = Foo.find(params['id']) haml '%h1= foo.name', :locals => { :foo => foo } end -~~~~ +``` -典型的使用情况是在别的模板中按照局部模板的方式来填充。 +locals 哈希典型的使用情景是在别的模板中渲染 partials。 + +### 带 `yield` 的模板和嵌套布局 + +布局通常就是使用了 `yield` 方法的模板。 +这样的布局文件可以通过上面描述的 `:template` 选项指定,也可以通过下面的代码块渲染: + +```ruby +erb :post, :layout => false do + erb :index +end +``` + +这段代码几乎完全等同于 `erb :index, :layout => :post`。 + +向渲染方法传递代码块对于创建嵌套布局是最有用的: + +```ruby +erb :main_layout, :layout => false do + erb :admin_layout do + erb :user + end +end +``` + +代码行数可以更少: + +```ruby +erb :admin_layout, :layout => :main_layout do + erb :user +end +``` + +当前,以下的渲染方法接受一个代码块:`erb`、`haml`、`liquid`、`slim ` 和 `wlang`。 +通用的 `render` 方法也接受。 ### 内联模板 模板可以在源文件的末尾定义: -~~~~ruby +```ruby require 'sinatra' get '/' do @@ -793,18 +1123,17 @@ __END__ = yield @@ index -%div.title Hello world!!!!! -~~~~ +%div.title Hello world. +``` -注意:引入sinatra的源文件中定义的内联模板才能被自动载入。 -如果你在其他源文件中有内联模板, -需要显式执行调用`enable :inline_templates`。 +注意:在引入了 sinatra 的源文件中定义的内联模板会自动载入。 +如果你在其他源文件中也有内联模板,需要显式调用 `enable :inline_templates`。 ### 具名模板 -模板可以通过使用顶层 `template` 方法定义: +可以使用顶层 `template` 方法定义模板: -~~~~ruby +```ruby template :layout do "%html\n =yield\n" end @@ -816,33 +1145,32 @@ end get '/' do haml :index end -~~~~ +``` -如果存在名为“layout”的模板,该模板会在每个模板填充的时候被使用。 -你可以单独地通过传送 `:layout => false`来禁用, -或者通过`set :haml, :layout => false`来禁用他们。 +如果存在名为 “layout” 的模板,该模板会在每个模板渲染的时候作为布局使用。 +你可以为渲染方法传送 `:layout => false` 来禁用该次渲染的布局, +也可以设置 `set :haml, :layout => false` 来默认禁用布局。 -~~~~ruby +```ruby get '/' do haml :index, :layout => !request.xhr? end -~~~~ +``` ### 关联文件扩展名 -为了关联一个文件扩展名到一个模版引擎,使用 -`Tilt.register`。比如,如果你喜欢使用 `tt` -作为Textile模版的扩展名,你可以这样做: +为了将一个文件扩展名到对应的模版引擎,要使用 `Tilt.register`。 +比如,如果你喜欢使用 `tt` 作为 Textile 模版的扩展名,你可以这样做: -~~~~ruby +```ruby Tilt.register :tt, Tilt[:textile] -~~~~ +``` -### 添加你自己的模版引擎 +### 添加自定义模板引擎 -首先,通过Tilt注册你自己的引擎,然后创建一个填充方法: +首先,通过 Tilt 注册你自定义的引擎,然后创建一个渲染方法: -~~~~ruby +```ruby Tilt.register :myat, MyAwesomeTemplateEngine helpers do @@ -852,18 +1180,33 @@ end get '/' do myat :index end -~~~~ +``` -这里调用的是 `./views/index.myat`。察看 -[github.com/rtomayko/tilt](https://github.com/rtomayko/tilt) -来更多了解Tilt. +这段代码将会渲染 `./views/index.myat` 文件。 +查看 https://github.com/rtomayko/tilt 以了解更多关于 Tilt 的信息。 + +### 自定义模板查找逻辑 + +要实现自定义的模板查找机制,你可以构建自己的 `#find_template` 方法: + +```ruby +configure do + set :views, [ './views/a', './views/b' ] +end + +def find_template(views, name, engine, &block) + Array(views).each do |v| + super(v, name, engine, &block) + end +end +``` ## 过滤器 -前置过滤器在每个请求前,在请求的上下文环境中被执行, -而且可以修改请求和响应。 在过滤器中设定的实例变量可以被路由和模板访问: +`before` 过滤器在每个请求之前调用,调用的上下文与请求的上下文相同,并且可以修改请求和响应。 +在过滤器中设置的变量可以被路由和模板访问: -~~~~ruby +```ruby before do @note = 'Hi!' request.path_info = '/foo/bar/baz' @@ -873,24 +1216,23 @@ get '/foo/*' do @note #=> 'Hi!' params['splat'] #=> 'bar/baz' end -~~~~ +``` -后置过滤器在每个请求之后,在请求的上下文环境中执行, -而且可以修改请求和响应。 -在前置过滤器和路由中设定的实例变量可以被后置过滤器访问: +`after` 过滤器在每个请求之后调用,调用上下文与请求的上下文相同,并且也会修改请求和响应。 +在 `before` 过滤器和路由中设置的实例变量可以被 `after` 过滤器访问: -~~~~ruby +```ruby after do puts response.status end -~~~~ +``` 请注意:除非你显式使用 `body` 方法,而不是在路由中直接返回字符串, -消息体在后置过滤器是不可用的, 因为它在之后才会生成。 +响应主体在 `after` 过滤器是不可访问的, 因为它在之后才会生成。 过滤器可以可选地带有范式, 只有请求路径满足该范式时才会执行: -~~~~ruby +```ruby before '/protected/*' do authenticate! end @@ -898,11 +1240,11 @@ end after '/create/:slug' do |slug| session['last_slug'] = slug end -~~~~ +``` -和路由一样,过滤器也可以带有条件: +和路由一样,过滤器也可以带有条件: -~~~~ruby +```ruby before :agent => /Songbird/ do # ... end @@ -910,13 +1252,13 @@ end after '/blog/*', :host_name => 'example.com' do # ... end -~~~~ +``` ## 辅助方法 使用顶层的 `helpers` 方法来定义辅助方法, 以便在路由处理器和模板中使用: -~~~~ruby +```ruby helpers do def bar(name) "#{name}bar" @@ -926,14 +1268,29 @@ end get '/:name' do bar(params['name']) end -~~~~ +``` -### 使用 Sessions +也可以在多个分散的模块中定义辅助方法: -Session被用来在请求之间保持状态。如果被激活,每一个用户会话 -对应有一个session哈希: +```ruby +module FooUtils + def foo(name) "#{name}foo" end +end -~~~~ruby +module BarUtils + def bar(name) "#{name}bar" end +end + +helpers FooUtils, BarUtils +``` + +以上代码块与在应用类中包含模块等效。 + +### 使用会话 + +会话用于在请求之间保持状态。如果激活了会话,每一个用户会话都对应一个会话 hash: + +```ruby enable :sessions get '/' do @@ -943,14 +1300,14 @@ end get '/:value' do session['value'] = params['value'] end -~~~~ +``` -请注意 `enable :sessions` 实际上保存所有的数据在一个cookie之中。 -这可能不会总是做你想要的(比如,保存大量的数据会增加你的流量)。 -你可以使用任何的Rack session中间件,为了这么做, \*不要\*调用 -`enable :sessions`,而是 按照自己的需要引入你的中间件: +请注意 `enable :sessions` 实际将所有的数据保存在一个 cookie 中。 +这可能并不总是你想要的(cookie 中存储大量的数据会增加你的流量)。 +你可以使用任何 Rack session 中间件:要达到此目的,**不要**使用 `enable :sessions`, +而是按照自己的需要引入想使用的中间件: -~~~~ruby +```ruby use Rack::Session::Pool, :expire_after => 2592000 get '/' do @@ -960,45 +1317,70 @@ end get '/:value' do session['value'] = params['value'] end -~~~~ +``` -### 挂起 +为提高安全性,cookie 中的会话数据会被一个会话密码保护。Sinatra 会为你生成一个随机的密码。 +然而,每次启动应用时,该密码都会变化,你也可以自己设置该密码,以便所有的应用实例共享: -要想直接地停止请求,在过滤器或者路由中使用: +``` +set :session_secret, 'super secret' +``` -~~~~ruby +如果你想进一步配置会话,可以在设置 `sessions` 时提供一个选项 hash 作为第二个参数: + +``` +set :sessions, :domain => 'foo.com' +``` + +为了在 foo.com 的子域名间共享会话数据,可以在域名前添加一个 *.*: + +```ruby +set :sessions, :domain => '.foo.com' +``` + +### 中断请求 + +要想在过滤器或路由中立即中断一个请求: + +```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' -~~~~ +``` -### 让路 +当然也可以使用模板: -一个路由可以放弃处理,将处理让给下一个匹配的路由,使用 `pass`: +``` +halt erb(:error) +``` -~~~~ruby +### 传递请求 + +一个路由可以放弃对请求的处理并将处理让给下一个匹配的路由,这要通过 `pass` 实现: + +```ruby get '/guess/:who' do pass unless params['who'] == 'Frank' 'You got me!' @@ -1007,17 +1389,17 @@ end get '/guess/*' do 'You missed!' end -~~~~ +``` -路由代码块被直接退出,控制流继续前进到下一个匹配的路由。 -如果没有匹配的路由,将返回404。 +执行 `pass` 后,控制流从该路由代码块直接退出,并继续前进到下一个匹配的路由。 +如果没有匹配的路由,将返回 404。 ### 触发另一个路由 -有些时候,`pass` 并不是你想要的,你希望得到的是另一个路由的结果 -。简单的使用 `call` 可以做到这一点: +有些时候,`pass` 并不是你想要的,你希望得到的是调用另一个路由的结果。 +使用 `call` 就可以做到这一点: -~~~~ruby +```ruby get '/foo' do status, headers, body = call env.merge("PATH_INFO" => '/bar') [status, headers, body.map(&:upcase)] @@ -1026,27 +1408,22 @@ end get '/bar' do "bar" end -~~~~ +``` -请注意在以上例子中,你可以更加简化测试并增加性能,只要简单的移动 +请注意在以上例子中,你只需简单地移动 `"bar"` 到一个被 `/foo` 和 `/bar` 同时使用的辅助方法中, +就可以简化测试和增加性能。 - "bar"到一个被/foo +如果你希望请求发送到同一个应用,而不是应用副本,应使用 `call!` 而不是 `call`。 -和 `/bar`同时使用的helper。 +如果想更多了解关于 `call` 的信息,请查看 Rack 规范。 -如果你希望请求被发送到同一个应用,而不是副本, 使用 `call!` 而不是 -`call`. +### 设置响应主体、状态码和响应首部 -如果想更多了解 `call`,请察看 Rack specification。 +推荐在路由代码块的返回值中设定状态码和响应主体。 +但是,在某些场景下你可能想在别处设置响应主体,这时你可以使用 `body` 辅助方法。 +设置之后,你可以在那以后使用该方法访问响应主体: -### 设定 消息体,状态码和消息头 - -通过路由代码块的返回值来设定状态码和消息体不仅是可能的,而且是推荐的。 -但是,在某些场景中你可能想在作业流程中的特定点上设置消息体。 你可以通过 -`body` 辅助方法这么做。 如果你这样做了, -你可以在那以后使用该方法获得消息体: - -~~~~ruby +```ruby get '/foo' do body "bar" end @@ -1054,14 +1431,14 @@ end after do puts body end -~~~~ +``` -也可以传一个代码块给 `body`,它将会被Rack处理器执行( -这将可以被用来实现streaming,参见“返回值”)。 +也可以传递一个代码块给 `body` 方法, +它会被 Rack 处理器执行(这可以用来实现流式传输,参见“返回值”)。 -和消息体类似,你也可以设定状态码和消息头: +与响应主体类似,你也可以设定状态码和响应首部: -~~~~ruby +```ruby get '/foo' do status 418 headers \ @@ -1069,61 +1446,151 @@ get '/foo' do "Refresh" => "Refresh: 20; http://www.ietf.org/rfc/rfc2324.txt" body "I'm a tea pot!" end -~~~~ +``` -如同 `body`, 不带参数的 `headers` 和 `status` 可以用来访问 -他们你的当前值. +正如 `body` 方法,不带参数调用 `headers` 和 `status` 方法可以访问它们的当前值。 -### 媒体(MIME)类型 +### 响应的流式传输 -使用 `send_file` 或者静态文件的时候,Sinatra可能不能识别你的媒体类型。 -使用 `mime_type` 通过文件扩展名来注册它们: +有时你可能想在完全生成响应主体前返回数据。 +更极端的情况是,你希望在客户端关闭连接前一直发送数据。 +为满足这些需求,可以使用 `stream` 辅助方法而不必重新造轮子: -~~~~ruby +```ruby +get '/' do + stream do |out| + out << "It's gonna be legen -\n" + sleep 0.5 + out << " (wait for it) \n" + sleep 1 + out << "- dary!\n" + end +end +``` + +`stream` 辅助方法允许你实现流式 API 和 +[服务器端发送事件](https://w3c.github.io/eventsource/), +同时它也是实现 [WebSockets](https://en.wikipedia.org/wiki/WebSocket) 的基础。 +如果你应用的部分(不是全部)内容依赖于访问缓慢的资源,它也可以用来提高并发能力。 + +请注意流式传输,尤其是并发请求数,高度依赖于应用所使用的服务器。 +一些服务器可能根本不支持流式传输。 +如果服务器不支持,传递给 `stream` 方法的代码块执行完毕之后,响应主体会一次性地发送给客户端。 +Shotgun 完全不支持流式传输。 + +如果 `:keep_open` 作为可选参数传递给 `stream` 方法,将不会在流对象上调用 `close` 方法, +这允许你在控制流的下游某处手动关闭。该参数只对事件驱动的服务器(如 Thin 和 Rainbows)生效。 +其它服务器仍会关闭流式传输: + +```ruby +# 长轮询 + +set :server, :thin +connections = [] + +get '/subscribe' do + # 在服务器端的事件中注册客户端 + stream(:keep_open) do |out| + connections << out + # 清除关闭的连接 + connections.reject!(&:closed?) + end +end + +post '/:message' do + connections.each do |out| + # 通知客户端有条新消息 + out << params['message'] << "\n" + + # 使客户端重新连接 + out.close + end + + # 确认 + "message received" +end +``` + +### 日志 + +在请求作用域下,`logger` 辅助方法会返回一个 `Logger` 类的实例: + +```ruby +get '/' do + logger.info "loading data" + # ... +end +``` + +该 `logger` 方法会自动参考 Rack 处理器的日志设置。 +若日志被禁用,该方法会返回一个无关痛痒的对象,所以你完全不必担心这会影响路由和过滤器。 + +注意只有 `Sinatra::Application` 默认开启了日志,若你的应用继承自 `Sinatra::Base`, +很可能需要手动开启: + +```ruby +class MyApp < Sinatra::Base + configure :production, :development do + enable :logging + end +end +``` + +为避免使用任何与日志有关的中间件,需要将 `logging` 设置项设为 `nil`。 +然而,在这种情况下,`logger` 辅助方法会返回 `nil`。 +一种常见的使用场景是你想要使用自己的日志工具。 +Sinatra 会使用 `env['rack.logger']` 的值作为日志工具,无论该值是什么。 + +### 媒体类型 + +使用 `send_file` 或者静态文件的时候,Sinatra 可能不会识别你的媒体类型。 +使用 `mime_type` 通过文件扩展名来注册媒体类型: + +```ruby mime_type :foo, 'text/foo' -~~~~ +``` 你也可以使用 `content_type` 辅助方法: -~~~~ruby +```ruby get '/' do content_type :foo "foo foo foo" end -~~~~ +``` ### 生成 URL -为了生成URL,你需要使用 `url` 辅助方法, 例如,在Haml中: +为了生成 URL,你应当使用 `url` 辅助方法,例如,在 Haml 中: -~~~~ruby +```ruby %a{:href => url('/foo')} foo -~~~~ +``` -如果使用反向代理和Rack路由,生成URL的时候会考虑这些因素。 +如果使用了反向代理和 Rack 路由,生成 URL 的时候会考虑这些因素。 -这个方法还有一个别名 `to` (见下面的例子). +这个方法还有一个别名 `to` (见下面的例子)。 ### 浏览器重定向 -你可以通过 `redirect` 辅助方法触发浏览器重定向: +你可以通过 `redirect` 辅助方法触发浏览器重定向: -~~~~ruby +```ruby get '/foo' do redirect to('/bar') end -~~~~ +``` -其他参数的用法,与 `halt`相同: +其他参数的用法,与 `halt` 相同: -~~~~ruby +```ruby redirect to('/bar'), 303 -redirect 'http://google.com', 'wrong place, buddy' -~~~~ +redirect 'http://www.google.com/', 'wrong place, buddy' +``` -用 `redirect back`可以把用户重定向到原始页面: +用 `redirect back` 可以把用户重定向到原始页面: -~~~~ruby +```ruby get '/foo' do "
do something" end @@ -1132,17 +1599,17 @@ get '/bar' do do_something redirect back end -~~~~ +``` -如果想传递参数给redirect,可以用query string: +如果想传递参数给 redirect,可以用查询字符串: -~~~~ruby +```ruby redirect to('/bar?sum=42') -~~~~ +``` -或者用session: +或者使用会话: -~~~~ruby +```ruby enable :sessions get '/foo' do @@ -1153,65 +1620,61 @@ end get '/bar' do session['secret'] end -~~~~ +``` ### 缓存控制 -要使用HTTP缓存,必须正确地设定消息头。 +正确设置响应首部是合理利用 HTTP 缓存的基础。 -你可以这样设定 Cache-Control 消息头: +可以这样设定 Cache-Control 首部字段: -~~~~ruby +```ruby get '/' do cache_control :public "cache it!" end -~~~~ +``` -核心提示: 在前置过滤器中设定缓存. +核心提示: 应当在 `before` 过滤器中设定缓存。 -~~~~ruby +```ruby before do cache_control :public, :must_revalidate, :max_age => 60 end -~~~~ +``` -如果你正在用 `expires` 辅助方法设定对应的消息头 `Cache-Control` -会自动设定: +如果你使用 `expires` 辅助方法设定响应的响应首部, 会自动设定 `Cache-Control` 字段: -~~~~ruby +```ruby before do expires 500, :public, :must_revalidate end -~~~~ +``` -为了合适地使用缓存,你应该考虑使用 `etag` 和 `last_modified`方法。 -推荐在执行繁重任务\*之前\*使用这些helpers,这样一来, -如果客户端在缓存中已经有相关内容,就会立即得到显示。 +为了合理使用缓存,你应该考虑使用 `etag` 或 `last_modified` 方法。 +推荐在执行繁重任务*之前*使用这些辅助方法,这样一来, +如果客户端在缓存中已经有相关内容,就会立即得到响应: - -~~~~ruby +```ruby get '/article/:id' do @article = Article.find params['id'] last_modified @article.updated_at etag @article.sha1 erb :article end -~~~~ +``` -使用 [weak -ETag](http://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation) -也是有可能的: +也可以使用 [weak ETag](https://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation): -~~~~ruby +```ruby etag @article.sha1, :weak -~~~~ +``` -这些辅助方法并不会为你做任何缓存,而是将必要的信息传送给你的缓存 -如果你在寻找缓存的快速解决方案,试试 -[rack-cache](https://github.com/rtomayko/rack-cache): +这些辅助方法并不会为你做任何缓存,而是将必要的信息发送给你的缓存。 +如果你正在寻找快捷的反向代理缓存方案,可以尝试 +[rack-cache](https://github.com/rtomayko/rack-cache): -~~~~ruby +```ruby require "rack/cache" require "sinatra" @@ -1222,138 +1685,201 @@ get '/' do sleep 5 "hello" end -~~~~ +``` + +使用 `:statis_cache_control` 设置(见下文)为静态文件添加 `Cache-Control` 首部字段。 + +根据 RFC 2616,如果 If-Match 或 If-None-Match 首部设置为 `*`,根据所请求的资源存在与否, +你的应用应当有不同的行为。 +Sinatra 假设安全请求(如 GET)和幂等性请求(如 PUT)所访问的资源是已经存在的, +而其它请求(如 POST 请求)所访问的资源是新资源。 +你可以通过传入 `:new_resource` 选项改变这一行为。 + +```ruby +get '/create' do + etag '', :new_resource => true + Article.create + erb :new_article +end +``` + +如果你仍想使用 weak ETag,可以传入一个 `:kind` 选项: + +```ruby +etag '', :new_resource => true, :kind => :weak +``` ### 发送文件 -为了发送文件,你可以使用 `send_file` 辅助方法: +为了将文件的内容作为响应返回,可以使用 `send_file` 辅助方法: -~~~~ruby +```ruby get '/' do send_file 'foo.png' end -~~~~ +``` -也可以带一些选项: +该辅助方法接受一些选项: -~~~~ruby +```ruby send_file 'foo.png', :type => :jpg -~~~~ +``` 可用的选项有:
-
filename
-
响应中的文件名,默认是真实文件的名字。
+
filename
+
响应中使用的文件名,默认是真实的文件名。
-
last_modified
-
Last-Modified 消息头的值,默认是文件的mtime(修改时间)。
+
last_modified
+
Last-Modified 响应首部的值,默认是文件的 mtime (修改时间)。
-
type
-
使用的内容类型,如果没有会从文件扩展名猜测。
+
type
+
Content-Type 响应首部的值,如果未指定,会根据文件扩展名猜测。
-
disposition
-
- 用于 Content-Disposition,可能的包括: nil (默认), :attachment 和 - :inline -
+
disposition
+
+ Content-Disposition 响应首部的值, + 可选的值有: nil (默认)、:attachment 和 + :inline +
-
length
-
Content-Length 的值,默认是文件的大小。
+
length
+
Content-Length 响应首部的值,默认是文件的大小。
+ +
status
+
+ 将要返回的状态码。当以一个静态文件作为错误页面时,这很有用。 + + 如果 Rack 处理器支持的话,Ruby 进程也能使用除 streaming 以外的方法。 + 如果你使用这个辅助方法, Sinatra会自动处理 range 请求。 +
-如果Rack处理器支持的话,Ruby进程也能使用除streaming以外的方法。 -如果你使用这个辅助方法, Sinatra会自动处理range请求。 - ### 访问请求对象 -传入的请求对象可以在请求层(过滤器,路由,错误处理) 通过 `request` -方法被访问: +传入的请求对象可以在请求层(过滤器、路由、错误处理器内部)通过 `request` 方法访问: -~~~~ruby +```ruby # 在 http://example.com/example 上运行的应用 get '/foo' do - request.body # 被客户端设定的请求体(见下) - request.scheme # "http" - request.script_name # "/example" - request.path_info # "/foo" - request.port # 80 - request.request_method # "GET" - request.query_string # "" - request.content_length # request.body的长度 - request.media_type # request.body的媒体类型 - request.host # "example.com" - request.get? # true (其他动词也具有类似方法) - request.form_data? # false - request["SOME_HEADER"] # SOME_HEADER header的值 - request.referrer # 客户端的referrer 或者 '/' - request.user_agent # user agent (被 :agent 条件使用) - request.cookies # 浏览器 cookies 哈希 - request.xhr? # 这是否是ajax请求? - request.url # "http://example.com/example/foo" - request.path # "/example/foo" - request.ip # 客户端IP地址 - request.secure? # false(如果是ssl则为true) - request.forwarded? # true (如果是运行在反向代理之后) - request.env # Rack中使用的未处理的env哈希 + t = %w[text/css text/html application/javascript] + request.accept # ['text/html', '*/*'] + request.accept? 'text/xml' # true + request.preferred_type(t) # 'text/html' + request.body # 客户端设定的请求主体(见下文) + request.scheme # "http" + request.script_name # "/example" + request.path_info # "/foo" + request.port # 80 + request.request_method # "GET" + request.query_string # "" + request.content_length # request.body 的长度 + request.media_type # request.body 的媒体类型 + request.host # "example.com" + request.get? # true (其它动词也具有类似方法) + request.form_data? # false + request["some_param"] # some_param 参数的值。[] 是访问 params hash 的捷径 + request.referrer # 客户端的 referrer 或者 '/' + request.user_agent # 用户代理 (:agent 条件使用该值) + request.cookies # 浏览器 cookies 哈希 + request.xhr? # 这是否是 ajax 请求? + request.url # "http://example.com/example/foo" + request.path # "/example/foo" + request.ip # 客户端 IP 地址 + request.secure? # false (如果是 ssl 则为 true) + request.forwarded? # true (如果是运行在反向代理之后) + request.env # Rack 中使用的未处理的 env hash end -~~~~ +``` 一些选项,例如 `script_name` 或者 `path_info` 也是可写的: -~~~~ruby +```ruby before { request.path_info = "/" } get "/" do "all requests end up here" end -~~~~ +``` -`request.body` 是一个IO或者StringIO对象: +`request.body` 是一个 IO 或者 StringIO 对象: -~~~~ruby +```ruby post "/api" do request.body.rewind # 如果已经有人读了它 data = JSON.parse request.body.read "Hello #{data['name']}!" end -~~~~ +``` ### 附件 -你可以使用 `attachment` 辅助方法来告诉浏览器响应 -应当被写入磁盘而不是在浏览器中显示。 +你可以使用 `attachment` 辅助方法来告诉浏览器响应应当被写入磁盘而不是在浏览器中显示。 -~~~~ruby +```ruby get '/' do attachment "store it!" end -~~~~ +``` -你也可以传递一个文件名: +你也可以传递给该方法一个文件名: -~~~~ruby +```ruby get '/' do attachment "info.txt" "store it!" end -~~~~ +``` + +### 处理日期和时间 + +Sinatra 提供了一个 `time_for` 辅助方法,其目的是根据给定的值生成 Time 对象。 +该方法也能够转换 `DateTime`、`Date` 和类似的类: + +```ruby +get '/' do + pass if Time.now > time_for('Dec 23, 2012') + "still time" +end +``` + +`expires`、`last_modified` 和类似方法都在内部使用了该方法。 +因此,通过在应用中重写 `time_for` 方法,你可以轻松地扩展这些方法的行为: + +```ruby +helpers do + def time_for(value) + case value + when :yesterday then Time.now - 24*60*60 + when :tomorrow then Time.now + 24*60*60 + else super + end + end +end + +get '/' do + last_modified :yesterday + expires :tomorrow + "hello" +end +``` ### 查找模板文件 -`find_template` 辅助方法被用于在填充时查找模板文件: +`find_template` 辅助方法用于在渲染时查找模板文件: -~~~~ruby +```ruby find_template settings.views, 'foo', Tilt[:haml] do |file| puts "could be #{file}" end -~~~~ +``` -这并不是很有用。但是在你需要重载这个方法 -来实现你自己的查找机制的时候有用。 比如,如果你想支持多于一个视图目录: +这其实并不是很有用,除非你需要重载这个方法来实现你自己的查找机制。 +比如,如果你想使用不只一个视图目录: -~~~~ruby +```ruby set :views, ['views', 'templates'] helpers do @@ -1361,11 +1887,11 @@ helpers do Array(views).each { |v| super(v, name, engine, &block) } end end -~~~~ +``` -另一个例子是为不同的引擎使用不同的目录: +另一个例子是对不同的引擎使用不同的目录: -~~~~ruby +```ruby set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views' helpers do @@ -1375,58 +1901,57 @@ helpers do super(folder, name, engine, &block) end end -~~~~ +``` -你可以很容易地包装成一个扩展然后与他人分享! +你可以很容易地封装成一个扩展,然后与他人分享! -请注意 `find_template` 并不会检查文件真的存在, -而是对任何可能的路径调用给入的代码块。这并不会带来性能问题, 因为 -`render` 会在找到文件的时候马上使用 `break` 。 -同样的,模板的路径(和内容)会在除development mode以外的场合 -被缓存。你应该时刻提醒自己这一点, 如果你真的想写一个非常疯狂的方法。 +请注意 `find_template` 并不会检查文件是否存在,而是为任何可能的路径调用传入的代码块。 +这并不会导致性能问题,因为 `render` 会在找到文件的时候马上使用 `break`。 +同样的,模板的路径(和内容)会在 development 以外的模式下被缓存。 +你应该时刻提醒自己这一点, 如果你真的想写一个非常疯狂的方法的话。 ## 配置 -运行一次,在启动的时候,在任何环境下: +在启动时运行一次,在任何环境下都是如此: -~~~~ruby +```ruby configure do - # setting one option + # 设置一个选项 set :option, 'value' - # setting multiple options + # 设置多个选项 set :a => 1, :b => 2 - # same as `set :option, true` + # 等同于 `set :option, true` enable :option - # same as `set :option, false` + # 等同于 `set :option, false` disable :option - # you can also have dynamic settings with blocks + # 也可以用代码块做动态设置 set(:css_dir) { File.join(views, 'css') } end -~~~~ +``` -只当环境 (RACK\_ENV environment 变量) 被设定为 `:production`的时候运行: +只有当环境 (`RACK_ENV` 环境变量) 被设定为 `:production` 时才运行: -~~~~ruby +```ruby configure :production do ... end -~~~~ +``` -当环境被设定为 `:production` 或者 `:test`的时候运行: +当环境被设定为 `:production` 或者 `:test` 时运行: -~~~~ruby +```ruby configure :production, :test do ... end -~~~~ +``` -你可以使用 `settings` 获得这些配置: +你可以用 `settings` 访问这些配置项: -~~~~ruby +```ruby configure do set :foo, 'bar' end @@ -1436,208 +1961,271 @@ get '/' do settings.foo # => 'bar' ... end -~~~~ +``` + +### 配置攻击防护 + +Sinatra 使用 [Rack::Protection](https://github.com/sinatra/rack-protection#readme) +来抵御常见的攻击。你可以轻易地禁用该行为(但这会大大增加应用被攻击的概率)。 + +```ruby +disable :protection +``` + +为了绕过某单层防护,可以设置 `protection` 为一个选项 hash: + +```ruby +set :protection, :except => :path_traversal +``` + +你可以传入一个数组,以禁用一系列防护措施: + +```ruby +set :protection, :except => [:path_traversal, :session_hijacking] +``` + +默认地,如果 `:sessions` 是启用的,Sinatra 只会使用基于会话的防护措施。 +当然,有时你可能想根据自己的需要设置会话。 +在这种情况下,你可以通过传入 `:session` 选项来开启基于会话的防护。 + +```ruby +use Rack::Session::Pool +set :protection, :session => true +``` ### 可选的设置
-
absolute_redirects
-
-

- 如果被禁用,Sinatra会允许使用相对路径重定向, 但是,Sinatra就不再遵守 - RFC 2616标准 (HTTP 1.1), 该标准只允许绝对路径重定向。 -

+
absolute_redirects
+
+ 如果被禁用,Sinatra 会允许使用相对路径重定向。 + 然而这样的话,Sinatra 就不再遵守 RFC 2616 (HTTP 1.1), 该协议只允许绝对路径重定向。 +
+
+ 如果你的应用运行在一个未恰当设置的反向代理之后,你需要启用这个选项。 + 注意 url 辅助方法仍然会生成绝对 URL,除非你传入false 作为第二参数。 +
+
默认禁用。
-

- 如果你的应用运行在一个未恰当设置的反向代理之后, - 你需要启用这个选项。注意 url 辅助方法 仍然会生成绝对 URL,除非你传入 - false 作为第二参数。 -

-

- 默认禁用。 -

- +
add_charset
+
+ 设置 content_type 辅助方法会自动为媒体类型加上字符集信息。 + 你应该添加而不是覆盖这个选项: + settings.add_charset << "application/foobar" +
-
add_charset
-
-

- 设定 content_type 辅助方法会 自动加上字符集信息的多媒体类型。 -

+
app_file
+
+ 主应用文件的路径,用来检测项目的根路径, views 和 public 文件夹和内联模板。 +
-

- 你应该添加而不是覆盖这个选项: - settings.add_charset << "application/foobar" -

- +
bind
+
+ 绑定的 IP 地址 (默认: 0.0.0.0,开发环境下为 localhost)。 + 仅对于内置的服务器有用。 +
-
app_file
-
- 主应用文件,用来检测项目的根路径, views和public文件夹和内联模板。 -
+
default_encoding
+
默认编码 (默认为 "utf-8")。
-
bind
-
- 绑定的IP 地址 (默认: 0.0.0.0)。 仅对于内置的服务器有用。 -
+
dump_errors
+
在日志中显示错误。
-
default_encoding
-
- 默认编码 (默认为 "utf-8")。 -
+
environment
+
+ 当前环境,默认是 ENV['RACK_ENV'], + 或者 "development" (如果 ENV['RACK_ENV'] 不可用)。 +
-
dump_errors
-
- 在log中显示错误。 -
+
logging
+
使用 logger。
-
environment
-
- 当前环境,默认是 ENV['RACK_ENV'], 或者 "development" 如果不可用。 -
+
lock
+
对每一个请求放置一个锁,只使用进程并发处理请求。
+
如果你的应用不是线程安全则需启动。默认禁用。
-
logging
-
- 使用logger -
+
method_override
+
+ 使用 _method 魔法,以允许在不支持的浏览器中在使用 put/delete 方法提交表单。 +
-
lock
-
-

- 对每一个请求放置一个锁, 只使用进程并发处理请求。 -

+
port
+
监听的端口号。只对内置服务器有用。
-

- 如果你的应用不是线程安全则需启动。 默认禁用。 -

- +
prefixed_redirects
+
+ 如果没有使用绝对路径,是否添加 request.script_name 到重定向请求。 + 如果添加,redirect '/foo' 会和 redirect to('/foo') 相同。 + 默认禁用。 +
-
method_override
-
- 使用 _method 魔法以允许在旧的浏览器中在 表单中使用 put/delete 方法 -
+
protection
+
是否启用网络攻击防护。参见上面的保护部分
-
port
-
- 监听的端口号。只对内置服务器有用。 -
+
public_dir
+
public_folder 的别名。见下文。
-
prefixed_redirects
-
- 是否添加 request.script_name 到 - 重定向请求,如果没有设定绝对路径。那样的话 redirect '/foo' 会和 - redirect to('/foo')起相同作用。默认禁用。 -
+
public_folder
+
+ public 文件存放的路径。只有启用了静态文件服务(见下文的 static)才会使用。 + 如果未设置,默认从 app_file 推断。 +
-
public_folder
-
- public文件夹的位置。 -
+
reload_templates
+
+ 是否每个请求都重新载入模板。在开发模式下开启。 +
-
reload_templates
-
- 是否每个请求都重新载入模板。 在development mode和 Ruby 1.8.6 - 中被企业(用来 消除一个Ruby内存泄漏的bug)。 -
+
root
+
到项目根目录的路径。默认从 app_file 设置推断。
-
root
-
- 项目的根目录。 -
+
raise_errors
+
+ 抛出异常(会停止应用)。 + 当 environment 设置为 "test" 时会默认开启,其它环境下默认禁用。 +
-
raise_errors
-
- 抛出异常(应用会停下)。 -
+
run
+
如果启用,Sinatra 会负责 web 服务器的启动。若使用 rackup 或其他方式则不要启用。
-
run
-
- 如果启用,Sinatra会开启web服务器。 如果使用rackup或其他方式则不要启用。 -
+
running
+
内置的服务器在运行吗? 不要修改这个设置!
-
running
-
- 内置的服务器在运行吗? 不要修改这个设置! -
+
server
+
服务器,或用于内置服务器的服务器列表。顺序表明了优先级,默认顺序依赖 Ruby 实现。
-
server
-
- 服务器,或用于内置服务器的列表。 默认是 [‘thin’, ‘mongrel’, ‘webrick’], - 顺序表明了 优先级。 -
+
sessions
+
+ 使用 Rack::Session::Cookie,启用基于 cookie 的会话。 + 查看“使用会话”部分以获得更多信息。 +
-
sessions
-
- 开启基于cookie的sesson。 -
+
show_exceptions
+
+ 当有异常发生时,在浏览器中显示一个 stack trace。 + 当 environment 设置为 "development" 时,默认启用, + 否则默认禁用。 +
+
+ 也可以设置为 :after_handler, + 这会在浏览器中显示 stack trace 之前触发应用级别的错误处理。 +
-
show_exceptions
-
- 在浏览器中显示一个stack trace。 -
+
static
+
决定 Sinatra 是否服务静态文件。
+
当服务器能够自行服务静态文件时,会禁用。
+
禁用会增强性能。
+
在经典风格中默认启用,在模块化应用中默认禁用。
-
static
-
- Sinatra是否处理静态文件。 当服务器能够处理则禁用。 禁用会增强性能。 - 默认开启。 -
+
static_cache_control
+
+ 当 Sinatra 提供静态文件服务时,设置此选项为响应添加 Cache-Control 首部。 + 使用 cache_control 辅助方法。默认禁用。 +
+
+ 当设置多个值时使用数组: + set :static_cache_control, [:public, :max_age => 300] +
-
views
-
- views 文件夹。 -
+
threaded
+
+ 若设置为 true,会告诉 Thin 使用 EventMachine.defer 处理请求。 +
+ +
traps
+
Sinatra 是否应该处理系统信号。
+ +
views
+
views 文件夹的路径。若未设置则会根据 app_file 推断。
+ +
x_cascade
+
若没有路由匹配,是否设置 X-Cascade 首部。默认为 true
+## 环境 + +Sinatra 中有三种预先定义的环境:"development"、"production" 和 "test"。 +环境可以通过 `RACK_ENV` 环境变量设置。默认值为 "development"。 +在开发环境下,每次请求都会重新加载所有模板, +特殊的 `not_found` 和 `error` 错误处理器会在浏览器中显示 stack trace。 +在测试和生产环境下,模板默认会缓存。 + +在不同的环境下运行,设置 `RACK_ENV` 环境变量: + +```shell +RACK_ENV=production ruby my_app.rb +``` + +可以使用预定义的三种方法: `development?`、`test?` 和 `production?` 来检查当前环境: + +```ruby +get '/' do + if settings.development? + "development!" + else + "not development" + end +end +``` ## 错误处理 -错误处理在与路由和前置过滤器相同的上下文中运行, +错误处理器在与路由和 before 过滤器相同的上下文中运行, 这意味着你可以使用许多好东西,比如 `haml`, `erb`, `halt`,等等。 ### 未找到 -当一个 `Sinatra::NotFound` 错误被抛出的时候, -或者响应状态码是404,`not_found` 处理器会被调用: +当一个 `Sinatra::NotFound` 错误被抛出时,或者当响应的状态码是 404 时, +会调用 `not_found` 处理器: -~~~~ruby +```ruby not_found do - 'This is nowhere to be found' + 'This is nowhere to be found.' end -~~~~ +``` ### 错误 -`error` 处理器,在任何路由代码块或者过滤器抛出异常的时候会被调用。 -异常对象可以通过`sinatra.error` Rack 变量获得: +在任何路由代码块或过滤器抛出异常时,会调用 `error` 处理器。 +但注意在开发环境下只有将 show exceptions 项设置为 `:after_handler` 时,才会生效。 -~~~~ruby +```ruby +set :show_exceptions, :after_handler +``` + +可以用 Rack 变量 `sinatra.error` 访问异常对象: + +```ruby error do 'Sorry there was a nasty error - ' + env['sinatra.error'].message end -~~~~ +``` 自定义错误: -~~~~ruby +```ruby error MyCustomError do 'So what happened was...' + env['sinatra.error'].message end -~~~~ +``` -那么,当这个发生的时候: +当下面的代码执行时: -~~~~ruby +```ruby get '/' do raise MyCustomError, 'something bad' end -~~~~ +``` -你会得到: +你会得到错误信息: - So what happened was... something bad +``` +So what happened was... something bad +``` -另一种替代方法是,为一个状态码安装错误处理器: +或者,你也可以为状态码设置错误处理器: -~~~~ruby +```ruby error 403 do 'Access forbidden' end @@ -1645,29 +2233,28 @@ end get '/secret' do 403 end -~~~~ +``` -或者一个范围: +或者为某个范围内的状态码统一设置错误处理器: -~~~~ruby +```ruby error 400..510 do 'Boom' end -~~~~ +``` -在运行在development环境下时,Sinatra会安装特殊的 `not_found` 和 `error` -处理器。 +在开发环境下,Sinatra会使用特殊的 `not_found` 和 `error` 处理器, +以便在浏览器中显示美观的 stack traces 和额外的调试信息。 ## Rack 中间件 -Sinatra 依靠 [Rack](http://rack.github.io/), 一个面向Ruby -web框架的最小标准接口。 -Rack的一个最有趣的面向应用开发者的能力是支持“中间件”——坐落在服务器和你的应用之间, -监视 并/或 操作HTTP请求/响应以 提供多样类型的常用功能。 +Sinatra 依赖 [Rack](http://rack.github.io/), 一个面向 Ruby 网络框架的最小化标准接口。 +Rack 最有趣的功能之一是支持“中间件”——位于服务器和你的应用之间的组件, +它们监控或操作 HTTP 请求/响应以提供多种常用功能。 -Sinatra 让建立Rack中间件管道异常简单, 通过顶层的 `use` 方法: +Sinatra 通过顶层的 `use` 方法,让建立 Rack 中间件管道异常简单: -~~~~ruby +```ruby require 'sinatra' require 'my_custom_middleware' @@ -1677,29 +2264,33 @@ use MyCustomMiddleware get '/hello' do 'Hello World' end -~~~~ +``` -`use` 的语义和在 -[Rack::Builder](http://rubydoc.info/github/rack/rack/master/Rack/Builder) -DSL(在rack文件中最频繁使用)中定义的完全一样。例如,`use` 方法接受 -多个/可变 参数,包括代码块: +`use` 的语义和在 [Rack::Builder](http://www.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 -~~~~ +``` -Rack中分布有多样的标准中间件,针对日志, -调试,URL路由,认证和session处理。 Sinatra会自动使用这里面的大部分组件, -所以你一般不需要显示地 `use` 他们。 +Rack 拥有有多种标准中间件,用于日志、调试、URL 路由、认证和会话处理。 +根据配置,Sinatra 可以自动使用这里面的许多组件, +所以你一般不需要显式地 `use` 它们。 + +你可以在 [rack](https://github.com/rack/rack/tree/master/lib/rack)、 +[rack-contrib](https://github.com/rack/rack-contrib#readm) 或 +[Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware) +中找到有用的中间件。 ## 测试 -Sinatra的测试可以使用任何基于Rack的测试程序库或者框架来编写。 -[Rack::Test](http://gitrdoc.com/brynary/rack-test) 是推荐候选: +可以使用任何基于 Rack 的测试程序库或者框架来编写Sinatra的测试。 +推荐使用 [Rack::Test](http://www.rubydoc.info/github/brynary/rack-test/master/frames): -~~~~ruby +```ruby require 'my_sinatra_app' require 'minitest/autorun' require 'rack/test' @@ -1726,22 +2317,20 @@ class MyAppTest < Minitest::Test assert_equal "You're using Songbird!", last_response.body end end -~~~~ +``` -请注意: 内置的 Sinatra::Test 模块和 Sinatra::TestHarness 类 在 0.9.2 -版本已废弃。 +注意:如果你使用 Sinatra 的模块化风格,应该用你应用的类名替代 `Sinatra::Application`。 -## Sinatra::Base - 中间件,程序库和模块化应用 +## Sinatra::Base - 中间件、库和模块化应用 -把你的应用定义在顶层,对于微型应用这会工作得很好, -但是在构建可复用的组件时候会带来客观的不利, 比如构建Rack中间件,Rails -metal,带有服务器组件的简单程序库, -或者甚至是Sinatra扩展。顶层的DSL污染了Object命名空间, -并假定了一个微型应用风格的配置 (例如, 单一的应用文件, ./public 和 -./views 目录,日志,异常细节页面,等等)。 这时应该让 Sinatra::Base -走到台前了: +在顶层定义你的应用很适合微型项目, +但是在构建可复用的组件(如 Rack 中间件、Rails metal、带服务器组件的库或 Sinatra 扩展)时, +却有相当大的缺陷。 +顶层 DSL 认为你采用的是微型应用风格的配置 (例如:唯一应用文件、 +`./public` 和 `./views` 目录、日志、异常细节页面等)。 +如果你的项目不采用微型应用风格,应该使用 `Sinatra::Base`: -~~~~ruby +```ruby require 'sinatra/base' class MyApp < Sinatra::Base @@ -1752,120 +2341,167 @@ class MyApp < Sinatra::Base 'Hello world!' end end -~~~~ +``` -Sinatra::Base子类可用的方法实际上就是通过顶层 DSL 可用的方法。 -大部分顶层应用可以通过两个改变转换成Sinatra::Base组件: +Sinatra::Base 的子类可以使用的方法实际上就是顶层 DSL 中可以使用的方法。 +大部分顶层应用可以通过两方面的改变转换为 Sinatra::Base 组件: -- 你的文件应当引入 `sinatra/base` 而不是 `sinatra`; - 否则,所有的Sinatra的 DSL 方法将会被引进到 主命名空间。 +* 你的文件应当引入 `sinatra/base` 而不是 `sinatra`; +否则,Sinatra 的所有 DSL 方法将会被导入主命名空间。 -- 把你的应用的路由,错误处理,过滤器和选项放在 - 一个Sinatra::Base的子类中。 +* 把应用的路由、错误处理器、过滤器和选项放在一个 Sinatra::Base 的子类中。 -`+Sinatra::Base+` 是一张白纸。大部分的选项默认是禁用的, -包含内置的服务器。参见 -[选项和配置](http://sinatra.github.com/configuration.html) -查看可用选项的具体细节和他们的行为。 +`Sinatra::Base` 是一个白板。大部分选项(包括内置的服务器)默认是禁用的。 +可以参考[配置](http://www.sinatrarb.com/configuration.html) +以查看可用选项的具体细节和它们的行为。如果你想让你的应用更像顶层定义的应用(即经典风格), +你可以继承 `Sinatra::Applicaiton`。 -### 模块化 vs. 传统的方式 +```ruby +require 'sinatra/base' -与通常的认识相反,传统的方式没有任何错误。 -如果它适合你的应用,你不需要转换到模块化的应用。 +class MyApp < Sinatra::Application + get '/' do + 'Hello world!' + end +end +``` -和模块化方式相比只有两个缺点: +### 模块化风格 vs. 经典风格 -- 你对每个Ruby进程只能定义一个Sinatra应用,如果你需要更多, - 切换到模块化方式。 +与通常的认识相反,经典风格并没有任何错误。 +如果它适合你的应用,你不需要切换到模块化风格。 -- 传统方式使用代理方法污染了 Object 。如果你打算 把你的应用封装进一个 - library/gem,转换到模块化方式。 +与模块化风格相比,经典风格的主要缺点在于,每个 Ruby 进程只能有一个 Sinatra 应用。 +如果你计划使用多个 Sinatra 应用,应该切换到模块化风格。 +你也完全可以混用模块化风格和经典风格。 -没有任何原因阻止你混合模块化和传统方式。 +如果从一种风格转换到另一种,你需要注意默认设置中的一些细微差别: -如果从一种转换到另一种,你需要注意settings中的 一些微小的不同: + + + + + + + - Setting Classic Modular + + + + + + - app_file file loading sinatra nil - run $0 == app_file false - logging true false - method_override true false - inline_templates true false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
设置经典风格模块化风格模块化风格
app_file加载 sinatra 的文件继承 Sinatra::Base 的文件继承 Sinatra::Application 的文件
run$0 == app_filefalsefalse
loggingtruefalsetrue
method_overridetruefalsetrue
inline_templatestruefalsetrue
statictrueFile.exist?(public_folder)true
### 运行一个模块化应用 -有两种方式运行一个模块化应用,使用 `run!`来运行: +模块化应用的启动有两种常见方式,其中之一是使用 `run!` 方法主动启动: -~~~~ruby +```ruby # my_app.rb require 'sinatra/base' class MyApp < Sinatra::Base - # ... app code here ... + # ... 这里是应用代码 ... - # start the server if ruby file executed directly + # 如果直接执行该文件,那么启动服务器 run! if app_file == $0 end -~~~~ +``` -运行: +执行该文件就会启动服务器: - ruby my_app.rb +```shell +ruby my_app.rb +``` -或者使用一个 `config.ru`,允许你使用任何Rack处理器: +另一种方式是使用 `config.ru` 文件,这种方式允许你使用任何 Rack 处理器: -~~~~ruby -# config.ru +```ruby +# config.ru (用 rackup 启动) require './my_app' run MyApp -~~~~ +``` -运行: +运行: - rackup -p 4567 +```shell +rackup -p 4567 +``` -### 使用config.ru运行传统方式的应用 +### 使用 config.ru 运行经典风格的应用 编写你的应用: -~~~~ruby +```ruby # app.rb require 'sinatra' get '/' do 'Hello world!' end -~~~~ +``` -加入相应的 `config.ru`: +添加相应的 `config.ru`: -~~~~ruby +```ruby require './app' run Sinatra::Application -~~~~ +``` -### 什么时候用 config.ru? +### 何时使用 config.ru? -以下情况你可能需要使用 `config.ru`: +下列情况,推荐使用 `config.ru`: -- 你要使用不同的 Rack 处理器部署 (Passenger, Unicorn, Heroku, …). +* 部署时使用不同的 Rack 处理器 (Passenger、Unicorn、Heroku 等)。 +* 使用多个 `Sinatra::Base` 的子类。 +* 把 Sinatra 当作中间件使用,而非端点。 -- 你想使用一个或者多个 `Sinatra::Base`的子类. +**你不必仅仅因为想使用模块化风格而切换到 `config.ru`,同样的, +你也不必仅仅因为要运行 `config.ru` 而切换到模块化风格。** -- 你只想把Sinatra当作中间件使用,而不是端点。 +### 把 Sinatra 当作中间件使用 -**你并不需要切换到`config.ru`仅仅因为你切换到模块化方式, -你同样不需要切换到模块化方式, 仅仅因为要运行 `config.ru`.** +Sinatra 可以使用其它 Rack 中间件, +反过来,任何 Sinatra 应用程序自身都可以被当作中间件,添加到任何 Rack 端点前面。 +此端点可以是任何 Sinatra 应用,或任何基于 Rack 的应用程序 (Rails/Ramaze/Camping/...): -### 把Sinatra当成中间件来使用 - -不仅Sinatra有能力使用其他的Rack中间件,任何Sinatra -应用程序都可以反过来自身被当作中间件,被加在任何Rack端点前面。 -这个端点可以是任何Sinatra应用,或者任何基于Rack的应用程序 -(Rails/Ramaze/Camping/…)。 - -~~~~ruby +```ruby require 'sinatra/base' class LoginScreen < Sinatra::Base @@ -1874,7 +2510,7 @@ class LoginScreen < Sinatra::Base get('/login') { haml :login } post('/login') do - if params['name'] = 'admin' and params['password'] = 'admin' + if params['name'] == 'admin' && params['password'] == 'admin' session['user_name'] = params['name'] else redirect '/login' @@ -1883,7 +2519,7 @@ class LoginScreen < Sinatra::Base end class MyApp < Sinatra::Base - # 在前置过滤器前运行中间件 + # 中间件的执行发生在 before 过滤器之前 use LoginScreen before do @@ -1894,273 +2530,343 @@ class MyApp < Sinatra::Base get('/') { "Hello #{session['user_name']}." } end -~~~~ +``` -## 变量域和绑定 +### 创建动态应用 -当前所在的变量域决定了哪些方法和变量是可用的。 +有时你希望在运行时创建新应用,而不必把应用预先赋值给常量。这时可以使用 `Sinatra.new`: -### 应用/类 变量域 +```ruby +require 'sinatra/base' +my_app = Sinatra.new { get('/') { "hi" } } +my_app.run! +``` -每个Sinatra应用相当与Sinatra::Base的一个子类。 -如果你在使用顶层DSL(`require 'sinatra'`),那么这个类就是 -Sinatra::Application,或者这个类就是你显式创建的子类。 -在类层面,你具有的方法类似于 \`get\` 或者 \`before\`,但是你不能访问 -\`request\` 对象或者 \`session\`, 因为对于所有的请求, -只有单一的应用类。 +`Sinatra.new` 接受一个可选的参数,表示要继承的应用: -通过 \`set\` 创建的选项是类层面的方法: +```ruby +# config.ru (用 rackup 启动) +require 'sinatra/base' -~~~~ruby +controller = Sinatra.new do + enable :logging + helpers MyHelpers +end + +map('/a') do + run Sinatra.new(controller) { get('/') { 'a' } } +end + +map('/b') do + run Sinatra.new(controller) { get('/') { 'b' } } +end +``` + +当你测试 Sinatra 扩展或在自己的类库中使用 Sinatra 时,这非常有用。 + +这也让把 Sinatra 当作中间件使用变得极其容易: + +```ruby +require 'sinatra/base' + +use Sinatra do + get('/') { ... } +end + +run RailsProject::Application +``` + +## 作用域和绑定 + +当前作用域决定了可以使用的方法和变量。 + +### 应用/类作用域 + +每个 Sinatra 应用都对应 `Sinatra::Base` 类的一个子类。 +如果你在使用顶层 DSL (`require 'sinatra'`),那么这个类就是 `Sinatra::Application`, +否则该类是你显式创建的子类。 +在类层面,你可以使用 `get` 或 `before` 这样的方法, +但不能访问 `request` 或 `session` 对象, 因为对于所有的请求,只有单一的应用类。 + +通过 `set` 创建的选项是类方法: + +```ruby class MyApp < Sinatra::Base - # 嘿,我在应用变量域! + # 嘿,我在应用作用域! set :foo, 42 foo # => 42 get '/foo' do - # 嘿,我不再处于应用变量域了! + # 嘿,我已经不在应用作用域了! end end -~~~~ +``` -在下列情况下你将拥有应用变量域的绑定: +下列位置绑定的是应用作用域: -- 在应用类中 +* 应用类内部 +* 通过扩展定义的方法内部 +* 传递给 `helpers` 方法的代码块内部 +* 作为 `set` 值的 procs/blocks 内部 +* 传递给 `Sinatra.new` 的代码块内部 -- 在扩展中定义的方法 +你可以这样访问变量域对象(应用类): +* 通过传递给 configure 代码块的对象 (`configure { |c| ... }`) +* 在请求作用域中使用 `settings` -- 传递给 \`helpers\` 的代码块 +### 请求/实例作用域 -- 用作\`set\`值的过程/代码块 +对于每个请求,Sinatra 会创建应用类的一个新实例。所有的处理器代码块都在该实例对象的作用域中运行。 +在该作用域中, 你可以访问 `request` 和 `session` 对象, +或调用渲染方法(如 `erb`、`haml`)。你可以在请求作用域中通过 `settings` 辅助方法 +访问应用作用域: -你可以访问变量域对象(就是应用类)就像这样: - -- 通过传递给代码块的对象 (`configure { |c| ... }`) - -- 在请求变量域中使用\`settings\` - -### 请求/实例 变量域 - -对于每个进入的请求,一个新的应用类的实例会被创建 -所有的处理器代码块在该变量域被运行。在这个变量域中, 你可以访问 -\`request\` 和 \`session\` 对象,或者调用填充方法比如 \`erb\` 或者 -\`haml\`。你可以在请求变量域当中通过\`settings\`辅助方法 -访问应用变量域: - -~~~~ruby +```ruby class MyApp < Sinatra::Base - # 嘿,我在应用变量域! + # 嘿,我在应用作用域! get '/define_route/:name' do - # 针对 '/define_route/:name' 的请求变量域 + # '/define_route/:name' 的请求作用域 @value = 42 settings.get("/#{params['name']}") do - # 针对 "/#{params['name']}" 的请求变量域 - @value # => nil (并不是相同的请求) + # "/#{params['name']}" 的请求作用域 + @value # => nil (并不是同一个请求) end "Route defined!" end end -~~~~ +``` -在以下情况将获得请求变量域: +以下位置绑定的是请求作用域: -- get/head/post/put/delete 代码块 +* get、head、post、put、delete、options、patch、link 和 unlink 代码块内部 +* before 和 after 过滤器内部 +* 辅助方法内部 +* 模板/视图内部 -- 前置/后置 过滤器 +### 代理作用域 -- 辅助方法 - -- 模板/视图 - -### 代理变量域 - -代理变量域只是把方法转送到类变量域。可是, -他并非表现得100%类似于类变量域, 因为你并不能获得类的绑定: +代理作用域只是把方法转送到类作用域。 +然而,它与类作用域的行为并不完全相同, 因为你并不能在代理作用域获得类的绑定。 只有显式地标记为供代理使用的方法才是可用的, -而且你不能和类变量域共享变量/状态。(解释:你有了一个不同的 \`self\`)。 -你可以显式地增加方法代理,通过调用 -`Sinatra::Delegator.delegate :method_name`。 +而且你不能和类作用域共享变量/状态。(解释:你有了一个不同的 `self`)。 +你可以通过调用 `Sinatra::Delegator.delegate :method_name` 显式地添加方法代理。 -在以下情况将获得代理变量域: +以下位置绑定的是代理变量域: +* 顶层绑定,如果你执行了 `require "sinatra"` +* 扩展了 `Sinatra::Delegator` 这一 mixin 的对象内部 -- 顶层的绑定,如果你做过 `require "sinatra"` - -- 在扩展了 \`Sinatra::Delegator\` mixin的对象 - -自己在这里看一下代码: [Sinatra::Delegator -mixin](http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/base.rb#L1128) +自己在这里看一下源码:[Sinatra::Delegator +mixin](https://github.com/sinatra/sinatra/blob/ca06364/lib/sinatra/base.rb#L1609-1633) 已经 -[被包含进了主命名空间](http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/main.rb#L28)。 +[被扩展进了 main 对象](https://github.com/sinatra/sinatra/blob/ca06364/lib/sinatra/main.rb#L28-30)。 ## 命令行 -Sinatra 应用可以被直接运行: +可以直接运行 Sinatra 应用: - ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER] +```shell +ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER] +``` 选项是: - -h # help - -p # 设定端口 (默认是 4567) - -o # 设定主机名 (默认是 0.0.0.0) - -e # 设定环境 (默认是 development) - -s # 限定 rack 服务器/处理器 (默认是 thin) - -x # 打开互斥锁 (默认是 off) +``` +-h # 显示帮助 +-p # 设置端口号 (默认是 4567) +-o # 设定主机名 (默认是 0.0.0.0) +-e # 设置环境 (默认是 development) +-s # 声明 rack 服务器/处理器 (默认是 thin) +-x # 打开互斥锁 (默认是 off) +``` + +### 多线程 + +_根据 Konstantin 的 [这个 StackOverflow 答案] [so-answer] 改写_ + +Sinatra 本身并不使用任何并发模型,而是将并发的任务留给底层的 +Rack 处理器(服务器),如 Thin、Puma 或 WEBrick。Sinatra 本身是线程安全的,所以 +Rack 处理器使用多线程并发模型并无任何问题。这意味着在启动服务器时,你必须指定特定 +Rack 处理器的正确调用方法。 +下面的例子展示了如何启动一个多线程的 Thin 服务器: + +```ruby +# app.rb + +require 'sinatra/base' + +class App < Sinatra::Base + get '/' do + "Hello, World" + end +end + +App.run! + +``` + +启动服务器的命令是: + +```shell +thin --threaded start +``` + + +[so-answer]: http://stackoverflow.com/questions/6278817/is-sinatra-multi-threaded/6282999#6282999) ## 必要条件 -推荐在 Ruby 1.8.7, 1.9.2, JRuby 或者 Rubinius 上安装Sinatra。 - -下面的Ruby版本是官方支持的: - +以下 Ruby 版本受官方支持:
-
Ruby 1.8.6
-
- 不推荐在1.8.6上安装Sinatra, 但是直到Sinatra - 1.3.0发布才会放弃对它的支持。 RDoc 和 - CoffeScript模板不被这个Ruby版本支持。 - 1.8.6在它的Hash实现中包含一个内存泄漏问题, - 该问题会被1.1.1版本之前的Sinatra引发。 - 当前版本使用性能下降的代价排除了这个问题。你需要把Rack降级到1.1.x, - 因为Rack \>= 1.2不再支持1.8.6。 -
+
Ruby 1.8.7
+
+ Sinatra 完全支持 1.8.7,但是,除非必要,我们推荐你升级或者切换到 + JRuby 或 Rubinius。Sinatra 2.0 之前都不会取消对 1.8.7 + 的支持。Ruby 1.8.6 目前已不受支持。 +
-
Ruby 1.8.7
-
- 1.8.7 被完全支持,但是,如果没有特别原因, 我们推荐你升级到 1.9.2 - 或者切换到 JRuby 或者 Rubinius. -
+
Ruby 1.9.2
+
+ Sinatra 完全支持 1.9.2。 + 不要使用 1.9.2p0,它在运行 Sinatra 程序时会产生 segmentation faults 错误。 + 至少在 Sinatra 1.5 发布之前,官方对 1.9.2 的支持仍会继续。 +
-
Ruby 1.9.2
-
- 1.9.2 被支持而且推荐。注意 Radius 和 Markaby 模板并不和1.9兼容。不要使用 - 1.9.2p0, 它被已知会产生 segmentation faults. -
+
Ruby 1.9.3
+
+ Sinatra 完全支持并推荐使用 1.9.3。请注意从更早的版本迁移到 1.9.3 会使所有的会话失效。 + 直到 Sinatra 2.0 发布之前,官方仍然会支持 1.9.3。 +
-
Rubinius
-
- Rubinius 被官方支持 (Rubinius \>= 1.2.2), 除了Textile模板。 -
+
Ruby 2.x
+
+ Sinatra 完全支持并推荐使用 2.x。目前尚无停止支持 2.x 的计划。 +
-
JRuby
-
- JRuby 被官方支持 (JRuby \>= 1.5.6)。 目前未知和第三方模板库有关的问题, - 但是,如果你选择了JRuby,请查看一下JRuby rack 处理器, 因为 Thin web - 服务器还没有在JRuby上获得支持。 -
+
Rubinius
+
+ Sinatra 官方支持 Rubinius (Rubinius >= 2.x)。推荐 gem install puma。 +
+ +
JRuby
+
+ Sinatra 官方支持 JRuby 的最新稳定版本,但不推荐在 JRuby 上使用 C 扩展。 + 推荐 gem install trinidad。 +
-我们也会时刻关注新的Ruby版本。 +我们也在时刻关注新的 Ruby 版本。 -下面的 Ruby 实现没有被官方支持, 但是已知可以运行 Sinatra: +以下 Ruby 实现不受 Sinatra 官方支持,但可以运行 Sinatra: -- JRuby 和 Rubinius 老版本 +* 老版本 JRuby 和 Rubinius +* Ruby 企业版 +* MacRuby、Maglev、IronRuby +* Ruby 1.9.0 和 1.9.1 (不推荐使用) -- MacRuby +不受官方支持的意思是,如果仅在不受支持的 Ruby 实现上发生错误,我们认为不是我们的问题,而是该实现的问题。 -- Maglev +我们同时也针对 ruby-head (MRI 的未来版本)运行 CI,但由于 ruby-head 一直处在变化之中, +我们不能作任何保证。我们期望完全支持未来的 2.x 版本。 -- IronRuby +Sinatra 应该会运行在任何支持上述 Ruby 实现的操作系统上。 -- Ruby 1.9.0 and 1.9.1 +如果你使用 MacRuby,你应该 `gem install control_tower`。 -不被官方支持的意思是,如果在不被支持的平台上有运行错误, -我们假定不是我们的问题,而是平台的问题。 +Sinatra 目前不支持 Cardinal、SmallRuby、BlueRuby 或其它 1.8.7 之前的 Ruby 版本。 -Sinatra应该会运行在任何支持上述Ruby实现的操作系统。 +## 紧跟前沿 -## 紧追前沿 +如果你想使用 Sinatra 的最新代码,请放心使用 master 分支来运行你的程序,它是相当稳定的。 -如果你喜欢使用 Sinatra 的最新鲜的代码,请放心的使用 master -分支来运行你的程序,它会非常的稳定。 +我们也会不定期推出 prerelease gems,所以你也可以运行 - cd myapp - git clone git://github.com/sinatra/sinatra.git - ruby -Isinatra/lib myapp.rb - -我们也会不定期的发布预发布gems,所以你也可以运行 - - gem install sinatra --pre +```shell +gem install sinatra --pre +``` 来获得最新的特性。 -### 通过Bundler +### 通过 Bundler 使用 Sinatra -如果你想使用最新的Sinatra运行你的应用,通过 -[Bundler](http://gembundler.com/) 是推荐的方式。 +如果你想在应用中使用最新的 Sinatra,推荐使用 [Bundler](http://bundler.io)。 -首先,安装bundler,如果你还没有安装: +首先,安装 Bundler,如果你还没有安装的话: - gem install bundler +```shell +gem install bundler +``` -然后,在你的项目目录下,创建一个 `Gemfile`: +然后,在你的项目目录下创建一个 `Gemfile`: -~~~~ruby -source :rubygems -gem 'sinatra', :git => "git://github.com/sinatra/sinatra.git" +```ruby +source 'https://rubygems.org' +gem 'sinatra', :github => "sinatra/sinatra" -# 其他的依赖关系 -gem 'haml' # 举例,如果你想用haml +# 其它依赖 +gem 'haml' # 假如你使用 haml gem 'activerecord', '~> 3.0' # 也许你还需要 ActiveRecord 3.x -~~~~ +``` -请注意在这里你需要列出你的应用的所有依赖关系。 Sinatra的直接依赖关系 -(Rack and Tilt) 将会, 自动被Bundler获取和添加。 +请注意你必须在 `Gemfile` 中列出应用的所有依赖项。 +然而, Sinatra 的直接依赖项 (Rack 和 Tilt) 则会被 Bundler 自动获取和添加。 -现在你可以像这样运行你的应用: +现在你可以这样运行你的应用: - bundle exec ruby myapp.rb +```shell +bundle exec ruby myapp.rb +``` -### 使用自己的 +### 使用自己本地的 Sinatra -创建一个本地克隆并通过 `sinatra/lib` 目录运行你的应用, 通过 -`$LOAD_PATH`: +创建一个本地克隆,并通过 `$LOAD_PATH` 里的 `sinatra/lib` 目录运行你的应用: - cd myapp - git clone git://github.com/sinatra/sinatra.git - ruby -Isinatra/lib myapp.rb +```shell +cd myapp +git clone git://github.com/sinatra/sinatra.git +ruby -I sinatra/lib myapp.rb +``` -为了在未来更新 Sinatra 源代码: +为了在未来更新 Sinatra 源代码: - cd myapp/sinatra - git pull +```shell +cd myapp/sinatra +git pull +``` ### 全局安装 -你可以自行编译 gem : +你可以自行编译 Sinatra gem: - git clone git://github.com/sinatra/sinatra.git - cd sinatra - rake sinatra.gemspec - rake install +```shell +git clone git://github.com/sinatra/sinatra.git +cd sinatra +rake sinatra.gemspec +rake install +``` -如果你以root身份安装 gems,最后一步应该是 +如果你以 root 身份安装 gems,最后一步应该是: - sudo rake install +```shell +sudo rake install +``` -## 更多 +## 版本 -- [项目主页(英文)](http://www.sinatrarb.com/) - 更多的文档, - 新闻,和其他资源的链接。 +Sinatra 遵循[语义化版本](http://semver.org),无论是 SemVer 还是 SemVerTag。 -- [贡献](http://www.sinatrarb.com/contributing) - 找到了一个bug? - 需要帮助?有了一个 patch? +## 更多资料 -- [问题追踪](http://github.com/sinatra/sinatra/issues) - -- [Twitter](http://twitter.com/sinatra) - -- [邮件列表](http://groups.google.com/group/sinatrarb/topics) - -- [IRC: \#sinatra](irc://chat.freenode.net/#sinatra) on - [freenode.net](http://freenode.net) - -- [Sinatra宝典](https://github.com/sinatra/sinatra-book/) Cookbook教程 - -- [Sinatra使用技巧](http://recipes.sinatrarb.com/) 网友贡献的实用技巧 - -- [最新版本](http://rubydoc.info/gems/sinatra)API文档;[http://rubydoc.info](http://rubydoc.info)的[当前HEAD](http://rubydoc.info/github/sinatra/sinatra) - -- [CI服务器](http://travis-ci.org/sinatra/sinatra) +* [项目官网](http://www.sinatrarb.com/) - 更多文档、新闻和其它资源的链接。 +* [贡献](http://www.sinatrarb.com/contributing) - 找到一个 bug?需要帮助?有了一个 patch? +* [问题追踪](https://github.com/sinatra/sinatra/issues) +* [Twitter](https://twitter.com/sinatra) +* [邮件列表](http://groups.google.com/group/sinatrarb/topics) +* IRC: [#sinatra](irc://chat.freenode.net/#sinatra) on http://freenode.net +* [Sinatra & Friends](https://sinatrarb.slack.com) on Slack,点击 +[这里](https://sinatra-slack.herokuapp.com/) 获得邀请。 +* [Sinatra Book](https://github.com/sinatra/sinatra-book/) Cookbook 教程 +* [Sinatra Recipes](http://recipes.sinatrarb.com/) 社区贡献的实用技巧 +* http://www.rubydoc.info/ 上[最新版本](http://www.rubydoc.info//gems/sinatra)或[当前 HEAD](http://www.rubydoc.info/github/sinatra/sinatra) 的 API 文档 +* [CI 服务器](https://travis-ci.org/sinatra/sinatra) diff --git a/lib/sinatra/base.rb b/lib/sinatra/base.rb index 575c376e..a0bdfaad 100644 --- a/lib/sinatra/base.rb +++ b/lib/sinatra/base.rb @@ -2,7 +2,6 @@ require 'rack' require 'tilt' require 'rack/protection' -require 'forwardable' # stdlib dependencies require 'thread' @@ -304,10 +303,15 @@ module Sinatra response.headers end - extend Forwardable - def_delegators :request, - :session, # Access the underlying Rack session. - :logger # Access shared logger object. + # Access the underlying Rack session. + def session + request.session + end + + # Access shared logger object. + def logger + request.logger + end # Look up a media type by file extension in Rack's mime registry. def mime_type(type)