dao 2.1.0 → 2.2.3

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/lib/dao/form.rb CHANGED
@@ -60,19 +60,19 @@ module Dao
60
60
  options = Dao.map_for(args.last.is_a?(Hash) ? args.pop : {})
61
61
  keys = args.flatten
62
62
 
63
- name = options.delete(:name) || keys.last
64
63
  id = options.delete(:id) || id_for(keys)
65
64
  klass = class_for(keys, options.delete(:class))
66
65
  error = error_for(keys, options.delete(:error))
66
+ target = options.delete(:for) || id_for(keys)
67
67
 
68
68
  content =
69
- if block.nil? and !options.has_key?(:content)
70
- name.to_s.humanize
69
+ if block.nil? and !options.has_key?(:content)
70
+ humanize(keys.last)
71
71
  else
72
72
  block ? block.call() : options.delete(:content)
73
73
  end
74
74
 
75
- label_(options_for(options, :name => name, :class => klass, :id => id, :data_error => error)){ content }
75
+ label_(options_for(options, :for => target, :class => klass, :id => id, :data_error => error)){ content }
76
76
  end
77
77
 
78
78
  def input(*args, &block)
@@ -97,10 +97,14 @@ module Dao
97
97
 
98
98
  def submit(*args, &block)
99
99
  options = Dao.map_for(args.last.is_a?(Hash) ? args.pop : {})
100
- options[:type] = :submit
101
- options[:value] = block ? block.call : :Submit
102
- args.push(options)
103
- input(*args)
100
+
101
+ content = block ? block.call : (args.first || 'Submit')
102
+
103
+ options[:name] ||= :submit
104
+ options[:type] ||= :submit
105
+ options[:value] ||= content
106
+
107
+ input_(options_for(options)){}
104
108
  end
105
109
 
106
110
  def button(*args)
@@ -156,6 +160,13 @@ module Dao
156
160
  name = options.delete(:name) || name_for(keys)
157
161
  from = options.delete(:from) || options.delete(:options)
158
162
 
163
+ selected =
164
+ if options.has_key?(:selected)
165
+ options.delete(:selected)
166
+ else
167
+ value_for(data, keys)
168
+ end
169
+
159
170
  id = options.delete(:id) || id_for(keys)
160
171
  klass = class_for(keys, options.delete(:class))
161
172
  error = error_for(keys, options.delete(:error))
@@ -170,7 +181,6 @@ module Dao
170
181
 
171
182
  list = Array(from)
172
183
 
173
-
174
184
  case list.first
175
185
  when Hash, Array
176
186
  nil
@@ -180,11 +190,21 @@ module Dao
180
190
  list.map!{|element| [element, element]}
181
191
  end
182
192
 
183
- selected_value = value_for(data, keys)
193
+ selected_value =
194
+ case selected
195
+ when Array
196
+ selected.first
197
+ when Hash
198
+ key = [:id, 'id', :value, 'value'].detect{|k| selected.has_key?(k)}
199
+ key ? selected[key] : selected
200
+ else
201
+ selected
202
+ end
184
203
 
185
204
  select_(options_for(options, :name => name, :class => klass, :id => id, :data_error => error)){
186
205
  list.each do |pair|
187
206
  returned = block.call(pair)
207
+
188
208
  case returned
189
209
  when Array
190
210
  value, content, selected, *ignored = returned
@@ -197,9 +217,11 @@ module Dao
197
217
  content = returned
198
218
  selected = nil
199
219
  end
220
+
200
221
  if selected.nil?
201
222
  selected = value.to_s==selected_value.to_s
202
223
  end
224
+
203
225
  opts = {:value => value}
204
226
  opts[:selected] = !!selected if selected
205
227
  option_(opts){ content }
@@ -233,8 +255,24 @@ module Dao
233
255
  value = Tagz.escapeHTML(data.get(keys))
234
256
  end
235
257
 
258
+ def Form.name_for(path, *keys)
259
+ path = Path.new(path) unless path.is_a?(Path)
260
+ "#{ path }(#{ Array(keys).flatten.compact.join(',') })"
261
+ end
262
+
263
+ def Form.name_re_for(path)
264
+ path = Path.new(path) unless path.is_a?(Path)
265
+ Regexp.new(/^#{ Regexp.escape(path) }/)
266
+ end
267
+
268
+ def Form.encoded?(path, params)
269
+ name_re = Form.name_re_for(path)
270
+ params.keys.any?{|key| name_re =~ key.to_s}
271
+ end
272
+
273
+
236
274
  def name_for(keys)
237
- "#{ result.path }(#{ Array(keys).flatten.compact.join(',') })"
275
+ Form.name_for(result.path, keys)
238
276
  end
239
277
 
240
278
  def options_for(*hashes)
@@ -256,5 +294,11 @@ module Dao
256
294
  def attr_for(string)
257
295
  slug_for(string).gsub(/_/, '-')
258
296
  end
297
+
298
+ def humanize(string)
299
+ string = string.to_s
300
+ string = string.humanize if string.respond_to?(:humanize)
301
+ string
302
+ end
259
303
  end
260
304
  end
data/lib/dao/params.rb CHANGED
@@ -3,9 +3,11 @@ module Dao
3
3
  include Dao::InstanceExec
4
4
 
5
5
  class << Params
6
- def parse(prefix, params = {})
6
+ def parse(prefix, params = {}, options = {})
7
7
  prefix = prefix.to_s
8
- params = Map.new(params)
8
+ params = Map.new(params || {})
9
+ base = Map.new(params || {})
10
+ options = Map.options(options || {})
9
11
  parsed = Params.new
10
12
  parsed.update(params[prefix]) if params.has_key?(prefix)
11
13
 
@@ -17,11 +19,44 @@ module Dao
17
19
  matched, keys = re.match(key).to_a
18
20
  next unless matched
19
21
  next unless keys
20
- keys = keys.strip.split(%r/\s*,\s*/).map{|key| key =~ %r/^\d+$/ ? Integer(key) : key}
22
+ keys = keys_for(keys)
21
23
  parsed.set(keys => value)
24
+ base.delete(key)
22
25
  end
23
26
 
24
- parsed
27
+ whitelist = Set.new( [options.getopt([:include, :select, :only])].flatten.compact.map{|k| k.to_s} )
28
+ blacklist = Set.new( [options.getopt([:exclude, :reject, :except])].flatten.compact.map{|k| k.to_s} )
29
+
30
+ unless blacklist.empty?
31
+ base.keys.dup.each do |key|
32
+ base.delete(key) if blacklist.include?(key.to_s)
33
+ end
34
+ end
35
+
36
+ unless whitelist.empty?
37
+ base.keys.dup.each do |key|
38
+ base.delete(key) unless whitelist.include?(key.to_s)
39
+ end
40
+ end
41
+
42
+ if options.getopt(:fold, default=true)
43
+ parsed_and_folded = base.merge(parsed)
44
+ else
45
+ parsed
46
+ end
47
+ end
48
+
49
+ def keys_for(keys)
50
+ keys.strip.split(%r/\s*,\s*/).map{|key| key =~ %r/^\d+$/ ? Integer(key) : key}
51
+ end
52
+
53
+ def process(path, params, options = {})
54
+ return params if params.is_a?(Params)
55
+
56
+ parsed = Params.parse(path, params, options)
57
+ return parsed unless parsed.empty?
58
+
59
+ return Params.new(params)
25
60
  end
26
61
  end
27
62
 
@@ -82,52 +117,7 @@ module Dao
82
117
  end
83
118
  end
84
119
 
85
- def Dao.parse(path, params)
86
- return params if params.is_a?(Params)
87
-
88
- smells_like_unparsed_rails_params = (
89
- params.has_key?(:action) and
90
- params.has_key?(:controller) and
91
- params.class.name =~ /HashWithIndifferentAccess/
92
- )
93
- return(Params.parse(path.to_s, params)) if smells_like_unparsed_rails_params
94
-
95
- smells_like_unparsed_params = false
96
- unparsed_re = %r/^#{ Regexp.escape(path.to_s) }/
97
- params.each do |key, val|
98
- if key =~ unparsed_re
99
- smells_like_unparsed_params = true
100
- break
101
- end
102
- end
103
- return(Params.parse(path.to_s, params)) if smells_like_unparsed_params
104
-
105
- return Params.new(params)
106
- end
107
-
108
- =begin
109
- def Dao.parse(path, params)
110
- returned = Params.new(params)
111
-
112
- smells_like_rails = (params.has_key?(:action) and params.has_key?(:controller) and params.class.name =~ /HashWithIndifferentAccess/)
113
- if smells_like_rails
114
- returned.delete(:action)
115
- returned.delete(:controller)
116
- returned.update(Params.parse(path, params))
117
- return returned
118
- end
119
-
120
- re = %r/^#{ Regexp.escape(path) }/
121
- smells_like_unparsed = false
122
- params.each do |key, val|
123
- break(smells_like_unparsed = true) if key =~ re
124
- end
125
- if smells_like_unparsed
126
- returned.update(Params.parse(path, params))
127
- return returned
128
- end
129
-
130
- return returned
120
+ def Dao.parse(*args, &block)
121
+ Params.process(*args, &block)
131
122
  end
132
- =end
133
123
  end
@@ -0,0 +1,129 @@
1
+ module Dao
2
+ class Presenter
3
+ include Tagz.globally
4
+
5
+ class << Presenter
6
+ def for(*args, &block)
7
+ new(*args, &block)
8
+ end
9
+ end
10
+
11
+ attr_accessor :result
12
+ attr_accessor :formats
13
+
14
+ def initialize(*args, &block)
15
+ @result = args.shift if args.first.is_a?(Result)
16
+ @formats = Map.new
17
+ end
18
+
19
+ %w( set get has has? [] ).each do |method|
20
+ module_eval <<-__, __FILE__, __LINE__
21
+ def #{ method }(*args, &block)
22
+ data.#{ method }(*args, &block)
23
+ end
24
+ __
25
+ end
26
+
27
+ def extend(*args, &block)
28
+ return super if block.nil?
29
+ singleton_class =
30
+ class << self
31
+ self
32
+ end
33
+ singleton_class.module_eval(&block)
34
+ end
35
+
36
+ def tag(*args, &block)
37
+ options = Dao.options_for!(args)
38
+ args.push(:div) if args.empty?
39
+ tagname = args.shift
40
+ keys = args
41
+
42
+ tag_method = "#{ tagname }_"
43
+
44
+ id = options.delete(:id) || id_for(keys)
45
+ klass = class_for(keys, options.delete(:class))
46
+ error = error_for(keys, options.delete(:error))
47
+
48
+ tag_options =
49
+ options_for(options, :id => id, :class => klass, :data_error => error)
50
+
51
+ value = value_for(keys)
52
+ tag_value = instance_exec(value, &format_for(keys))
53
+
54
+ send(tag_method, tag_options){ tag_value }
55
+ end
56
+
57
+ include InstanceExec
58
+
59
+ DefaultFormat = lambda{|value| value}
60
+
61
+ def format_for(keys)
62
+ formats.get(keys) || DefaultFormat
63
+ end
64
+
65
+ def format(list_of_keys, &block)
66
+ Array(list_of_keys).each do |keys|
67
+ formats.set(keys, block)
68
+ end
69
+ end
70
+
71
+ def data
72
+ result.data
73
+ end
74
+
75
+ def errors
76
+ result.errors
77
+ end
78
+
79
+ def ==(other)
80
+ result == other.result
81
+ end
82
+
83
+ def id_for(keys)
84
+ id = [result.path, keys.join('-')].compact.join('_')
85
+ slug_for(id)
86
+ end
87
+
88
+ def class_for(keys, klass = nil)
89
+ klass =
90
+ if result.errors.on?(keys)
91
+ [klass, 'dao', 'errors'].compact.join(' ')
92
+ else
93
+ [klass, 'dao'].compact.join(' ')
94
+ end
95
+ klass
96
+ end
97
+
98
+ def error_for(keys, klass = nil)
99
+ if result.errors.on?(keys)
100
+ result.errors.get(keys)
101
+ end
102
+ end
103
+
104
+ def value_for(keys)
105
+ return nil unless data.has?(keys)
106
+ value = Tagz.escapeHTML(data.get(keys))
107
+ end
108
+
109
+ def options_for(*hashes)
110
+ map = Map.new
111
+ hashes.flatten.each do |h|
112
+ h.each{|k,v| map[attr_for(k)] = v unless v.nil?}
113
+ end
114
+ map
115
+ end
116
+
117
+ def slug_for(string)
118
+ string = string.to_s
119
+ words = string.to_s.scan(%r/\w+/)
120
+ words.map!{|word| word.gsub(%r/[^0-9a-zA-Z_:-]/, '')}
121
+ words.delete_if{|word| word.nil? or word.strip.empty?}
122
+ words.join('-').downcase.sub(/_+$/, '')
123
+ end
124
+
125
+ def attr_for(string)
126
+ slug_for(string).gsub(/_/, '-')
127
+ end
128
+ end
129
+ end
data/lib/dao/rails.rb CHANGED
@@ -7,12 +7,60 @@ if defined?(Rails)
7
7
  ### ref: https://gist.github.com/af7e572c2dc973add221
8
8
 
9
9
  paths.path = ROOT_DIR
10
+
10
11
  ### config.autoload_paths << APP_DIR
11
12
  ### $LOAD_PATH.push(File.join(Rails.root.to_s, 'app'))
12
-
13
13
  #config.after_initialize do
14
14
  #unloadable(Dao)
15
15
  #end
16
+
17
+
18
+ # yes yes, this should probably be somewhere else...
19
+ #
20
+ config.after_initialize do
21
+
22
+ ActionController::Base.module_eval do
23
+
24
+ # you will likely want to override this!
25
+ #
26
+ def current_api
27
+ @api ||= (
28
+ api = Api.new
29
+ %w( real_user effective_user current_user ).each do |attr|
30
+ getter = "#{ attr }"
31
+ setter = "#{ attr }="
32
+ if respond_to?(getter) and api.respond_to?(setter)
33
+ api.send(setter, send(getter))
34
+ end
35
+ end
36
+ api
37
+ )
38
+ end
39
+ helper_method(:current_api)
40
+ alias_method(:api, :current_api)
41
+ helper_method(:api)
42
+
43
+ # setup sane rescuing from dao errors with crap statuses
44
+ #
45
+ rescue_from(Dao::Error::Result) do |error|
46
+ result = error.result
47
+ basename = "#{ result.status.code }.html"
48
+ error_page = File.join(Rails.root, 'public', basename)
49
+
50
+ if test(?e, error_page)
51
+ file = File.expand_path(error_page)
52
+ status = result.status.code
53
+ render(:file => file, :status => status, :layout => false)
54
+ else
55
+ text = result.status.to_s
56
+ status = result.status.code
57
+ render(:text => text, :status => status, :layout => false)
58
+ end
59
+ end
60
+ end
61
+
62
+ end
63
+
16
64
  end
17
65
  end
18
66
  end
@@ -12,8 +12,7 @@ class DaoGenerator < Rails::Generators::NamedBase
12
12
 
13
13
  copy_file("dao.css", "public/stylesheets/dao.css")
14
14
 
15
- route("match 'api/*path' => 'api#call', :as => 'api'")
16
- route("match 'api' => 'api#index', :as => 'api_index'")
15
+ route("match 'api(/*path)' => 'api#index', :as => 'api'")
17
16
 
18
17
  gem("yajl-ruby")
19
18