jasonette-rails 0.1.2 → 0.2.0
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.
- checksums.yaml +4 -4
- data/README.md +2 -1
- data/Rakefile +0 -1
- data/lib/jasonette-rails.rb +1 -0
- data/lib/jasonette.rb +26 -11
- data/lib/jasonette/action_view_extensions.rb +15 -0
- data/lib/jasonette/core/action.rb +34 -0
- data/lib/jasonette/core/base.rb +177 -60
- data/lib/jasonette/core/body.rb +14 -0
- data/lib/jasonette/core/body/footer.rb +7 -0
- data/lib/jasonette/core/body/footer/input.rb +24 -0
- data/lib/jasonette/core/body/footer/tabs.rb +11 -0
- data/lib/jasonette/core/body/header.rb +21 -0
- data/lib/jasonette/core/body/header/search.rb +6 -0
- data/lib/jasonette/core/body/layers.rb +4 -0
- data/lib/jasonette/core/body/sections.rb +5 -0
- data/lib/jasonette/core/components.rb +0 -9
- data/lib/jasonette/core/data.rb +4 -0
- data/lib/jasonette/core/item.rb +21 -0
- data/lib/jasonette/core/items.rb +99 -14
- data/lib/jasonette/core/layout.rb +2 -5
- data/lib/jasonette/core/map.rb +6 -0
- data/lib/jasonette/core/options.rb +9 -0
- data/lib/jasonette/{jason/body/header.rb → core/pins.rb} +1 -1
- data/lib/jasonette/core/properties.rb +151 -22
- data/lib/jasonette/engine.rb +10 -0
- data/lib/jasonette/handler.rb +14 -0
- data/lib/jasonette/helpers.rb +38 -0
- data/lib/jasonette/jason/body.rb +2 -9
- data/lib/jasonette/jason/head.rb +22 -2
- data/lib/jasonette/jason/head/actions.rb +5 -0
- data/lib/jasonette/jason/head/templates.rb +5 -0
- data/lib/jasonette/railtie.rb +30 -0
- data/lib/jasonette/template.rb +201 -0
- data/lib/jasonette/version.rb +1 -1
- metadata +55 -23
- data/lib/jasonette/core/sections.rb +0 -9
- data/lib/jasonette/jason/body/header/search.rb +0 -5
- data/lib/jasonette/jbuilder_extensions.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 89ec6352c3bb86dd49af440b735535264434176d
|
4
|
+
data.tar.gz: ed9f0f8ed31dca762ef2d576f240a3a57221b299
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f248d2b865dffc64cdfabd1d32e558f8aa54661a2b71faed45ec0fb762db51642feb98f016d6615246657817f132d502f43e697f7ff96c28402b16c5e8073482
|
7
|
+
data.tar.gz: dd6ff575d3beb33b39a04cf6bba7282423f6c4c6ea7fa668302d74f44445e95e27e94968d80769f9d86bdc3feff0ce337baed15cb7fb5ddfd1cdf6c7f8e9bded
|
data/README.md
CHANGED
@@ -4,7 +4,8 @@ flavored JSON in Rails.
|
|
4
4
|
|
5
5
|
## ALPHA code!
|
6
6
|
|
7
|
-
Warning:
|
7
|
+
Warning: Work in progress. Proceed with caution. Testers and contributions are welcome.
|
8
|
+
This project is **alpha** code and still in highly experimental stage and subjected to
|
8
9
|
drastic changes to the DSL. It is also quite full of bugs despite the unit tests you may find herein!
|
9
10
|
|
10
11
|
Note: Almost nothing about this gem is documented, however, you can find ample examples in the project's
|
data/Rakefile
CHANGED
data/lib/jasonette-rails.rb
CHANGED
data/lib/jasonette.rb
CHANGED
@@ -1,24 +1,39 @@
|
|
1
|
-
require 'rails/railtie'
|
2
|
-
require 'jbuilder/jbuilder_template'
|
3
|
-
|
4
|
-
module Jasonette
|
5
|
-
end
|
6
|
-
|
7
1
|
# Core components for library
|
8
2
|
require_relative 'jasonette/core/properties'
|
9
3
|
require_relative 'jasonette/core/base'
|
10
4
|
require_relative 'jasonette/core/style'
|
11
|
-
require_relative 'jasonette/core/
|
5
|
+
require_relative 'jasonette/core/item'
|
12
6
|
require_relative 'jasonette/core/items'
|
13
7
|
require_relative 'jasonette/core/layout'
|
8
|
+
require_relative 'jasonette/core/map'
|
9
|
+
require_relative 'jasonette/core/pins'
|
14
10
|
require_relative 'jasonette/core/components'
|
11
|
+
require_relative 'jasonette/core/options'
|
12
|
+
require_relative 'jasonette/core/action'
|
13
|
+
require_relative 'jasonette/core/data'
|
14
|
+
require_relative 'jasonette/core/body'
|
15
|
+
require_relative 'jasonette/core/body/header'
|
16
|
+
require_relative 'jasonette/core/body/header/search'
|
17
|
+
require_relative 'jasonette/core/body/footer'
|
18
|
+
require_relative 'jasonette/core/body/footer/input'
|
19
|
+
require_relative 'jasonette/core/body/footer/tabs'
|
20
|
+
require_relative 'jasonette/core/body/sections'
|
21
|
+
require_relative 'jasonette/core/body/layers'
|
15
22
|
|
16
23
|
# Structural components
|
17
24
|
require_relative 'jasonette/jason'
|
18
25
|
require_relative 'jasonette/jason/head'
|
26
|
+
require_relative 'jasonette/jason/head/actions'
|
27
|
+
require_relative 'jasonette/jason/head/templates'
|
19
28
|
require_relative 'jasonette/jason/body'
|
20
|
-
require_relative 'jasonette/jason/body/header'
|
21
|
-
require_relative 'jasonette/jason/body/header/search'
|
22
29
|
|
23
|
-
|
24
|
-
|
30
|
+
module Jasonette
|
31
|
+
def self.setup
|
32
|
+
yield self
|
33
|
+
end
|
34
|
+
|
35
|
+
# :dump_options, :load_options
|
36
|
+
def self.multi_json
|
37
|
+
yield ::MultiJson
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Jasonette
|
2
|
+
module TemplateRendererExtensions
|
3
|
+
def render(context, options)
|
4
|
+
@details = extract_details(options)
|
5
|
+
path, locals = options[:layout], options[:locals] || {}
|
6
|
+
layout = path && find_layout(path, locals.keys, [formats.first])
|
7
|
+
if !layout.try(:virtual_path).nil?
|
8
|
+
JasonSingleton.fetch(context).__layout = layout
|
9
|
+
JasonSingleton.fetch(context).__locals = locals
|
10
|
+
end
|
11
|
+
super
|
12
|
+
end
|
13
|
+
end
|
14
|
+
::ActionView::TemplateRenderer.send(:prepend, TemplateRendererExtensions)
|
15
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Jasonette
|
2
|
+
class Action < Jasonette::Base
|
3
|
+
property :options
|
4
|
+
property :success
|
5
|
+
property :error
|
6
|
+
|
7
|
+
def trigger name, &block
|
8
|
+
with_attributes do
|
9
|
+
set! "trigger", name
|
10
|
+
encode(&block) if block_given?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def render!
|
15
|
+
set! "type", "$render"
|
16
|
+
end
|
17
|
+
|
18
|
+
def reload!
|
19
|
+
set! "type", "$reload"
|
20
|
+
end
|
21
|
+
|
22
|
+
def success &block
|
23
|
+
@success = Jasonette::Action.new(context) do
|
24
|
+
block_given? ? encode(&block) : render!
|
25
|
+
end
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def error &block
|
30
|
+
@error = Jasonette::Action.new(context, &block)
|
31
|
+
self
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/jasonette/core/base.rb
CHANGED
@@ -1,20 +1,17 @@
|
|
1
1
|
module Jasonette
|
2
2
|
class Base
|
3
3
|
include Properties
|
4
|
-
include ActionView::Helpers
|
5
4
|
|
6
5
|
def implicit_set! name, *args, &block
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
json.set!(name) { instance_eval(&block) }
|
12
|
-
end
|
6
|
+
if property_names.include? name
|
7
|
+
with_attributes { property_set! name, *args, &block }
|
8
|
+
else
|
9
|
+
set!(name) { encode(&block) }
|
13
10
|
end
|
14
11
|
end
|
15
12
|
|
16
13
|
def attr_value name
|
17
|
-
if
|
14
|
+
if property_names.include? name
|
18
15
|
instance_variable_get :"@#{name}"
|
19
16
|
else
|
20
17
|
@attributes[name.to_s]
|
@@ -25,104 +22,224 @@ module Jasonette
|
|
25
22
|
if ::Kernel.block_given?
|
26
23
|
implicit_set! name, *args, &block
|
27
24
|
else
|
28
|
-
if
|
25
|
+
if property_names.include? name
|
29
26
|
return property_get! name
|
30
27
|
else
|
31
|
-
|
28
|
+
set! name, *args if args.present?
|
32
29
|
end
|
33
30
|
end
|
34
|
-
self
|
35
31
|
end
|
36
32
|
|
37
33
|
attr_reader :context
|
38
34
|
attr_reader :attributes
|
39
|
-
attr_reader :json
|
40
35
|
|
41
36
|
def initialize context
|
42
37
|
@context = context
|
43
38
|
@attributes = {}
|
44
|
-
|
39
|
+
|
40
|
+
encode(&::Proc.new) if ::Kernel.block_given?
|
45
41
|
end
|
46
42
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
43
|
+
# Fixed for below error :
|
44
|
+
# IOError - not opened for reading:
|
45
|
+
# activesupport (5.0.1) lib/active_support/core_ext/object/json.rb:130:in `as_json'
|
46
|
+
# Eventually called by multi_json/adapter.rb:25:in `dump'
|
47
|
+
def as_json(options = nil)
|
48
|
+
attributes!
|
49
|
+
end
|
50
|
+
|
51
|
+
def encode
|
52
|
+
binding = eval "self", ::Proc.new.binding
|
53
|
+
if (binding.method(:encode).parameters.first.include?(:req) rescue false)
|
54
|
+
binding.encode(self, &::Proc.new)
|
55
|
+
else
|
56
|
+
instance_eval(&::Proc.new)
|
51
57
|
end
|
58
|
+
self
|
52
59
|
end
|
53
60
|
|
54
|
-
def
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
61
|
+
def empty?
|
62
|
+
properties_empty? && @attributes.empty?
|
63
|
+
end
|
64
|
+
|
65
|
+
def klass name
|
66
|
+
set! "class", name
|
67
|
+
end
|
68
|
+
alias :css_class :klass
|
69
|
+
|
70
|
+
def _method name = nil
|
71
|
+
if block_given?
|
72
|
+
set! 'method', _scope { yield }
|
73
|
+
else
|
74
|
+
set! 'method', name
|
59
75
|
end
|
60
76
|
end
|
77
|
+
alias :action_method :_method
|
78
|
+
|
79
|
+
def with_attributes
|
80
|
+
@attributes.merge! _scope { yield self }
|
81
|
+
self
|
82
|
+
end
|
61
83
|
|
62
|
-
def
|
63
|
-
|
84
|
+
def inline json
|
85
|
+
@attributes.merge! JSON.parse(json)
|
86
|
+
self
|
64
87
|
end
|
65
88
|
|
66
|
-
def
|
67
|
-
|
89
|
+
def attributes!
|
90
|
+
merge_properties
|
91
|
+
@attributes
|
68
92
|
end
|
69
93
|
|
70
|
-
def
|
71
|
-
|
72
|
-
if
|
73
|
-
|
94
|
+
def set! key, value=nil, *args
|
95
|
+
result = if ::Kernel.block_given?
|
96
|
+
if !_blank?(value)
|
97
|
+
# comments @post.comments { |comment| ... }
|
98
|
+
# { "comments": [ { ... }, { ... } ] }
|
99
|
+
_scope{ array! value, &::Proc.new }
|
100
|
+
else
|
101
|
+
# comments { ... }
|
102
|
+
# { "comments": ... }
|
103
|
+
_merge_block(key){ yield self }
|
104
|
+
end
|
105
|
+
elsif args.empty?
|
106
|
+
if _is_collection?(value) || Jasonette::Base === value
|
107
|
+
# person another_jasonette
|
108
|
+
# { "person": { ... } }
|
109
|
+
# comments [ { content: "...", created_at: "..." } ]
|
110
|
+
# { "comments": [ { "content": "hello", "created_at": "..." } ] }
|
111
|
+
# comments { content: "...", created_at: "..." }
|
112
|
+
# { "comments": [ { "content": "hello", "created_at": "..." } ] }
|
113
|
+
_scope{ merge! value }
|
74
114
|
else
|
75
|
-
|
115
|
+
_key(value)
|
76
116
|
end
|
117
|
+
elsif _is_collection?(value)
|
118
|
+
# comments @post.comments, :content, :created_at
|
119
|
+
# { "comments": [ { "content": "hello", "created_at": "..." }, { "content": "world", "created_at": "..." } ] }
|
120
|
+
_scope{ array! value, *args }
|
121
|
+
else
|
122
|
+
# author @post.creator, :name, :email_address
|
123
|
+
# { "author": { "name": "David", "email_address": "david@loudthinking.com" } }
|
124
|
+
_merge_block(key){ extract! value, *args }
|
77
125
|
end
|
78
|
-
end
|
79
126
|
|
80
|
-
|
81
|
-
|
127
|
+
_set_key_value key, result
|
128
|
+
self
|
82
129
|
end
|
83
130
|
|
84
|
-
|
85
|
-
|
86
|
-
|
131
|
+
|
132
|
+
def array! collection = [], *args
|
133
|
+
array = if collection.nil?
|
134
|
+
[]
|
135
|
+
elsif ::Kernel.block_given?
|
136
|
+
_map_collection(collection, &::Proc.new)
|
137
|
+
else
|
138
|
+
_map_collection(collection) { |element| extract! element, *args }
|
139
|
+
end
|
140
|
+
|
141
|
+
merge! array
|
87
142
|
end
|
88
143
|
|
89
|
-
def
|
90
|
-
|
144
|
+
def extract! object, *attributes
|
145
|
+
if ::Hash === object
|
146
|
+
_extract_hash_values(object, attributes)
|
147
|
+
elsif Jasonette::Base === object
|
148
|
+
_extract_hash_values(object.attributes!, attributes)
|
149
|
+
else
|
150
|
+
_extract_method_values(object, attributes)
|
151
|
+
end
|
91
152
|
end
|
92
153
|
|
93
|
-
def
|
94
|
-
|
154
|
+
def merge! key
|
155
|
+
case key
|
156
|
+
when Jasonette::Base
|
157
|
+
merge! key.attributes!
|
158
|
+
when Hash
|
159
|
+
key.each{ |key, value| set! _key(key), value }
|
160
|
+
when Array
|
161
|
+
_set_value key
|
162
|
+
end
|
163
|
+
@attributes
|
95
164
|
end
|
96
|
-
alias :css_class :klass
|
97
165
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
166
|
+
private
|
167
|
+
|
168
|
+
def _extract_hash_values(object, attributes)
|
169
|
+
if attributes.blank?
|
170
|
+
object.each{ |key, value| _set_key_value key, value }
|
171
|
+
else
|
172
|
+
attributes.each{ |key| _set_key_value key, object.fetch(key) }
|
102
173
|
end
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
174
|
+
end
|
175
|
+
|
176
|
+
def _extract_method_values(object, attributes)
|
177
|
+
if attributes.blank?
|
178
|
+
_set_value object
|
179
|
+
else
|
180
|
+
attributes.each{ |key| _set_key_value key, object.public_send(key) }
|
107
181
|
end
|
108
|
-
@attributes.merge! template.attributes!
|
109
|
-
self
|
110
182
|
end
|
111
183
|
|
112
|
-
def
|
113
|
-
@attributes.
|
114
|
-
self
|
184
|
+
def _merge_block(key)
|
185
|
+
current_value = @attributes.fetch(_key(key), {})
|
186
|
+
new_value = _scope{ yield self }
|
187
|
+
_merge_values(current_value, new_value)
|
115
188
|
end
|
116
189
|
|
117
|
-
def
|
118
|
-
|
119
|
-
|
190
|
+
def _merge_values(current_value, updates)
|
191
|
+
if _blank?(updates)
|
192
|
+
current_value
|
193
|
+
elsif _blank?(current_value) || updates.nil? || current_value.empty? && ::Array === updates
|
194
|
+
updates
|
195
|
+
elsif ::Array === current_value && ::Array === updates
|
196
|
+
current_value + updates
|
197
|
+
elsif ::Hash === current_value && ::Hash === updates
|
198
|
+
current_value.merge(updates)
|
199
|
+
else
|
200
|
+
raise "MergeError"
|
120
201
|
end
|
121
202
|
end
|
122
203
|
|
123
|
-
def
|
124
|
-
|
204
|
+
def _key(key)
|
205
|
+
key.to_s
|
206
|
+
end
|
207
|
+
|
208
|
+
def _set_key_value(key, value)
|
209
|
+
raise "ArrayError" if ::Array === @attributes
|
210
|
+
@attributes[_key(key)] = value unless _blank?(value)
|
211
|
+
end
|
212
|
+
|
213
|
+
def _set_value(value)
|
214
|
+
raise "HashError" if ::Hash === @attributes && !_blank?
|
215
|
+
@attributes = value unless _blank?(value)
|
216
|
+
end
|
217
|
+
|
218
|
+
def _map_collection(collection)
|
219
|
+
collection.map do |element|
|
220
|
+
_scope{ yield element }
|
221
|
+
end # - [BLANK]
|
222
|
+
end
|
223
|
+
|
224
|
+
def _scope
|
225
|
+
parent_attributes = @attributes
|
226
|
+
@attributes = {}
|
227
|
+
yield
|
125
228
|
@attributes
|
229
|
+
ensure
|
230
|
+
@attributes = parent_attributes
|
231
|
+
end
|
232
|
+
|
233
|
+
def _is_collection?(object)
|
234
|
+
_object_respond_to?(object, :map, :count) # && NON_ENUMERABLES.none?{ |klass| klass === object }
|
235
|
+
end
|
236
|
+
|
237
|
+
def _blank?(value=@attributes)
|
238
|
+
value.nil? ? true : value.blank?
|
239
|
+
end
|
240
|
+
|
241
|
+
def _object_respond_to?(object, *methods)
|
242
|
+
methods.all?{ |m| object.respond_to?(m) }
|
126
243
|
end
|
127
244
|
end
|
128
245
|
end
|