dao 4.2.1 → 4.4.2

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.
Files changed (78) hide show
  1. data/README +103 -63
  2. data/Rakefile +3 -3
  3. data/dao.gemspec +27 -16
  4. data/lib/dao.rb +17 -17
  5. data/lib/dao/active_record.rb +1 -0
  6. data/lib/dao/api.rb +2 -1
  7. data/lib/dao/api/{endpoints.rb → call.rb} +1 -0
  8. data/lib/dao/api/context.rb +2 -0
  9. data/lib/dao/api/dsl.rb +1 -0
  10. data/lib/dao/api/initializers.rb +1 -0
  11. data/lib/dao/api/modes.rb +1 -0
  12. data/lib/dao/api/routes.rb +1 -0
  13. data/lib/dao/blankslate.rb +1 -0
  14. data/lib/dao/conducer.rb +315 -274
  15. data/lib/dao/conducer/active_model.rb +98 -0
  16. data/lib/dao/conducer/attributes.rb +1 -0
  17. data/lib/dao/conducer/autocrud.rb +58 -0
  18. data/lib/dao/conducer/callback_support.rb +20 -0
  19. data/lib/dao/conducer/collection.rb +45 -0
  20. data/lib/dao/conducer/controller_support.rb +104 -0
  21. data/lib/dao/conducer/nav_support.rb +9 -0
  22. data/lib/dao/conducer/view_support.rb +16 -0
  23. data/lib/dao/data.rb +2 -1
  24. data/lib/dao/db.rb +2 -0
  25. data/lib/dao/endpoint.rb +1 -0
  26. data/lib/dao/engine.rb +1 -0
  27. data/lib/dao/errors.rb +109 -99
  28. data/lib/dao/exceptions.rb +1 -0
  29. data/lib/dao/extractor.rb +1 -0
  30. data/lib/dao/form.rb +175 -20
  31. data/lib/dao/instance_exec.rb +1 -0
  32. data/lib/dao/mode.rb +1 -0
  33. data/lib/dao/mongo_mapper.rb +1 -0
  34. data/lib/dao/name.rb +1 -0
  35. data/lib/dao/params.rb +2 -1
  36. data/lib/dao/path.rb +1 -0
  37. data/lib/dao/path_map.rb +24 -0
  38. data/lib/dao/rack.rb +1 -0
  39. data/lib/dao/rack/middleware.rb +1 -0
  40. data/lib/dao/rack/middleware/params_parser.rb +1 -0
  41. data/lib/dao/rails.rb +12 -32
  42. data/lib/dao/rails/lib/generators/dao/USAGE +2 -2
  43. data/lib/dao/rails/lib/generators/dao/dao_generator.rb +8 -27
  44. data/lib/dao/rails/lib/generators/dao/templates/api.rb +2 -1
  45. data/lib/dao/rails/lib/generators/dao/templates/api_controller.rb +22 -20
  46. data/lib/dao/rails/lib/generators/dao/templates/conducer.rb +49 -43
  47. data/lib/dao/rails/lib/generators/dao/templates/dao.css +26 -25
  48. data/lib/dao/rails/lib/generators/dao/templates/dao.js +3 -0
  49. data/lib/dao/rails/lib/generators/dao/templates/dao_helper.rb +58 -45
  50. data/lib/dao/result.rb +50 -1
  51. data/lib/dao/route.rb +1 -0
  52. data/lib/dao/slug.rb +12 -36
  53. data/lib/dao/status.rb +91 -7
  54. data/lib/dao/stdext.rb +1 -0
  55. data/lib/dao/support.rb +90 -80
  56. data/lib/dao/upload.rb +396 -0
  57. data/lib/dao/validations.rb +23 -5
  58. data/lib/dao/validations/callback.rb +5 -0
  59. data/lib/dao/validations/common.rb +100 -3
  60. data/lib/dao/validations/instance.rb +17 -0
  61. data/lib/dao/validations/validator.rb +192 -91
  62. data/test/active_model_conducer_lint_test.rb +1 -0
  63. data/test/api_test.rb +15 -0
  64. data/test/conducer_test.rb +608 -90
  65. data/test/data/han-solo.jpg +0 -0
  66. data/test/form_test.rb +1 -0
  67. data/test/helper.rb +1 -0
  68. data/test/leak.rb +1 -0
  69. data/test/support_test.rb +4 -1
  70. data/test/testing.rb +1 -0
  71. data/test/validations_test.rb +176 -30
  72. metadata +120 -131
  73. data/b.rb +0 -38
  74. data/lib/dao/conducer/crud.rb +0 -70
  75. data/lib/dao/current.rb +0 -66
  76. data/lib/dao/image_cache.rb +0 -193
  77. data/lib/dao/rails/lib/generators/dao/templates/conducer_controller.rb +0 -79
  78. data/test/db.yml +0 -9
@@ -0,0 +1,98 @@
1
+ module Dao
2
+ class Conducer
3
+ include ActiveModel::Naming
4
+ include ActiveModel::Conversion
5
+ extend ActiveModel::Translation
6
+
7
+ =begin
8
+ include ActiveModel::AttributeMethods
9
+ include ActiveModel::Serialization
10
+ include ActiveModel::Dirty
11
+ include ActiveModel::MassAssignmentSecurity
12
+ include ActiveModel::Observing
13
+ include ActiveModel::Serializers::JSON
14
+ include ActiveModel::Serializers::Xml
15
+ include ActiveModel::Validations
16
+ extend ActiveModel::Callbacks
17
+ define_model_callbacks(:save, :create, :update, :destroy)
18
+ define_model_callbacks(:reset, :initialize, :find, :touch)
19
+ include ActiveModel::Validations::Callbacks
20
+ =end
21
+
22
+ class << Conducer
23
+ def model_name(*args)
24
+ return send('model_name=', args.first.to_s) unless args.empty?
25
+ @model_name ||= default_model_name
26
+ end
27
+
28
+ def model_name=(model_name)
29
+ @model_name = model_name_for(model_name)
30
+ end
31
+
32
+ def model_name_for(model_name)
33
+ ActiveModel::Name.new(Map[:name, model_name])
34
+ end
35
+
36
+ def default_model_name
37
+ return model_name_for('Conducer') if self == Dao::Conducer
38
+ model_name_for(name.to_s.sub(/Conducer$/, '').sub(/(:|_)+$/, ''))
39
+ end
40
+
41
+ def collection_name
42
+ @collection_name ||= model_name.plural.to_s
43
+ end
44
+ alias_method('table_name', 'collection_name')
45
+
46
+ def collection_name=(collection_name)
47
+ @collection_name = collection_name.to_s
48
+ end
49
+ alias_method('set_collection_name', 'collection_name=')
50
+ alias_method('table_name=', 'collection_name=')
51
+ alias_method('set_table_name', 'collection_name=')
52
+ end
53
+
54
+ def persisted
55
+ !!(defined?(@persisted) ? @persisted : @model ? @model.persisted? : !id.blank?)
56
+ end
57
+ def persisted?
58
+ persisted
59
+ end
60
+ def persisted=(value)
61
+ @persisted = !!value
62
+ end
63
+ def persisted!
64
+ self.persisted = true
65
+ end
66
+
67
+ def new_record
68
+ !!(defined?(@new_record) ? @new_record : @model ? @model.new_record? : id.blank?)
69
+ end
70
+ def new_record?
71
+ new_record
72
+ end
73
+ def new_record=(value)
74
+ @new_record = !!value
75
+ end
76
+ def new_record!
77
+ self.new_record = true
78
+ end
79
+
80
+ def destroyed
81
+ !!(defined?(@destroyed) ? @destroyed : @model ? @model.destroyed : id.blank?)
82
+ end
83
+ def destroyed?
84
+ destroyed
85
+ end
86
+ def destroyed=(value)
87
+ @destroyed = !!value
88
+ end
89
+ def destroyed!
90
+ self.destroyed = true
91
+ end
92
+
93
+ def read_attribute_for_validation(key)
94
+ get(key)
95
+ end
96
+
97
+ end
98
+ end
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  module Dao
2
3
  class Conducer
3
4
  class Attributes < ::Map
@@ -0,0 +1,58 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Dao
3
+ class << Conducer
4
+ def autocrud!
5
+ include(Conducer::AutoCRUD)
6
+ end
7
+ alias_method('crud!', 'autocrud!')
8
+ end
9
+
10
+ class Conducer
11
+ module AutoCRUD
12
+ Code = proc do
13
+ class << self
14
+ def db
15
+ @db ||= Db.instance
16
+ end
17
+
18
+ def db_collection
19
+ db.collection(collection_name)
20
+ end
21
+
22
+ def all(*args)
23
+ hashes = db_collection.all()
24
+ hashes.map{|hash| new(hash)}
25
+ end
26
+
27
+ def find(*args)
28
+ options = args.extract_options!.to_options!
29
+ id = args.shift || options[:id]
30
+ hash = db_collection.find(id)
31
+ new(hash) if hash
32
+ end
33
+ end
34
+
35
+ def save
36
+ id = self.class.db_collection.save(@attributes)
37
+ @attributes.set(:id => id)
38
+ true
39
+ end
40
+
41
+ def destroy
42
+ id = self.id
43
+ if id
44
+ self.class.db_collection.destroy(id)
45
+ @attributes.rm(:id)
46
+ end
47
+ id
48
+ end
49
+ end
50
+
51
+ def AutoCRUD.included(other)
52
+ super
53
+ ensure
54
+ other.module_eval(&Code)
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,20 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Dao
3
+ class Conducer
4
+ CallbackSupport = proc do
5
+ include Wrap
6
+
7
+ class << self
8
+ def method_missing(method, *args, &block)
9
+ case method.to_s
10
+ when %r/\A(before|after)_(.*)\Z/
11
+ lifecycle, method = $1, $2
12
+ send(lifecycle, method, *args, &block)
13
+ else
14
+ super
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,45 @@
1
+ module Dao
2
+ class Conducer
3
+ class << Conducer
4
+ fattr(:collection_class)
5
+
6
+ def build_collection_class!
7
+ conducer_class = self
8
+ collection_class = const_set(:Collection, Class.new(Collection){})
9
+ collection_class.conducer_class = conducer_class
10
+ conducer_class.collection_class = collection_class
11
+ end
12
+
13
+ def collection_for(models, *args, &block)
14
+ collection_class.load(models, *args, &block)
15
+ end
16
+ end
17
+
18
+ class Collection < ::Array
19
+ class << Collection
20
+ fattr(:conducer_class)
21
+
22
+ def load(*args, &block)
23
+ new.tap{|collection| collection.load(*args, &block)}
24
+ end
25
+ end
26
+
27
+ fattr(:models)
28
+
29
+ def conducer_class
30
+ self.class.conducer_class
31
+ end
32
+
33
+ def load(models, *args, &block)
34
+ block ||= proc{|model| conducer_class.new(model, *args) }
35
+ (self.models = models).each{|model| self << block.call(model, *args)}
36
+ self
37
+ end
38
+
39
+ def method_missing(method, *args, &block)
40
+ return(models.send(method, *args, &block)) if models.respond_to?(method)
41
+ super
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,104 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Dao
3
+ class Conducer
4
+ ControllerSupport = proc do
5
+ ##
6
+ #
7
+ def controller
8
+ unless defined?(@controller)
9
+ set_controller(Conducer.controller)
10
+ end
11
+ @controller
12
+ end
13
+
14
+ def controller=(controller)
15
+ set_controller(controller)
16
+ end
17
+
18
+ def set_controller(controller)
19
+ @controller = controller
20
+ ensure
21
+ default_url_options[:protocol] = @controller.request.protocol
22
+ default_url_options[:host] = @controller.request.host
23
+ default_url_options[:port] = @controller.request.port
24
+ @action = Action.new(@controller.send(:action_name).to_s, self)
25
+ end
26
+
27
+ ##
28
+ #
29
+ class Action < ::String
30
+ fattr :conducer
31
+
32
+ def initialize(action, conducer = nil)
33
+ super(action.to_s.downcase.strip)
34
+ @conducer = conducer
35
+ end
36
+
37
+ def action
38
+ to_s
39
+ end
40
+
41
+ def ==(other)
42
+ super(other.to_s)
43
+ end
44
+
45
+ Synonyms = {
46
+ 'new' => 'create',
47
+ 'create' => 'new',
48
+
49
+ 'edit' => 'update',
50
+ 'update' => 'edit'
51
+ }
52
+
53
+ def call(method, *args, &block)
54
+ return unless conducer
55
+
56
+ action_method = "#{ method }_for_#{ action }"
57
+
58
+ return Dao.call(conducer, action_method, *args, &block) if conducer.respond_to?(action_method)
59
+
60
+ if((synonym = Synonyms[action]))
61
+ action_method = "#{ method }_for_#{ synonym }"
62
+ return Dao.call(conducer, action_method, *args, &block) if conducer.respond_to?(action_method)
63
+ end
64
+
65
+ nil
66
+ end
67
+ end
68
+
69
+ def action
70
+ unless defined?(@action)
71
+ set_action(:new)
72
+ end
73
+ @action
74
+ end
75
+
76
+ def set_action(action)
77
+ unless action.is_a?(Action)
78
+ action = Action.new(action)
79
+ end
80
+ action.conducer = self
81
+ @action = action
82
+ end
83
+
84
+ def action=(action)
85
+ set_action(action)
86
+ end
87
+
88
+ ##
89
+ #
90
+ controller_delegates = %w(
91
+ render
92
+ render_to_string
93
+ )
94
+
95
+ controller_delegates.each do |method|
96
+ module_eval <<-__, __FILE__, __LINE__
97
+ def #{ method }(*args, &block)
98
+ controller.#{ method }(*args, &block)
99
+ end
100
+ __
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,9 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Dao
3
+ class Conducer
4
+ def nav_for(name, &block)
5
+ Nav.new(name, &block).for(controller)
6
+ end
7
+ alias_method(:nav, :nav_for)
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Dao
3
+ class Conducer
4
+ ViewSupport = proc do
5
+ include Tagz.globally
6
+
7
+ class << Conducer
8
+ include Tagz.globally
9
+ end
10
+
11
+ url_helpers = Rails.application.try(:routes).try(:url_helpers)
12
+ include(url_helpers) if url_helpers
13
+ include(ActionView::Helpers) if defined?(ActionView::Helpers)
14
+ end
15
+ end
16
+ end
data/lib/dao/data.rb CHANGED
@@ -1,9 +1,10 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  module Dao
2
3
  class Data < ::Map
3
4
  # look good for inspect
4
5
  #
5
6
  def inspect
6
- ::JSON.pretty_generate(self, :max_nesting => 0)
7
+ Dao.json_for(self)
7
8
  end
8
9
 
9
10
  # support updates with dao-ish objects
data/lib/dao/db.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # -*- encoding : utf-8 -*-
2
+
1
3
  require 'yaml'
2
4
  require 'yaml/store'
3
5
  require 'fileutils'
data/lib/dao/endpoint.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  module Dao
2
3
  class Endpoint
3
4
  Attrs = %w( api path route block doc )
data/lib/dao/engine.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  module Dao
2
3
  if(defined?(Rails) && Rails::VERSION::MAJOR == 3)
3
4
  class Engine < Rails::Engine
data/lib/dao/errors.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  module Dao
2
3
  class Errors < ::Map
3
4
  # for html generation
@@ -18,23 +19,18 @@ module Dao
18
19
  # you can tweak these if you want
19
20
  #
20
21
  Global = '*' unless defined?(Global)
21
- #Separator = "\342\207\222" unless defined?(Separator) ### this is an "Open-outlined rightward arrow"
22
- Separator = ":" unless defined?(Separator)
22
+ Separator = "\342\207\222" unless defined?(Separator) ### this is an "Open-outlined rightward arrow"
23
+ #Separator = ":" unless defined?(Separator)
23
24
 
24
25
  # messages know when they're sticky
25
26
  #
26
27
  class Message < ::String
27
- attr_accessor :sticky
28
+ attr_accessor :source
28
29
 
29
30
  def initialize(*args)
30
31
  options = Map.options_for!(args)
31
32
  replace(args.join(' '))
32
- @sticky = options[:sticky]
33
- end
34
-
35
- def sticky?
36
- @sticky ||= nil
37
- !!@sticky
33
+ self.source = options[:source]
38
34
  end
39
35
 
40
36
  def to_s
@@ -58,94 +54,114 @@ module Dao
58
54
  @object = args.shift
59
55
  end
60
56
 
61
- def errors
62
- self
63
- end
64
-
65
57
  def [](key)
66
- self[key] = Array.new unless has_key?(key)
58
+ return [] unless has_key?(key)
67
59
  super
68
60
  end
69
61
 
62
+ def errors
63
+ self
64
+ end
65
+
70
66
  def size
71
67
  size = 0
72
- depth_first_each{|key, val| size += Array(val).size}
68
+ depth_first_each do |keys, value|
69
+ size += Array(value).size
70
+ end
73
71
  size
74
72
  end
75
73
  alias_method('count', 'size')
76
74
  alias_method('length', 'size')
77
75
 
76
+ def empty?
77
+ size == 0
78
+ end
79
+
78
80
  def add(*args)
81
+ return relay(args.first) if args.size == 1 and relay?(args.first)
79
82
  options = Map.options_for!(args)
80
- sticky = options[:sticky]
83
+
81
84
  clear = options[:clear]
85
+ source = options[:source]
82
86
 
83
87
  args.flatten!
84
- message = args.pop
85
- keys = args
86
- keys = [Global] if keys.empty?
87
- errors = Hash.new
88
88
 
89
- if Array(keys) == [Global]
90
- sticky = true unless options.has_key?(:sticky)
91
- end
89
+ message = args.pop or raise(ArgumentError, 'no message!')
90
+ key = args.empty? ? [Global] : args
92
91
 
93
- sticky = true if(message.respond_to?(:sticky?) and message.sticky?)
94
-
95
- if message
96
- if message.respond_to?(:full_messages)
97
- message.depth_first_each do |keys, msg|
98
- errors[keys] = Message.new(msg, :sticky => sticky)
92
+ if message.is_a?(Hash) or message.respond_to?(:full_messages)
93
+ message.each do |k, v|
94
+ Array(v).each do |msg|
95
+ add(key + [k], msg)
99
96
  end
100
- else
101
- errors[keys] = Message.new(message, :sticky => sticky)
102
97
  end
103
- else
104
- raise(ArgumentError, 'no message!')
98
+ return(self)
105
99
  end
106
100
 
107
- message = Message.new(message) unless message.is_a?(Message)
101
+ message = message.is_a?(Message) ? message : Message.new(message)
102
+ message.source = source
108
103
 
109
- result = []
104
+ set(key => []) unless has?(key)
105
+ list = get(key)
106
+ list.clear if clear
107
+ list.push(message)
108
+ list.uniq!
109
+ list
110
+ self
111
+ end
112
+ alias_method('add!', 'add')
113
+ alias_method('add_to_base', 'add')
114
+ alias_method('add_to_base!', 'add!')
110
115
 
111
- errors.each do |keys, message|
112
- list = get(keys)
113
- unless has?(keys)
114
- set(keys => [])
115
- list = get(keys)
116
- end
117
- list.clear if clear
118
- list.push(message)
119
- result = list
116
+ def relay(other, options = {})
117
+ case
118
+ when other.respond_to?(:each)
119
+ other.each do |key, messages|
120
+ Array(messages).each do |message|
121
+ add(key, message, options = {})
122
+ end
123
+ end
124
+ when other.respond_to?(:each_pair)
125
+ other.each_pair do |key, messages|
126
+ Array(messages).each do |message|
127
+ add(key, message, options = {})
128
+ end
129
+ end
130
+
131
+ when other.respond_to?(:each_slice)
132
+ Array(other).flatten.each_slice(2) do |key, messages|
133
+ Array(messages).each do |message|
134
+ add(key, message, options = {})
135
+ end
136
+ end
137
+
138
+ else
139
+ raise(ArgumentError, other.class.name)
120
140
  end
121
-
122
- result
141
+ self
123
142
  end
124
143
 
125
- alias_method('add_to_base', 'add')
126
-
127
- def add!(*args)
128
- options = Map.new(args.last.is_a?(Hash) ? args.last : {})
129
- options[:sticky] = true
130
- args.push(options)
131
- add(*args)
144
+ def relay?(arg)
145
+ [:each, :each_pair, :each_slice].any?{|method| arg.respond_to?(method)}
132
146
  end
133
147
 
134
- alias_method('add_to_base!', 'add!')
148
+ def add_from_source(keys, callback, message)
149
+ add(keys, message, :source => callback)
150
+ self
151
+ end
135
152
 
136
- alias_method('clear!', 'clear')
153
+ def delete_from_source(keys, callback)
154
+ if((messages = errors.on(keys)))
155
+ messages.delete_if{|m| m.respond_to?(:source) and m.source==callback}
156
+ rm(*keys) if messages.empty?
157
+ end
158
+ self
159
+ end
137
160
 
138
161
  def clear
139
- keep = []
140
- depth_first_each do |keys, message|
141
- index = keys.pop
142
- args = [keys, message].flatten
143
- keep.push(args) if message.sticky?
144
- end
145
- clear!
146
- ensure
147
- keep.each{|args| add!(*args)}
162
+ super
148
163
  end
164
+ alias_method('clear!', 'clear')
149
165
 
150
166
  def invalid?(*keys)
151
167
  has?(keys) and !get(keys).nil?
@@ -164,7 +180,6 @@ module Dao
164
180
  depth_first_each do |keys, value|
165
181
  index = keys.pop
166
182
  key = keys
167
- #key = keys.join('.')
168
183
  value = value.to_s
169
184
  next if value.strip.empty?
170
185
  if key == Global
@@ -217,41 +232,36 @@ module Dao
217
232
  errors = [error, *args].flatten.compact
218
233
 
219
234
  at_least_one_error = false
220
- css_class = options[:class] || 'errors dao'
221
-
222
- to_html =
223
- div_(:class => css_class){
224
- __
225
-
226
- div_(:class => :caption){ "We're so sorry, but can you please fix the following errors?" }
227
- __
228
-
229
- ul_{
230
- __
231
- errors.each do |e|
232
- e.full_messages.each do |key, message|
233
- at_least_one_error = true
234
- title = Array(key).join(' ').titleize
235
-
236
- error_class = Array(key)==Array(Global) ? "global-error" : "field-error"
237
- title_class = "title"
238
- separator_class = "separator"
239
- message_class = "message"
240
-
241
- li_(:class => error_class){
242
- span_(:class => title_class){ title }
243
- span_(:class => separator_class){ " #{ Separator } " }
244
- span_(:class => message_class){ message }
245
- }
246
- __
247
- end
248
- end
249
- __
250
- }
251
- __
252
- }
253
235
 
254
- at_least_one_error ? to_html : ''
236
+ emap = Map.new
237
+
238
+ errors.each do |e|
239
+ e.full_messages.each do |key, message|
240
+ at_least_one_error = true
241
+ emap[key] ||= message
242
+ end
243
+ end
244
+
245
+ return "" unless at_least_one_error
246
+
247
+ div_(:class => "dao errors summary"){
248
+ __
249
+
250
+ h3_(:class => "caption"){ "We're so sorry, but can you please fix the following errors?" }
251
+ __
252
+
253
+ dl_(:class => "list"){
254
+ emap.each do |key, message|
255
+ title = Array(key).join(" ").titleize
256
+
257
+ type = Array(key) == Array(Global) ? "global" : "field"
258
+
259
+ dt_(:class => "title #{ type }"){ title }
260
+ dd_(:class => "message #{ type }"){ message }
261
+ end
262
+ }
263
+ __
264
+ }
255
265
  end
256
266
 
257
267
  def to_s(*args, &block)