Allow conditionnal blocks within template
This commit is contained in:
parent
cf39a3f748
commit
3999737daf
|
@ -5,6 +5,7 @@ require 'active_support/core_ext/class/attribute_accessors'
|
||||||
|
|
||||||
require 'rabl-rails/version'
|
require 'rabl-rails/version'
|
||||||
require 'rabl-rails/template'
|
require 'rabl-rails/template'
|
||||||
|
require 'rabl-rails/condition'
|
||||||
require 'rabl-rails/compiler'
|
require 'rabl-rails/compiler'
|
||||||
|
|
||||||
require 'rabl-rails/renderer'
|
require 'rabl-rails/renderer'
|
||||||
|
@ -17,10 +18,10 @@ require 'multi_json'
|
||||||
|
|
||||||
module RablRails
|
module RablRails
|
||||||
extend Renderer
|
extend Renderer
|
||||||
|
|
||||||
mattr_accessor :cache_templates
|
mattr_accessor :cache_templates
|
||||||
@@cache_templates = true
|
@@cache_templates = true
|
||||||
|
|
||||||
mattr_accessor :include_json_root
|
mattr_accessor :include_json_root
|
||||||
@@include_json_root = true
|
@@include_json_root = true
|
||||||
|
|
||||||
|
@ -30,18 +31,18 @@ module RablRails
|
||||||
def self.configure
|
def self.configure
|
||||||
yield self
|
yield self
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.json_engine=(name)
|
def self.json_engine=(name)
|
||||||
MultiJson.engine = name
|
MultiJson.engine = name
|
||||||
@@json_engine = name
|
@@json_engine = name
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
Rails.logger.warn %Q(WARNING: rabl-rails could not load "#{self.json_engine}" as JSON engine, fallback to default)
|
Rails.logger.warn %Q(WARNING: rabl-rails could not load "#{self.json_engine}" as JSON engine, fallback to default)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.cache_templates?
|
def self.cache_templates?
|
||||||
ActionController::Base.perform_caching && @@cache_templates
|
ActionController::Base.perform_caching && @@cache_templates
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.load_default_engines!
|
def self.load_default_engines!
|
||||||
self.json_engine = :yajl
|
self.json_engine = :yajl
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,7 +5,7 @@ module RablRails
|
||||||
#
|
#
|
||||||
class Compiler
|
class Compiler
|
||||||
def initialize
|
def initialize
|
||||||
@glue_count = 0
|
@i = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -76,8 +76,8 @@ module RablRails
|
||||||
#
|
#
|
||||||
def glue(data)
|
def glue(data)
|
||||||
return unless block_given?
|
return unless block_given?
|
||||||
name = :"_glue#{@glue_count}"
|
name = :"_glue#{@i}"
|
||||||
@glue_count += 1
|
@i += 1
|
||||||
@template[name] = sub_compile(data) { yield }
|
@template[name] = sub_compile(data) { yield }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -114,6 +114,20 @@ module RablRails
|
||||||
@template.merge!(t.source)
|
@template.merge!(t.source)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Provide a conditionnal block
|
||||||
|
#
|
||||||
|
# condition(->(u) { u.is_a?(Admin) }) do
|
||||||
|
# attributes :secret
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
def condition(proc)
|
||||||
|
return unless block_given?
|
||||||
|
name = :"_if#{@i}"
|
||||||
|
@i += 1
|
||||||
|
@template[name] = Condition.new(proc, sub_compile(nil) { yield })
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -133,12 +147,12 @@ module RablRails
|
||||||
name_or_data
|
name_or_data
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def sub_compile(data)
|
def sub_compile(data)
|
||||||
return {} unless block_given?
|
return {} unless block_given?
|
||||||
old_template, @template = @template, {}
|
old_template, @template = @template, {}
|
||||||
yield
|
yield
|
||||||
@template.merge!(:_data => data)
|
data ? @template.merge!(:_data => data) : @template
|
||||||
ensure
|
ensure
|
||||||
@template = old_template
|
@template = old_template
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
module RablRails
|
||||||
|
class Condition
|
||||||
|
attr_reader :proc, :source
|
||||||
|
|
||||||
|
def initialize(proc, source)
|
||||||
|
@proc = proc
|
||||||
|
@source = source
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -65,6 +65,11 @@ module RablRails
|
||||||
else # child
|
else # child
|
||||||
object.respond_to?(:each) ? render_collection(object, current_value) : render_resource(object, current_value)
|
object.respond_to?(:each) ? render_collection(object, current_value) : render_resource(object, current_value)
|
||||||
end
|
end
|
||||||
|
when Condition
|
||||||
|
if instance_exec data, &(value.proc)
|
||||||
|
output.merge!(render_resource(data, value.source))
|
||||||
|
end
|
||||||
|
next output
|
||||||
end
|
end
|
||||||
output[key] = out
|
output[key] = out
|
||||||
output
|
output
|
||||||
|
|
|
@ -42,7 +42,7 @@ class CompilerTest < ActiveSupport::TestCase
|
||||||
assert_equal :@user, t.data
|
assert_equal :@user, t.data
|
||||||
assert_equal :users, t.root_name
|
assert_equal :users, t.root_name
|
||||||
end
|
end
|
||||||
|
|
||||||
test "root can be set to false via options" do
|
test "root can be set to false via options" do
|
||||||
t = @compiler.compile_source(%( object :@user, root: false))
|
t = @compiler.compile_source(%( object :@user, root: false))
|
||||||
assert_equal false, t.root_name
|
assert_equal false, t.root_name
|
||||||
|
@ -143,6 +143,12 @@ class CompilerTest < ActiveSupport::TestCase
|
||||||
assert_equal 2, t.source[:foo].size
|
assert_equal 2, t.source[:foo].size
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "conditionnal block compile nicely" do
|
||||||
|
t = @compiler.compile_source(%{ condition(->(u) {}) do attributes :secret end })
|
||||||
|
assert_instance_of RablRails::Condition, t.source[:_if0]
|
||||||
|
assert_equal({ :secret => :secret }, t.source[:_if0].source)
|
||||||
|
end
|
||||||
|
|
||||||
test "compile with no object" do
|
test "compile with no object" do
|
||||||
t = @compiler.compile_source(%{
|
t = @compiler.compile_source(%{
|
||||||
object false
|
object false
|
||||||
|
@ -154,7 +160,7 @@ class CompilerTest < ActiveSupport::TestCase
|
||||||
assert_equal({ :user => { :_data => :@user, :id => :id } }, t.source)
|
assert_equal({ :user => { :_data => :@user, :id => :id } }, t.source)
|
||||||
assert_equal false, t.data
|
assert_equal false, t.data
|
||||||
end
|
end
|
||||||
|
|
||||||
test "name extraction from argument" do
|
test "name extraction from argument" do
|
||||||
assert_equal [:@users, 'users'], @compiler.send(:extract_data_and_name, :@users)
|
assert_equal [:@users, 'users'], @compiler.send(:extract_data_and_name, :@users)
|
||||||
assert_equal [:users, :users], @compiler.send(:extract_data_and_name, :users)
|
assert_equal [:users, :users], @compiler.send(:extract_data_and_name, :users)
|
||||||
|
|
|
@ -75,7 +75,7 @@ class TestJsonRenderer < ActiveSupport::TestCase
|
||||||
@template.source = { :name => [condition, proc] }
|
@template.source = { :name => [condition, proc] }
|
||||||
assert_equal %q({}), render_json_output
|
assert_equal %q({}), render_json_output
|
||||||
end
|
end
|
||||||
|
|
||||||
test "node with context method call" do
|
test "node with context method call" do
|
||||||
@context.stub(:respond_to?).with(:context_method).and_return(true)
|
@context.stub(:respond_to?).with(:context_method).and_return(true)
|
||||||
@context.stub(:context_method).and_return('marty')
|
@context.stub(:context_method).and_return('marty')
|
||||||
|
@ -114,17 +114,29 @@ class TestJsonRenderer < ActiveSupport::TestCase
|
||||||
|
|
||||||
assert_equal %q({"users":[]}), render_json_output
|
assert_equal %q({"users":[]}), render_json_output
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "condition blocks are transparent if the condition passed" do
|
||||||
|
c = RablRails::Condition.new(->(u) { true }, { :name => :name })
|
||||||
|
@template.source = { :_if0 => c }
|
||||||
|
assert_equal %q({"name":"foobar"}), render_json_output
|
||||||
|
end
|
||||||
|
|
||||||
|
test "condition blocks are ignored if the condition is not met" do
|
||||||
|
c = RablRails::Condition.new(->(u) { false }, { :name => :name })
|
||||||
|
@template.source = { :_if0 => c }
|
||||||
|
assert_equal %q({}), render_json_output
|
||||||
|
end
|
||||||
|
|
||||||
test "render object with root node" do
|
test "render object with root node" do
|
||||||
@template.root_name = :author
|
@template.root_name = :author
|
||||||
@template.source = { :id => :id, :name => :name }
|
@template.source = { :id => :id, :name => :name }
|
||||||
assert_equal %q({"author":{"id":1,"name":"foobar"}}), render_json_output
|
assert_equal %q({"author":{"id":1,"name":"foobar"}}), render_json_output
|
||||||
end
|
end
|
||||||
|
|
||||||
test "render object with root options set to false" do
|
test "render object with root options set to false" do
|
||||||
RablRails.include_json_root = false
|
RablRails.include_json_root = false
|
||||||
@template.root_name = :author
|
@template.root_name = :author
|
||||||
@template.source = { :id => :id, :name => :name }
|
@template.source = { :id => :id, :name => :name }
|
||||||
assert_equal %q({"id":1,"name":"foobar"}), render_json_output
|
assert_equal %q({"id":1,"name":"foobar"}), render_json_output
|
||||||
end
|
end
|
||||||
end
|
end
|
Loading…
Reference in New Issue