Skip to content

Use Grape formatter syntax instead of monkey-patching. #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 20, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--color
--format=documentation
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ source 'https://rubygems.org'
# Specify your gem's dependencies in grape-rabl.gemspec
gemspec

gem "grape", :git => "git://github.com/intridea/grape.git", :branch => "frontier"
gem "grape", :git => "git://github.com/intridea/grape.git"

group :test do
gem "rspec", "~> 2.8.0"
Expand Down
63 changes: 40 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# Grape::Rabl

Use rabl templates in grape!
Use Rabl templates in [Grape](https://github.com/intridea/grape)!

[![Build Status](https://secure.travis-ci.org/LTe/grape-rabl.png)](http://travis-ci.org/LTe/grape-rabl) [![Dependency Status](https://gemnasium.com/LTe/grape-rabl.png)](https://gemnasium.com/LTe/grape-rabl)


## Installation

Add this line to your application's Gemfile:
Add the `grape` and `grape-rabl` gems to Gemfile. Currently requires HEAD of Grape.

```ruby
gem 'grape', :git => "https://github.com/intridea/grape.git"
gem 'grape-rabl'
gem 'grape', :git => "git://github.com/intridea/grape.git", :branch => "frontier"
```

And then execute:
Expand All @@ -21,6 +21,7 @@ And then execute:
## Usage

### Require grape-rabl

```ruby
# config.ru
require 'grape/rabl'
Expand All @@ -36,27 +37,38 @@ use Rack::Config do |env|
end
```

### Create grape application

To *get post put delete options* add **:rabl** options with template name.
### Tell your API to use Grape::Formatter::Rabl

```ruby
get "/path", :rabl => "template_name" do
# stuff
@var = "hello"
class API < Grape::API
format :json
formatter :json, Grape::Formatter::Rabl
end

post "/path", :rabl => "template_name_diff" do
# stuff
@user = User.find_user("email@example.com")
### Use rabl templates conditionally

Add the template name to the API options.

```ruby
get "/user/:id", :rabl => "user.rabl" do
@user = User.find(params[:id])
end
```

**You can use instance variables in templates!**
You can use instance variables in the Rabl template.

```ruby
object @user => :user
attributes :name, :email

child @project => :project do
attributes :name
end
```

## Template name
## You can omit .rabl

You can use "**view.rabl**" or just "**view**"
The following are identical.

```ruby
get "/home", :rabl => "view"
Expand All @@ -74,14 +86,17 @@ use Rack::Config do |env|
end

class UserAPI < Grape::API
format :json
formatter :json, Grape::Formatter::Rabl

# use rabl with 'hello.rabl' template
get '/user', :rabl => 'hello' do
@user = User.first
get '/user/:id', :rabl => 'user' do
@user = User.find(params[:id])
end

# do not use rabl, normal usage
get '/user2' do
{ :some => :hash }
# do not use rabl, fallback to the defalt Grape JSON formatter
get '/users' do
User.all
end
end
```
Expand All @@ -100,8 +115,10 @@ Create grape application
```ruby
# app/api/user.rb
class MyAPI < Grape::API
get '/user', :rabl => "user" do
@user = User.first
format :json
formatter :json, Grape::Formatter::Rabl
get '/user/:id', :rabl => "user" do
@user = User.find(params[:id])
end
end
```
Expand Down Expand Up @@ -133,7 +150,7 @@ end

## Rspec

Writing Tests part at https://github.com/intridea/grape
See "Writing Tests" in https://github.com/intridea/grape.

Enjoy :)

Expand Down
1 change: 1 addition & 0 deletions lib/grape-rabl.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require "rabl"
require "grape"
require "hashie/hash"
require "grape-rabl/tilt"
require "grape-rabl/version"
require "grape-rabl/formatter"
86 changes: 43 additions & 43 deletions lib/grape-rabl/formatter.rb
Original file line number Diff line number Diff line change
@@ -1,52 +1,52 @@
require 'tilt'
Rabl.register!

module Grape
module Middleware
class Formatter
alias :old_after :after

def after
status, headers, bodies = *@app_response
current_endpoint = env['api.endpoint']

rabl(current_endpoint) do |template|
engine = ::Tilt.new(view_path(template))
rendered = engine.render(current_endpoint, {})
headers['Content-Type'] = content_types[env['api.format']]
Rack::Response.new(rendered, status, headers).to_a
end
end
module Formatter
module Rabl
class << self

private
attr_reader :env
attr_reader :endpoint

def view_path(template)
if template.split(".")[-1] == "rabl"
File.join(env['api.tilt.root'], template)
else
File.join(env['api.tilt.root'], (template + ".rabl"))
end
end
def call(object, env)

def rabl(endpoint)
if template = rablable?(endpoint)
yield template
else
old_after
end
end
@env = env
@endpoint = env['api.endpoint']

if rablable?
rabl do |template|
engine = ::Tilt.new(view_path(template))
engine.render endpoint, {}
end
else
Grape::Formatter::Json.call object, env
end

def rablable?(endpoint)
if template = endpoint.options[:route_options][:rabl]
set_view_root unless env['api.tilt.root']
template
else
false
end
end

def set_view_root
raise "Use Rack::Config to set 'api.tilt.root' in config.ru"

private

def view_path(template)
if template.split(".")[-1] == "rabl"
File.join(env['api.tilt.root'], template)
else
File.join(env['api.tilt.root'], (template + ".rabl"))
end
end

def rablable?
!! endpoint.options[:route_options][:rabl]
end

def rabl
template = endpoint.options[:route_options][:rabl]
raise "missing rabl template" unless template
set_view_root unless env['api.tilt.root']
yield template
end

def set_view_root
raise "Use Rack::Config to set 'api.tilt.root' in config.ru"
end

end
end
end
Expand Down
3 changes: 3 additions & 0 deletions lib/grape-rabl/tilt.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
require 'tilt'

Rabl.register!
15 changes: 12 additions & 3 deletions spec/grape_rabl_spec.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
require 'spec_helper'

describe Grape::Rabl do
subject { Class.new(Grape::API) }
before { subject.default_format :json }
def app; subject end
subject do
Class.new(Grape::API)
end

before do
subject.format :json
subject.formatter :json, Grape::Formatter::Rabl
end

def app
subject
end

it 'should work without rabl template' do
subject.get("/home") {"Hello World"}
Expand Down