
rabl 0.8.6 + fix for CVE-2014-4671
RABL (Ruby API Builder Language) ist ein Rails- und Padrino Ruby-Template-System zum Generieren von JSON, XML, MessagePack, PList und BSON. Wenn ich die ActiveRecord-Methode 'to_json' verwende, wünsche ich mir eine ausdrucksstärkere und leistungsfähigere Lösung zum Erstellen von APIs. Dies gilt insbesondere dann, wenn die JSON-Darstellung komplex ist oder nicht dem exakten Schema entspricht, das in der Datenbank definiert ist.
Insbesondere möchte ich problemlos:
Jeder, der die in ActiveRecord verwendete 'to_json'-Methode zum Erstellen einer JSON-Antwort ausprobiert hat, hat den Schmerz dieses restriktiven Ansatzes gespürt. RABL ist ein allgemeines Template-System, das entwickelt wurde, um diese Probleme zu lösen, indem es die API-Antworterzeugung auf völlig neue Weise angeht.
RABL dreht sich im Kern darum, MVC-Prinzipien einzuhalten, indem die API-Datendarstellung an die View-Schicht Ihrer Anwendung delegiert wird. Eine Aufschlüsselung häufiger Missverständnisse über RABL finden Sie in unserem Leitfaden zum Verständnis von RABL, der helfen kann, etwaige Verwirrung über dieses Projekt zu beseitigen.
v0.8.0 (veröffentlicht am 14. Februar 2013) entfernt die multi_json-Abhängigkeit und verlässt sich auf Oj (oder JSON) als JSON-Parser. Vereinfacht den Code, entfernt eine Abhängigkeit, aber Sie sollten alle Verweise auf MultiJson entfernen.
v0.6.14 (veröffentlicht am 28. Juni 2012) erfordert die Verwendung von render_views mit RSpec, um Templates zu testen. Andernfalls gibt der Controller den Render-Befehl einfach durch, wie es bei ERB-Templates der Fall ist.
Installieren Sie RABL als Gem:``` gem install rabl
oder füge zu deiner Gemfile hinzu:```ruby
# Gemfile
gem 'rabl'
# Also add either `oj` or `yajl-ruby` as the JSON parser
gem 'oj'
und führe bundle install aus, um die Abhängigkeit zu installieren.
Wenn du Rails 2.3.8 (und höher), Rails 3.X oder Padrino verwendest, funktioniert RABL ohne Konfiguration.
Wichtig: Stelle bei Padrino sicher, dass das rabl-gem nach dem padrino-gem in deiner Gemfile aufgeführt ist, da sonst Rabl nicht ordnungsgemäß als Template-Engine registriert wird.
Mit Sinatra oder einem anderen tilt-basierten Framework registriere einfach:```ruby Rabl.register!
und RABL wird initialisiert und ist bereit zur Verwendung. Für die Nutzung mit Sinatra lesen Sie bitte die
[Sinatra Nutzungsanleitung](https://github.com/nesquena/rabl/wiki/Setup-for-Sinatra).
## Übersicht ##
Sie können RABL verwenden, um JSON- und XML-basierte APIs aus einem beliebigen Ruby-Objekt zu generieren.
Mit RABL werden die Daten typischerweise hauptsächlich aus Modellen (ORM-unabhängig) abgeleitet und die Darstellung der API-Ausgabe wird in
einer View-Vorlage unter Verwendung einer einfachen Ruby-DSL beschrieben. Dies ermöglicht es Ihnen, Ihre Daten von dem JSON oder XML zu trennen, das Sie ausgeben möchten.
Sobald Sie RABL installiert haben (oben erläutert), können Sie eine RABL-View-Vorlage erstellen und dann die Vorlage
aus Ihren Sinatra-, Padrino- oder Rails-Anwendungen sehr einfach vom Controller (oder von der Route) aus rendern. Am Beispiel von [Padrino](http://padrinorb.com):
Angenommen, Sie haben ein `Post`-Modell mit Blogbeiträgen, können Sie eine API-Darstellung (sowohl JSON als auch XML) rendern, indem Sie eine Route erstellen:```ruby
# app/app.rb
get "/posts", :provides => [:json, :xml] do
@user = current_user
@posts = Post.order("id DESC")
render "posts/index"
end
Dann können wir die folgende RABL-Vorlage erstellen, um die API-Ausgabe von @posts auszudrücken:```ruby
collection @posts attributes :id, :title, :subject child(:user) { attributes :full_name } node(:read) { |post| post.read_by?(@user) }
Welches würde das folgende JSON oder XML ausgeben, wenn man `http://localhost:3000/posts.json` besucht.```js
[{ "post" :
{
"id" : 5, title: "...", subject: "...",
"user" : { full_name : "..." },
"read" : true
}
}]
Das ist ein grundlegender Überblick, aber es gibt noch viel mehr zu sehen, wie z.B. partials, Vererbung, benutzerdefinierte Knoten usw. Lesen Sie die vollständigen Details zu RABL unten.
RABL ist so konzipiert, dass es wenig bis gar keine Konfiguration benötigt, um zu funktionieren. Dies ist in den meisten Szenarien der Fall, aber abhängig von Ihren Bedürfnissen möchten Sie möglicherweise die folgenden globalen Konfigurationen in Ihrer Anwendung festlegen (dieser Block ist völlig optional):```ruby
require 'rabl' Rabl.configure do |config|
end
Jede Option beschreibt das Verhalten in Bezug auf die Ausgabe von RABL. Wenn `include_json_root` deaktiviert ist, wird der Wurzelknoten für jedes Wurzelobjekt in der Ausgabe entfernt, und `enable_json_callbacks` aktiviert die Unterstützung für 'jsonp'-Callback-Ausgabe, wenn die eingehende Anfrage einen 'callback'-Parameter enthält.
Wenn `include_child_root` auf false gesetzt ist, enthalten untergeordnete Objekte in der Antwort standardmäßig keinen Wurzelknoten. Dies ermöglicht Ihnen, die gewünschte Antwortstruktur weiter zu verfeinern.
Wenn `cache_engine` gesetzt ist, sollten Sie es einer Klasse mit einer `fetch`-Methode zuweisen. Siehe die [Standard-Engine](https://github.com/nesquena/rabl/blob/master/lib/rabl/cache_engine.rb) für ein Beispiel.
Wenn `perform_caching` auf `true` gesetzt ist, wird Caching durchgeführt. Sie können diese Option ignorieren, wenn Sie Rails verwenden, sie entspricht dem Rails-`config.action_controller.perform_caching`
Wenn `cache_sources` auf `true` gesetzt ist, werden Template-Lookups zur Leistungssteigerung gecacht. Der Cache kann manuell zurückgesetzt werden, indem Sie `Rabl.reset_source_cache!` in Ihrer Anwendung ausführen.
Wenn `cache_all_output` auf `true` gesetzt ist, wird jedes Template, einschließlich jedes einzelnen Templates, das als Teil einer Sammlung verwendet wird, separat gecacht. Zusätzlich wird alles innerhalb von child, glue und partial ebenfalls separat gecacht. Um nur ein einzelnes Template zu cachen, siehe den Abschnitt 'Caching' weiter unten.
Wenn `escape_all_output` auf `true` gesetzt ist und ActiveSupport verfügbar ist, wird die Attributausgabe mit [ERB::Util.html_escape](http://corelib.rubyonrails.org/classes/ERB/Util.html) maskiert. Benutzerdefinierte Knoten werden nicht maskiert, verwenden Sie `ERB::Util.h(value)`.
Wenn `view_paths` auf einen Pfad gesetzt ist, wird dieser Ansichtspfad für jedes Rabl-Template in Ihrer Anwendung überprüft. Fügen Sie diesen Pfad hinzu, insbesondere wenn Sie Rabl in eine Engine einbinden und Ansichtspfade innerhalb einer anderen Rails-App verwenden.
Wenn `raise_on_missing_attribute` auf `true` gesetzt ist, wird ein RuntimeError ausgelöst, sobald Rabl versucht, ein Attribut zu rendern, das nicht existiert. Andernfalls wird das Attribut einfach weggelassen. Das Setzen auf true während der Entwicklung kann die Robustheit Ihres Codes erhöhen, aber die Verwendung von `true` im Produktionscode wird nicht empfohlen.
Wenn `replace_nil_values_with_empty_strings` auf `true` gesetzt ist, werden alle Werte, die `nil` sind und normalerweise als `null` in der Antwort angezeigt würden, in leere Zeichenfolgen umgewandelt.
Wenn Sie [oj](https://github.com/ohler55/oj) als primäre JSON-Kodierungs-Engine verwenden möchten, fügen Sie es einfach Ihrer Gemfile hinzu:```ruby
# Gemfile
gem 'oj'
und RABL wird diese Engine automatisch zum Kodieren Ihrer JSON-Antworten verwenden.
Legen Sie Ihre eigene benutzerdefinierte json_engine fest, die eine dump- oder encode-Methode definiert, um JSON aus Ruby-Daten zu konvertieren:```ruby
config.json_engine = ActiveSupport::JSON
### Formatkonfiguration ###
RABL unterstützt die Konfiguration für MessagePack, BSON und Plist. Weitere Informationen finden Sie auf der Seite [Format-Konfiguration](https://github.com/nesquena/rabl/wiki/Configuring-Formats).
## Verwendung ##
### Objektzuweisung ###
Um das Datenobjekt für die Verwendung in der Vorlage zu deklarieren:```ruby
# app/views/users/show.json.rabl
object @user
oder geben Sie einen Alias für das Objekt an:```ruby object @user => :person
oder eine Sammlung von Objekten übergeben:```ruby
collection @users
# => [ { "user" : { ... } } ]
oder geben Sie ein Wurzelknoten-Label für die Sammlung an:```ruby collection @users => :people
oder sogar sowohl die Kind- als auch die Stamm-Labels für eine Sammlung angeben:```ruby
collection @users, :root => "people", :object_root => "user"
# => { "people" : [ { "user" : { ... } } ] }
und dies wird als Standarddaten für die Darstellung verwendet, oder deaktivieren Sie explizit das object root:```ruby collection @users, :root => "people", :object_root => false
Es kann auch seltsame Fälle geben, bei denen die oberste Ebene der Antwort nicht direkt auf ein Objekt abgebildet wird:```ruby
object false
node(:some_count) { |m| @user.posts.count }
child(@user) { attribute :name }
In diesen Fällen kann das Objekt auf 'false' gesetzt werden und die Knoten können frei konstruiert werden.
Grundlegende Verwendung des Templaters, um ein paar einfache Attribute für die Antwort zu definieren:```ruby
attributes :id, :foo, :bar
oder mit Alias-Attributen verwenden:```ruby
# Take the value of model attribute `foo` and name the node `bar`
attribute :foo => :bar
# => { bar : 5 }
oder sogar mehrere Alias-Attribute:```ruby attributes :bar => :baz, :dog => :animal
oder Attribute nur anzeigen, wenn eine Bedingung wahr ist:```ruby
# m is the object being rendered, also supports :unless
attributes :foo, :bar, :if => lambda { |m| m.condition? }
Benannte und mit Alias versehene Attribute können nicht in derselben Zeile kombiniert werden. Dies funktioniert derzeit nicht:```ruby attributes :foo, :bar => :baz # throws exception
### Untergeordnete Knoten ###
Oft erfordert eine Antwort das Einbeziehen von verschachtelten Informationen aus Daten, die mit dem übergeordneten Modell verknüpft sind:```ruby
child :address do
attributes :street, :city, :zip, :state
end
Sie können auch object root für child node deaktivieren:```ruby child :posts, :object_root => false do attributes :id, :title end
Sie können auch untergeordnete Knoten aus einer beliebigen Datenquelle hinzufügen:```ruby
child @posts => :foobar do
attributes :id, :title
end
oder verwenden Sie Modellassoziationen mit einem Alias:```ruby
child :posts => :foobar do attributes :id, :title end
Sie können auch das aktuelle Objekt übergeben:```ruby
object @user
child :posts do |user|
attribute :title unless user.suspended?
end
Sie können auch untergeordnete Attribute wieder an den Stammknoten anhängen:```ruby
glue @post do attributes :id => :post_id, :name => :post_name end
Verwenden Sie glue, um dem übergeordneten Objekt zusätzliche Attribute hinzuzufügen.
Sie können auch das aktuelle Objekt übergeben:```ruby
object @user
glue(@post) {|user| attribute :title if user.active? }
Dies erzeugt eine JSON-Antwort basierend auf dem Ergebnis des node-Blocks:```ruby
node :full_name do |u| u.first_name + " " + u.last_name end
oder ein benutzerdefinierter Knoten, der nur existiert, wenn eine Bedingung wahr ist:```ruby
# m is the object being rendered, also supports :unless
node(:foo, :if => lambda { |m| m.has_foo? }) do |m|
m.foo
end
oder geben Sie keinen Namen an und lassen Sie den Knotenblock in die Antwort einfließen:```ruby node do |u| { :full_name => u.first_name + " " + u.last_name }
end
Sie können benutzerdefinierte Knoten wie diese verwenden, um flexible Darstellungen eines Werts zu erstellen, die alle Daten des Modells nutzen.
### Partials ###
Oft müssen Sie auf andere Datenobjekte zugreifen, um benutzerdefinierte Knoten in komplexeren Assoziationen zu erstellen. Sie können auf die RABL-Darstellung eines anderen Datenobjekts zugreifen, indem Sie ein RABL-Partial rendern:```ruby
node :location do
{ :city => @city, :address => partial("users/address", :object => @address) }
end
oder sogar auf ein Objekt zugreifen, das mit dem übergeordneten Modell verknüpft ist:```ruby node :location do |m| { :city => m.city, :address => partial("users/address", :object => m.address) } end
Sie können diese Methode verwenden, um beliebig komplexe Nodes für Ihre APIs zu erstellen. Beachten Sie, dass Sie RABL-Vorlagen für jedes Objekt definieren müssen, für das Sie auf diese Weise Repräsentationen erstellen möchten.
### Vererbung ###
Ein weiteres häufiges Problem vieler Vorlagen-Builder ist unnötige Coderedundanz. Typischerweise teilen sich viele Repräsentationen eines Objekts über mehrere Endpoints hinweg gemeinsame Attribute oder Nodes. Die Nodes für ein 'post'-Objekt sind in den meisten Referenzen über die verschiedenen Endpoints wahrscheinlich gleich oder ähnlich.
RABL kann andere "Basis"-RABL-Vorlagen sowie zusätzliche Attribute erweitern:```ruby
# app/views/users/advanced.json.rabl
extends "users/base" # another RABL template in "app/views/users/base.json.rabl"
node :can_drink do |m|
m.age > 21
end
Sie können auch andere rabl-Vorlagen erweitern, während Sie untergeordnete Knoten erstellen, um Duplikationen zu reduzieren:```ruby
child @address do extends "address/item" end
Die Verwendung von Partials und Vererbung kann die Code-Duplizierung in Ihren Templates erheblich reduzieren.
Weitere Beispiele finden Sie auf der [Wiki-Seite zur Wiederverwendung von Templates](https://github.com/nesquena/rabl/wiki/Reusing-templates).
### Lokale Variablen in Partials übergeben ###
Sie können einen beliebigen Satz lokaler Variablen übergeben, wenn Sie Partials rendern oder Templates erweitern.
Wenn wir beispielsweise auf `posts/:id.json` alle Informationen zu einem bestimmten Beitrag und den zugehörigen Kommentaren anzeigen möchten,
in anderen Fällen diese Kommentare jedoch ausblenden möchten, können wir lokale Variablen verwenden:```ruby
# app/views/posts/index.json.rabl
collection @posts
extends('posts/show', :locals => { :hide_comments => true })
# or using partial instead of extends
# node(false) { |post| partial('posts/show', :object => :post, :locals => { :hide_comments => true })}
und dann auf lokale Variablen in der Untervorlage zugreifen:```ruby
object @post
attributes :id, :title, :body, :created_at node(:comments) { |post| post.comments } unless locals[:hide_comments]
Dies kann als fortgeschrittenes Werkzeug nützlich sein, wenn man Partials erweitert oder rendert.
### Gültigkeitsbereich der Vorlage ###
In RABL haben Sie Zugriff auf alles, was Sie zum Erstellen einer API-Antwort benötigen. Jede RABL-Vorlage hat vollen Zugriff auf die Instanzvariablen des Controllers sowie auf alle View-Helfer und Routing-URLs.```ruby
# app/some/template.rabl
object @post
# Access instance variables
child(@user => :user) { ... }
# or Rails helpers
node(:formatted_body) { |post| simple_format(post.body) }
Es sollte kein Problem sein, die entsprechenden Daten abzurufen, um eine Antwort zu erstellen.
Bei APIs kann es oft erforderlich sein, Knoten der 2. oder 3. Ebene zu konstruieren. Nehmen wir an, wir haben ein 'quiz'-Modell mit vielen 'questions' und jede Frage hat viele 'answers'. Diese Hierarchie können wir in RABL recht einfach darstellen:```ruby
object @quiz attribute :title child :questions do attribute :caption child :answers do # Use inheritance to reduce duplication extends "answers/item" end end
Dies zeigt das Quiz-Objekt mit verschachtelten Fragen und Antworten, wie man es von einem Quiz-Knoten erwarten würde, sowie eingebettete Fragen und Antworten.
Beachten Sie, dass RABL beliebig tief in untergeordneten Knoten verschachtelt werden kann, um diese Darstellungen zu definieren.
### Caching ###
RABL verfügt über integrierte Caching-Unterstützung für Vorlagen, die Fragment-Caching-Strategien nutzen. Beachten Sie, dass Caching derzeit **nur für Rails verfügbar** ist, aber die Unterstützung für andere Frameworks ist für eine zukünftige Version geplant. Die einfachste Verwendung von Caching ist:```ruby
# app/views/users/show.json.rabl
object @quiz
cache @quiz # key = rabl/quiz/[cache_key]
attribute :title
Caching kann die Darstellung von RABL-Vorlagen in der Produktion erheblich beschleunigen und wird nach Möglichkeit dringend empfohlen. Für eine detailliertere Betrachtung des Cachings schauen Sie sich den Caching Leitfaden im Wiki an.
Es gibt Situationen, in denen eine Anwendung RABL-Vorlagen außerhalb eines traditionellen Ansichtskontexts rendern muss. Zum Beispiel um RABL innerhalb einer Rake-Aufgabe zu rendern oder um Nachrichtenwarteschlangen-Payloads zu erstellen. In diesem Fall kann Rabl.render wie unten gezeigt verwendet werden:```ruby
Rabl.render(object, template, :view_path => 'app/views', :format => :json) #=> "{...json...}"
Sie können die Komfortmethoden von `Rabl::Renderer` verwenden, um die Objekte ebenfalls zu rendern:```ruby
Rabl::Renderer.json(@post, 'posts/show')
Rabl::Renderer.xml(@post, 'posts/show')
Diese Methoden ermöglichen es, RABL für beliebige Konvertierungen eines Objekts in ein gewünschtes Format zu verwenden.```ruby Rabl::Renderer.new('posts/show', @post, :view_path => 'app/views', :format => 'hash').render
Sie können auch andere Instanzvariablen übergeben, die in Ihrer Vorlage verwendet werden sollen als:```ruby
Rabl::Renderer.new('posts/show', @post, :locals => { :custom_title => "Hello world!" })
Dann können Sie in Ihrer Vorlage @custom_title wie folgt verwenden:```
attribute :content
node(:title) { @custom_title }
### Content Type Headers ###
Derzeit wird in RABL der Content-Type Ihrer Antwort nicht automatisch gesetzt. Dies liegt daran, dass RABL für jedes Rack-basierte Framework entwickelt wurde und so formatagnostisch wie möglich sein soll.
Weitere Informationen finden Sie in [diesem Issue](https://github.com/nesquena/rabl/issues/185#issuecomment-4501232). Wenn Sie Ideen oder Patches haben, lassen Sie es mich bitte wissen.
Setzen Sie in der Zwischenzeit unbedingt die korrekten Content-Types, falls erforderlich. Dies ist sowohl in Rails als auch in Padrino normalerweise recht einfach. Ich empfehle einen `before_filter` in diesem Controller oder eine direkte Angabe in einer Action.
## Ressourcen ##
Es gibt viele Ressourcen zu RABL, darunter das [RABL-Wiki](https://github.com/nesquena/rabl/wiki) sowie zahlreiche unten aufgeführte Tutorials und Anleitungen.
Sie können auch die [RABL-Website](http://nesquena.github.com/rabl) besuchen.
### Fortgeschrittene Nutzung ###
Links zu Ressourcen für die fortgeschrittene Nutzung:
* [Komplexitätsmanagement](https://github.com/nesquena/rabl/wiki/Managing-complexity-with-presenters)
* [Produktionsoptimierungen](https://github.com/nesquena/rabl/wiki/Rabl-In-Production)
* [Grape-Integration](https://github.com/nesquena/rabl/wiki/Using-Rabl-with-Grape)
* [JSON-Rendering für eine Baumstruktur mit RABL](https://github.com/nesquena/rabl/issues/70)
* [Layouts (erb, haml und rabl) in RABL](https://github.com/nesquena/rabl/wiki/Using-Layouts)
* [Backbone- oder Ember.js-Integration](https://github.com/nesquena/rabl/wiki/Backbone-Integration)
* [RABL mit Rails-Engines](https://github.com/nesquena/rabl/wiki/Setup-rabl-with-rails-engines)
Bitte fügen Sie Ihre eigenen Anwendungsfälle hinzu und lassen Sie es mich wissen, damit wir sie hier aufnehmen können! Schauen Sie sich auch das [RABL-Wiki](https://github.com/nesquena/rabl/wiki) für weitere Anwendungsfälle an.
### Tutorials ###
Tutorials können beim Einstieg immer hilfreich sein:
* [Railscasts #322](http://railscasts.com/episodes/322-rabl) – Ryan Bates erklärt RABL
* [BackboneRails](http://www.backbonerails.com/) – Hervorragende Screencasts von Brian Mann
* [Creating an API with RABL and Padrino](http://blog.crowdint.com/2012/10/22/rabl-with-padrino.html)
* http://blog.joshsoftware.com/2011/12/23/designing-rails-api-using-rabl-and-devise/
* http://engineering.gomiso.com/2011/06/27/building-a-platform-api-on-rails/
* http://blog.lawrencenorton.com/better-json-requests-with-rabl
* http://www.rodrigoalvesvieira.com/developing-json-api-rails-rabl/
* http://tech.favoritemedium.com/2011/06/using-rabl-in-rails-json-web-api.html
* http://seesparkbox.com/foundry/better_rails_apis_with_rabl
* http://blog.dcxn.com/2011/06/22/rails-json-templates-through-rabl
* http://teohm.github.com/blog/2011/05/31/using-rabl-in-rails-json-web-api
Lassen Sie mich wissen, falls es noch andere nützliche Ressourcen gibt, die hier nicht aufgeführt sind.
### Verwandte Bibliotheken ###
Es gibt andere Bibliotheken, die die Funktionalität von RABL ergänzen oder erweitern können:
* [versioncake](https://github.com/bwillis/versioncake) – Hervorragende Bibliothek zur einfachen Versionierung Ihrer RABL-APIs
* [gon](https://github.com/gazay/gon) – Stellt Ihre Rails-Variablen in JS mit integrierter RABL-Unterstützung bereit.
* [rabl-rails](https://github.com/ccocchi/rabl-rails) – Neuimplementierung für RABL und Rails, [fokussiert auf Geschwindigkeit](https://github.com/ccocchi/rabl-benchmark/blob/master/BENCHMARK).
Lassen Sie mich wissen, falls es noch andere verwandte Bibliotheken gibt, die hier nicht aufgeführt sind.
### Fehlerbehebung ###
* [Redundante Aufrufe für eine Sammlung](https://github.com/nesquena/rabl/issues/142#issuecomment-2969107)
* [Testen von RABL-Views](https://github.com/nesquena/rabl/issues/130#issuecomment-4179285)
### Beispiele ###
Siehe das [Beispiele](https://github.com/nesquena/rabl/tree/master/examples)-Verzeichnis.
## Issues ##
Schauen Sie sich den Reiter [Issues](https://github.com/nesquena/rabl/issues) für eine vollständige Liste an:
* Strenge Benchmarks und Leistungsoptimierungen
## Autoren und Mitwirkende ##
Danke an [Miso](http://gomiso.com), dass ich dies für unsere Anwendungen erstellen und dieses Projekt veröffentlichen durfte!
* [Nathan Esquenazi](https://github.com/nesquena) – Ersteller des Projekts
* [Arthur Chiu](https://github.com/achiu) – Hauptbetreuer, Riot-Testing-Guru
* [Tim Lee](https://github.com/timothy1ee) – RABL war ein großartiger Name, ausgewählt vom Miso-CTO.
* [David Sommers](https://github.com/databyte) – Template-Auflösung, Caching-Unterstützung und vieles mehr
* [Rick Thomas](https://github.com/rickthomasjr) – Optionen für „extends“ und Sinatra-Tests hinzugefügt
* [Benjamin Yu](https://github.com/byu) – msgpack-Format-Unterstützung hinzugefügt
* [Chris Kimpton](https://github.com/kimptoc) – Hilfe bei Dokumentation und Wiki
* [Marjun](https://github.com/mpagalan) – XML-Optionen-Konfigurationen hinzugefügt
* [Anton Orel](https://github.com/skyeagle) – Rails 3.1-Kompatibilität hinzugefügt
* [Sasha Koss](https://github.com/kossnocorp) – multi_json-Unterstützung hinzugefügt
* [Matthew Schulkind](https://github.com/mschulkind) – Bereinigung von Konfiguration und Tests
* [Luke van der Hoeven](https://github.com/plukevdh) – Unterstützung für Nicht-ORM-Objekte in Templates
* [Andrey Voronkov](https://github.com/Antiarchitect) – BSON-Format-Unterstützung hinzugefügt
* [Alli Witheford](https://github.com/alzeih) – Plist-Format-Unterstützung hinzugefügt
* [Ryan Bigg](https://github.com/radar) – Verbesserter Template-Auflösungscode
* [Ivan Vanderbyl](https://github.com/ivanvanderbyl) – Allgemeiner Renderer hinzugefügt
* [Cyril Mougel](https://github.com/shingara) – Pluggablen cache_engine und Renderer-Anpassungen hinzugefügt
* [Teng Siong Ong](https://github.com/siong1987) – Verbessertes Renderer-Interface
* [Brad Dunbar](https://github.com/braddunbar) – Übergabe des aktuellen Objekts an Blöcke
und viele weitere Mitwirkende, die im [CHANGELOG](https://github.com/nesquena/rabl/blob/master/CHANGELOG.md) aufgeführt sind.
Möchten Sie zur Unterstützung eines weiteren Formats beitragen?
Schauen Sie sich die Patches zur [msgpack-Unterstützung](https://github.com/nesquena/rabl/pull/69), [plist-Unterstützung](https://github.com/nesquena/rabl/pull/153) und [BSON-Unterstützung](https://github.com/nesquena/rabl/pull/163) als Referenz an.
Bitte forken und mitwirken – jede Hilfe, dieses Projekt zu verbessern, ist willkommen!
Dieses Projekt ist ein Mitglied des [OSS Manifesto](http://ossmanifesto.org).
## Inspirationen ##
Es gibt einige hervorragende Bibliotheken, die RABL inspiriert haben, und sie sind unten aufgeführt:
* [Tequila](https://github.com/inem/tequila)
* [JSON Builder](https://github.com/dewski/json_builder)
* [Argonaut](https://github.com/jbr/argonaut)
Nochmals vielen Dank für all diese großartigen Projekte.
## Urheberrecht ##
Copyright © 2011–2012 Nathan Esquenazi. Siehe [MIT-LIZENZ](https://github.com/nesquena/rabl/blob/master/MIT-LICENSE) für Details.