rabl 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.md +6 -0
- data/Rakefile +8 -0
- data/lib/rabl.rb +13 -2
- data/lib/rabl/builder.rb +3 -10
- data/lib/rabl/engine.rb +38 -15
- data/lib/rabl/register.rb +20 -0
- data/lib/rabl/template.rb +4 -3
- data/lib/rabl/version.rb +1 -1
- data/rabl.gemspec +3 -0
- data/test.watchr +48 -0
- data/test/builder_test.rb +1 -0
- data/test/engine_test.rb +2 -0
- data/test/template_test.rb +2 -0
- data/test/teststrap.rb +11 -0
- metadata +47 -7
data/README.md
CHANGED
@@ -25,6 +25,12 @@ or add to your Gemfile:
|
|
25
25
|
|
26
26
|
and run `bundle install` to install the dependency.
|
27
27
|
|
28
|
+
If you are using Rails 2.X or Padrino, RABL works out of the box. With Sinatra, or any other tilt-based framework, simply register:
|
29
|
+
|
30
|
+
Rabl.register!
|
31
|
+
|
32
|
+
and RABL will be initialized.
|
33
|
+
|
28
34
|
## Usage ##
|
29
35
|
|
30
36
|
### Object Assignment ###
|
data/Rakefile
CHANGED
data/lib/rabl.rb
CHANGED
@@ -1,8 +1,19 @@
|
|
1
1
|
require 'rabl/version'
|
2
2
|
require 'rabl/engine'
|
3
3
|
require 'rabl/builder'
|
4
|
-
require 'rabl/template' if defined?(Rails)
|
5
4
|
|
5
|
+
# Rabl.register!
|
6
6
|
module Rabl
|
7
|
-
|
7
|
+
def self.register!
|
8
|
+
require 'rabl/template' if defined?(Rails)
|
9
|
+
require 'rabl/register'
|
10
|
+
end
|
8
11
|
end
|
12
|
+
|
13
|
+
# Register
|
14
|
+
if defined?(Padrino)
|
15
|
+
require 'padrino-core'
|
16
|
+
Padrino.after_load { Rabl.register! }
|
17
|
+
else
|
18
|
+
Rabl.register!
|
19
|
+
end
|
data/lib/rabl/builder.rb
CHANGED
@@ -32,7 +32,7 @@ module Rabl
|
|
32
32
|
end if @options.has_key?(:extends)
|
33
33
|
|
34
34
|
@_root_name ||= @_object.class.model_name.element
|
35
|
-
options[:root] ? { @_root_name => @_result } : @_result
|
35
|
+
(@options[:root] || options[:root]) ? { @_root_name => @_result } : @_result
|
36
36
|
end
|
37
37
|
|
38
38
|
# Indicates an attribute or method should be included in the json output
|
@@ -74,18 +74,11 @@ module Rabl
|
|
74
74
|
@_result.merge!(glued_attributes)
|
75
75
|
end
|
76
76
|
|
77
|
-
# Renders a partial hash based on another rabl template
|
78
|
-
# partial("users/show", :object => @user)
|
79
|
-
def partial(file, options={}, &block)
|
80
|
-
source = File.read(Rails.root.join("app/views/" + file + ".json.rabl"))
|
81
|
-
self.object_to_hash(options[:object], source, &block)
|
82
|
-
end
|
83
|
-
|
84
77
|
# Extends an existing rabl template with additional attributes in the block
|
85
78
|
# extends("users/show") { attribute :full_name }
|
86
79
|
def extends(file, options={}, &block)
|
87
80
|
options = options.merge!(:object => @_object)
|
88
|
-
result = partial(file, options, &block)
|
81
|
+
result = @options[:engine].partial(file, options, &block)
|
89
82
|
@_result.merge!(result)
|
90
83
|
end
|
91
84
|
|
@@ -110,7 +103,7 @@ module Rabl
|
|
110
103
|
# data_name(@users) => :user
|
111
104
|
def data_name(data)
|
112
105
|
return data.values.first if data.is_a?(Hash)
|
113
|
-
return data.first.class.model_name.element.pluralize if data.first.
|
106
|
+
return data.first.class.model_name.element.pluralize if data.respond_to?(:first) && data.first.respond_to?(:valid?)
|
114
107
|
data.class.model_name.element
|
115
108
|
end
|
116
109
|
end
|
data/lib/rabl/engine.rb
CHANGED
@@ -1,15 +1,23 @@
|
|
1
1
|
module Rabl
|
2
2
|
class Engine
|
3
3
|
# Constructs a new ejs engine based on given vars, handler and declarations
|
4
|
-
|
5
|
-
|
6
|
-
@
|
7
|
-
@_options =
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
4
|
+
# Rabl::Engine.new("...source...", { :format => "xml" })
|
5
|
+
def initialize(source, options={})
|
6
|
+
@_source = source
|
7
|
+
@_options = options.reverse_merge(:format => "json")
|
8
|
+
end
|
9
|
+
|
10
|
+
# Renders the representation based on source, object, scope and locals
|
11
|
+
# Rabl::Engine.new("...source...", { :format => "xml" }).render(scope, { :foo => "bar", :object => @user })
|
12
|
+
def render(scope, locals, &block)
|
13
|
+
@_locals = locals
|
14
|
+
@_scope = scope
|
15
|
+
@_options = @_options.merge(:scope => @_scope, :locals => @_locals, :engine => self)
|
16
|
+
self.copy_instance_variables_from(@_scope, [:@assigns, :@helpers]);
|
17
|
+
@_object = locals[:object] || self.default_object
|
18
|
+
instance_eval(@_source) if @_source.present?
|
12
19
|
instance_eval(&block) if block_given?
|
20
|
+
self.send("to_" + @_options[:format])
|
13
21
|
end
|
14
22
|
|
15
23
|
# Sets the object to be used as the data source for this template
|
@@ -63,14 +71,14 @@ module Rabl
|
|
63
71
|
# Renders a partial hash based on another rabl template
|
64
72
|
# partial("users/show", :object => @user)
|
65
73
|
def partial(file, options={}, &block)
|
66
|
-
source =
|
74
|
+
source = self.fetch_source(file)
|
67
75
|
self.object_to_hash(options[:object], source, &block)
|
68
76
|
end
|
69
77
|
|
70
78
|
# Returns a hash representation of the data object
|
71
79
|
# to_hash(:root => true)
|
72
80
|
def to_hash(options={})
|
73
|
-
if @_object
|
81
|
+
if is_record?(@_object)
|
74
82
|
Rabl::Builder.new(@_object, @_options).to_hash(options)
|
75
83
|
elsif @_object.respond_to?(:each)
|
76
84
|
@_object.map { |object| Rabl::Builder.new(object, @_options).to_hash(options) }
|
@@ -80,24 +88,39 @@ module Rabl
|
|
80
88
|
# Returns a json representation of the data object
|
81
89
|
# to_json(:root => true)
|
82
90
|
def to_json(options={})
|
83
|
-
options.reverse_merge
|
91
|
+
options = options.reverse_merge(:root => true)
|
84
92
|
to_hash(options).to_json
|
85
93
|
end
|
86
94
|
|
87
95
|
# Returns a hash based representation of any data object given ejs template block
|
88
96
|
# object_to_hash(@user) { attribute :full_name } => { ... }
|
89
97
|
def object_to_hash(object, source=nil, &block)
|
90
|
-
return object unless
|
91
|
-
self.class.new(
|
98
|
+
return object unless is_record?(object) || is_record?(object.respond_to?(:first) && object.first)
|
99
|
+
self.class.new(source, :format => "hash", :root => false).render(@_scope, :object => object, &block)
|
92
100
|
end
|
93
101
|
|
94
102
|
protected
|
95
103
|
|
96
104
|
# Returns a guess at the default object for this template
|
97
105
|
def default_object
|
98
|
-
@
|
99
|
-
instance_variable_get("@#{@
|
106
|
+
@_scope.respond_to?(:controller) ?
|
107
|
+
instance_variable_get("@#{@_scope.controller.controller_name}") :
|
100
108
|
nil
|
101
109
|
end
|
110
|
+
|
111
|
+
# Returns true if item is a ORM record; false otherwise
|
112
|
+
def is_record?(obj)
|
113
|
+
obj && obj.respond_to?(:valid?)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Returns source for a given relative file
|
117
|
+
# fetch_source("show") => "...contents..."
|
118
|
+
def fetch_source(file)
|
119
|
+
root_path = Rails.root if defined?(Rails)
|
120
|
+
root_path = Padrino.root if defined?(Padrino)
|
121
|
+
view_path = File.join(root_path, "app/views/")
|
122
|
+
file_path = Dir[File.join(view_path, file + "*.rabl")].first
|
123
|
+
File.read(file_path) if file_path
|
124
|
+
end
|
102
125
|
end
|
103
126
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
## TILT ##
|
2
|
+
if defined?(Tilt)
|
3
|
+
class RablTemplate < Tilt::Template
|
4
|
+
def initialize_engine
|
5
|
+
return if defined?(::Rabl)
|
6
|
+
require_template_library 'rabl'
|
7
|
+
end
|
8
|
+
|
9
|
+
def prepare
|
10
|
+
options = @options.merge(:format => "json")
|
11
|
+
@engine = ::Rabl::Engine.new(data, options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def evaluate(scope, locals, &block)
|
15
|
+
@engine.render(scope, locals, &block)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
Tilt.register 'rabl', RablTemplate
|
20
|
+
end
|
data/lib/rabl/template.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# Rails Template
|
2
|
+
|
1
3
|
require 'action_view/base'
|
2
4
|
require 'action_view/template'
|
3
5
|
|
@@ -7,9 +9,8 @@ module ActionView
|
|
7
9
|
include Compilable
|
8
10
|
|
9
11
|
def compile(template) %{
|
10
|
-
::Rabl::Engine.new(
|
11
|
-
|
12
|
-
end.to_#{template.format}
|
12
|
+
::Rabl::Engine.new(#{template.source.inspect}, { :format => #{template.format.inspect} }).
|
13
|
+
render(self, assigns.merge(local_assigns))
|
13
14
|
} end
|
14
15
|
end
|
15
16
|
end
|
data/lib/rabl/version.rb
CHANGED
data/rabl.gemspec
CHANGED
@@ -18,4 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_development_dependency 'riot', '~>0.12.3'
|
23
|
+
s.add_development_dependency 'rr', '~>1.0.2'
|
21
24
|
end
|
data/test.watchr
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
ENV["WATCHR"] = "1"
|
2
|
+
system 'clear'
|
3
|
+
|
4
|
+
def run(cmd)
|
5
|
+
puts(cmd)
|
6
|
+
system cmd
|
7
|
+
end
|
8
|
+
|
9
|
+
def run_test_file(file)
|
10
|
+
system('clear')
|
11
|
+
run(%Q(ruby -I"lib:test" -rubygems #{file}))
|
12
|
+
end
|
13
|
+
|
14
|
+
def run_all_tests
|
15
|
+
system('clear')
|
16
|
+
run('rake test')
|
17
|
+
end
|
18
|
+
|
19
|
+
def related_test_files(path)
|
20
|
+
Dir['test/**/*.rb'].select { |file| file =~ /#{File.basename(path).split(".").first}_test.rb/ }
|
21
|
+
end
|
22
|
+
|
23
|
+
watch('test/teststrap\.rb') { run_all_tests }
|
24
|
+
watch('test/(.*).*_test\.rb') { |m| run_test_file(m[0]) }
|
25
|
+
watch('lib/.*/.*\.rb') { |m| related_test_files(m[0]).map {|tf| run_test_file(tf) } }
|
26
|
+
|
27
|
+
# Ctrl-\
|
28
|
+
Signal.trap 'QUIT' do
|
29
|
+
puts " --- Running all tests ---\n\n"
|
30
|
+
run_all_tests
|
31
|
+
end
|
32
|
+
|
33
|
+
@interrupted = false
|
34
|
+
|
35
|
+
# Ctrl-C
|
36
|
+
Signal.trap 'INT' do
|
37
|
+
if @interrupted then
|
38
|
+
@wants_to_quit = true
|
39
|
+
abort("\n")
|
40
|
+
else
|
41
|
+
puts "Interrupt a second time to quit"
|
42
|
+
@interrupted = true
|
43
|
+
Kernel.sleep 1.5
|
44
|
+
# raise Interrupt, nil # let the run loop catch it
|
45
|
+
run_all_tests
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
require File.expand_path('../teststrap',__FILE__)
|
data/test/engine_test.rb
ADDED
data/test/teststrap.rb
ADDED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rabl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 5
|
10
|
+
version: 0.0.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Nathan Esquenazi
|
@@ -16,8 +16,39 @@ bindir: bin
|
|
16
16
|
cert_chain: []
|
17
17
|
|
18
18
|
date: 2011-04-12 00:00:00 Z
|
19
|
-
dependencies:
|
20
|
-
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: riot
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 41
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
- 12
|
32
|
+
- 3
|
33
|
+
version: 0.12.3
|
34
|
+
type: :development
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rr
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 19
|
45
|
+
segments:
|
46
|
+
- 1
|
47
|
+
- 0
|
48
|
+
- 2
|
49
|
+
version: 1.0.2
|
50
|
+
type: :development
|
51
|
+
version_requirements: *id002
|
21
52
|
description: General ruby templating for json or xml
|
22
53
|
email:
|
23
54
|
- nesquena@gmail.com
|
@@ -35,9 +66,15 @@ files:
|
|
35
66
|
- lib/rabl.rb
|
36
67
|
- lib/rabl/builder.rb
|
37
68
|
- lib/rabl/engine.rb
|
69
|
+
- lib/rabl/register.rb
|
38
70
|
- lib/rabl/template.rb
|
39
71
|
- lib/rabl/version.rb
|
40
72
|
- rabl.gemspec
|
73
|
+
- test.watchr
|
74
|
+
- test/builder_test.rb
|
75
|
+
- test/engine_test.rb
|
76
|
+
- test/template_test.rb
|
77
|
+
- test/teststrap.rb
|
41
78
|
homepage: https://github.com/nesquena/rabl
|
42
79
|
licenses: []
|
43
80
|
|
@@ -71,5 +108,8 @@ rubygems_version: 1.7.2
|
|
71
108
|
signing_key:
|
72
109
|
specification_version: 3
|
73
110
|
summary: General ruby templating for json or xml
|
74
|
-
test_files:
|
75
|
-
|
111
|
+
test_files:
|
112
|
+
- test/builder_test.rb
|
113
|
+
- test/engine_test.rb
|
114
|
+
- test/template_test.rb
|
115
|
+
- test/teststrap.rb
|