Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Passing locals when rendering templates via partials or inheritance #422

Merged
merged 1 commit into from

4 participants

@simsalabim

Passing locals when rendering templates via partials or inheritance

Here's a copy-paste from README update below, hope this explains what I wanted to be implemented. And also I'm hoping you'll give this feature a try :)

You may pass arbitrary set of locals when reusing your templates via partials or extending.
For example, we want to show on posts/:id.json the information regarding particular post with its comments.
But collection output of posts.json shouldn't contain any info about posts comments, and at the same time we want to
reuse a app/views/posts/show.json.rabl template here, as it seems to be logical.

Now we can use locals to do so as follows:

# app/views/posts/index.json.rabl
collection @posts

extends('posts/show', :locals => {:hide_comments => true})
# or using partial instead of extend
# node(false) { |post| partial('posts/show', :object => :post, :locals => {:hide_comments => true})}
# app/views/posts/show.json.rabl
object @post

attributes :id, :title, :body, :created_at
node(:comments) { |post| post.comments } unless locals[:hide_comments]
@eduludi

+1

@nesquena
Owner

Looks great thanks!

@nesquena nesquena merged commit e62d2c2 into nesquena:master

1 check passed

Details default The Travis build passed
@nesquena
Owner

Available in Rabl 0.8.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
25 README.md
@@ -422,6 +422,31 @@ Using partials and inheritance can significantly reduce code duplication in your
You can see more examples on the [Reusing Templates wiki page](https://github.com/nesquena/rabl/wiki/Reusing-templates).
+### Passing locals when rendering templates via partials or inheritance ###
+You may pass arbitrary set of locals when reusing your templates via partials or extending.
+For example, we want to show on `posts/:id.json` the information regarding particular post with its comments.
+But collection output of `posts.json` shouldn't contain any info about posts comments, and at the same time we want to
+reuse a `app/views/posts/show.json.rabl` template here, as it seems to be logical.
+
+Now we can use locals to do so as follows:
+
+```ruby
+# app/views/posts/index.json.rabl
+collection @posts
+
+extends('posts/show', :locals => {:hide_comments => true})
+# or using partial instead of extend
+# node(false) { |post| partial('posts/show', :object => :post, :locals => {:hide_comments => true})}
+```
+
+```ruby
+# app/views/posts/show.json.rabl
+object @post
+
+attributes :id, :title, :body, :created_at
+node(:comments) { |post| post.comments } unless locals[:hide_comments]
+```
+
### Template Scope ###
In RABL, you have access to everything you need to build an API response. Each RABL template has full access to the controllers
View
2  fixtures/ashared/views_rails_3/users/index.json.rabl
@@ -1,3 +1,3 @@
collection @users
-extends "users/show"
+extends "users/show", :locals => {:revert => true}
View
6 fixtures/ashared/views_rails_3/users/phone_number.json.rabl
@@ -1,6 +1,8 @@
attributes :prefix, :suffix, :area_code
attributes :is_primary => :primary
-node :formatted do |n|
- n.formatted
+if locals[:revert]
+ node(:reverted) { |n| n.formatted.reverse }
+else
+ node(:formatted) { |n| n.formatted }
end
View
2  fixtures/ashared/views_rails_3/users/show.json.rabl
@@ -12,5 +12,5 @@ child :phone_numbers => :pnumbers do
end
node :node_numbers do |u|
- partial("users/phone_number", :object => u.phone_numbers)
+ partial("users/phone_number", :object => u.phone_numbers, :locals => {:revert => locals[:revert].presence})
end
View
0  fixtures/rails3_2/test/fixtures/.gitkeep
No changes.
View
0  fixtures/rails3_2/test/functional/.gitkeep
No changes.
View
0  fixtures/rails3_2/test/unit/.gitkeep
No changes.
View
1  lib/rabl/engine.rb
@@ -20,6 +20,7 @@ def source=(string)
# Renders the representation based on source, object, scope and locals
# Rabl::Engine.new("...source...", { :format => "xml" }).render(scope, { :foo => "bar", :object => @user })
def render(scope, locals, &block)
+ locals.merge! locals.delete(:locals) || {}
reset_options!
@_locals, @_scope = locals, scope
self.copy_instance_variables_from(@_scope, [:@assigns, :@helpers])
View
2  lib/rabl/partials.rb
@@ -24,7 +24,7 @@ def object_to_hash(object, options={}, &block)
return object if object.nil?
return [] if is_collection?(object) && object.blank? # empty collection
engine_options = options.reverse_merge(:format => "hash", :view_path => @_view_path, :root => (options[:root] || false))
- Rabl::Engine.new(options[:source], engine_options).render(@_scope, :object => object, &block)
+ Rabl::Engine.new(options[:source], engine_options).render(@_scope, :object => object, :locals => options[:locals], &block)
end
# Returns source for a given relative file
View
6 test/integration/rails3_2/users_controller_test.rb
@@ -48,9 +48,9 @@
end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } }
# Node (renders collection partial)
- asserts("contains formatted node numbers") do
- json_output.map { |u| u["user"]["node_numbers"].map { |n| n["formatted"] } }
- end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } }
+ asserts("contains reverted node numbers") do
+ json_output.map { |u| u["user"]["node_numbers"].map { |n| n["reverted"] } }
+ end.equals { @users.map { |u| u.phone_numbers.map(&:formatted).map(&:reverse) } }
end # index
context "for show action" do
Something went wrong with that request. Please try again.