rabl 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|