hobo 0.7.0 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/hobo_files/plugin/CHANGES.txt +220 -23
  2. data/hobo_files/plugin/generators/hobo_front_controller/templates/index.dryml +18 -25
  3. data/hobo_files/plugin/generators/hobo_migration/hobo_migration_generator.rb +20 -15
  4. data/hobo_files/plugin/generators/hobo_model/templates/model.rb +3 -3
  5. data/hobo_files/plugin/generators/hobo_rapid/hobo_rapid_generator.rb +3 -3
  6. data/hobo_files/plugin/generators/hobo_rapid/templates/hobo-rapid.css +1 -2
  7. data/hobo_files/plugin/generators/hobo_rapid/templates/hobo-rapid.js +21 -4
  8. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/images/fieldbg.gif +0 -0
  9. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/images/spinner.gif +0 -0
  10. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/stylesheets/application.css +154 -26
  11. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/stylesheets/rapid-ui.css +144 -0
  12. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/views/application.dryml +1 -1
  13. data/hobo_files/plugin/generators/hobo_user_controller/templates/controller.rb +1 -1
  14. data/hobo_files/plugin/generators/hobo_user_model/templates/model.rb +8 -11
  15. data/hobo_files/plugin/init.rb +0 -2
  16. data/hobo_files/plugin/lib/active_record/has_many_association.rb +0 -9
  17. data/hobo_files/plugin/lib/active_record/has_many_through_association.rb +0 -10
  18. data/hobo_files/plugin/lib/hobo.rb +57 -44
  19. data/hobo_files/plugin/lib/hobo/bundle.rb +222 -0
  20. data/hobo_files/plugin/lib/hobo/controller.rb +2 -5
  21. data/hobo_files/plugin/lib/hobo/dryml.rb +8 -7
  22. data/hobo_files/plugin/lib/hobo/dryml/dryml_builder.rb +10 -21
  23. data/hobo_files/plugin/lib/hobo/dryml/taglib.rb +107 -80
  24. data/hobo_files/plugin/lib/hobo/dryml/template.rb +27 -20
  25. data/hobo_files/plugin/lib/hobo/enum_string.rb +1 -1
  26. data/hobo_files/plugin/lib/hobo/field_declaration_dsl.rb +7 -0
  27. data/hobo_files/plugin/lib/hobo/guest.rb +4 -0
  28. data/hobo_files/plugin/lib/hobo/hobo_helper.rb +37 -9
  29. data/hobo_files/plugin/lib/hobo/model.rb +79 -17
  30. data/hobo_files/plugin/lib/hobo/model_controller.rb +59 -60
  31. data/hobo_files/plugin/lib/hobo/model_router.rb +16 -4
  32. data/hobo_files/plugin/lib/hobo/rapid_helper.rb +2 -1
  33. data/hobo_files/plugin/lib/hobo/user.rb +10 -7
  34. data/hobo_files/plugin/lib/hobo/user_controller.rb +6 -6
  35. data/hobo_files/plugin/{tags → taglibs}/core.dryml +5 -4
  36. data/hobo_files/plugin/{tags → taglibs}/rapid.dryml +54 -7
  37. data/hobo_files/plugin/{tags → taglibs}/rapid_document_tags.dryml +0 -0
  38. data/hobo_files/plugin/{tags → taglibs}/rapid_editing.dryml +4 -2
  39. data/hobo_files/plugin/{tags → taglibs}/rapid_forms.dryml +1 -4
  40. data/hobo_files/plugin/{tags → taglibs}/rapid_navigation.dryml +1 -2
  41. data/hobo_files/plugin/taglibs/rapid_pages.dryml +411 -0
  42. data/hobo_files/plugin/{tags → taglibs}/rapid_plus.dryml +0 -0
  43. data/hobo_files/plugin/{tags → taglibs}/rapid_support.dryml +9 -6
  44. data/hobo_files/plugin/tasks/fix_dryml.rake +0 -1
  45. metadata +16 -14
  46. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/stylesheets/rapid_ui.css +0 -167
  47. data/hobo_files/plugin/lib/hobo/plugins.rb +0 -75
  48. data/hobo_files/plugin/tags/rapid_pages.dryml +0 -341
@@ -64,7 +64,7 @@ module Hobo::Dryml
64
64
 
65
65
  def build(local_names, auto_taglibs)
66
66
 
67
- auto_taglibs.each{|t| import_taglib(t)}
67
+ auto_taglibs.each { |t| import_taglib(t) }
68
68
 
69
69
  @build_instructions.each do |instruction|
70
70
  name = instruction[:name]
@@ -82,7 +82,7 @@ module Hobo::Dryml
82
82
  @environment.class_eval(method_src, template_path, instruction[:line_num])
83
83
 
84
84
  when :include
85
- import_taglib(name, instruction[:as])
85
+ import_taglib(instruction)
86
86
 
87
87
  when :module
88
88
  import_module(name.constantize, instruction[:as])
@@ -102,24 +102,13 @@ module Hobo::Dryml
102
102
  end
103
103
 
104
104
 
105
- def expand_template_path(path)
106
- base = if path.starts_with? "plugins"
107
- "vendor/" + path
108
- elsif path.include?("/")
109
- "app/views/#{path}"
110
- else
111
- template_dir = File.dirname(template_path)
112
- "#{template_dir}/#{path}"
113
- end
114
- base + ".dryml"
115
- end
116
-
117
-
118
- def import_taglib(src_path, as=nil)
119
- path = expand_template_path(src_path)
120
- unless template_path == path
121
- taglib = Taglib.get(RAILS_ROOT + (path.starts_with?("/") ? path : "/" + path))
122
- taglib.import_into(@environment, as)
105
+ def import_taglib(options)
106
+ if options[:module]
107
+ import_module(options[:module].constantize, options[:as])
108
+ else
109
+ template_dir = File.dirname(template_path)
110
+ taglib = Taglib.get(options.merge(:template_dir => template_dir))
111
+ taglib.import_into(@environment, options[:as])
123
112
  end
124
113
  end
125
114
 
@@ -133,7 +122,7 @@ module Hobo::Dryml
133
122
  def set_theme(name)
134
123
  if Hobo.current_theme.nil? or Hobo.current_theme == name
135
124
  Hobo.current_theme = name
136
- import_taglib("taglibs/themes/#{name}/application")
125
+ import_taglib(:src => "taglibs/themes/#{name}/application")
137
126
  end
138
127
  end
139
128
  end
@@ -1,95 +1,122 @@
1
- module Hobo::Dryml
1
+ module Hobo
2
+
3
+ module Dryml
2
4
 
3
- class Taglib
4
-
5
- @cache = {}
6
-
7
- class << self
8
-
9
- def get(path)
10
- raise DrymlException, "No such taglib: #{path}" unless File.exists?(path)
11
- file = File.new(path)
12
-
13
- taglib = @cache[file.path]
14
- if taglib
15
- taglib.reload
16
- else
17
- taglib = Taglib.new(file)
18
- @cache[file.path] = taglib
5
+ class Taglib
6
+
7
+ @cache = {}
8
+
9
+ class << self
10
+
11
+ def get(options)
12
+ file = taglib_file(options)
13
+
14
+ taglib = @cache[options]
15
+ if taglib
16
+ taglib.reload
17
+ else
18
+ renames = (bundle = options[:bundle] and
19
+ Bundle.bundles[bundle]._?.renames)
20
+
21
+ taglib = Taglib.new(file, renames)
22
+ @cache[options] = taglib
23
+ end
24
+ taglib
19
25
  end
20
- taglib
21
- end
22
-
23
- def clear_cache
24
- @cache = {}
25
- end
26
-
27
- end
28
-
29
- def initialize(file)
30
- @file = file
31
- load
32
- end
33
-
34
- def reload
35
- load if @file.mtime > @last_load_time
36
- end
37
-
38
- def load
39
- @module = Module.new do
40
26
 
41
- @tag_attrs = {}
42
- @tag_aliases = {}
27
+ def clear_cache
28
+ @cache = {}
29
+ end
30
+
31
+ private
43
32
 
44
- class << self
33
+ def taglib_file(options)
34
+ base = if (plugin = options[:plugin])
35
+ "vendor/plugins/#{plugin}/taglibs"
36
+ elsif (bundle_name = options[:bundle])
37
+ bundle = Bundle.bundles[bundle_name]
38
+ "vendor/plugins/#{bundle.plugin}/taglibs"
39
+ elsif options[:src] =~ /\//
40
+ "app/views"
41
+ else
42
+ options[:template_dir]
43
+ end
45
44
 
46
- def included(base)
47
- @tag_aliases.each do |tag, feature|
48
- base.send(:alias_method_chain, tag, feature)
49
- end
50
- end
51
-
52
- def _register_tag_attrs(tag, attrs)
53
- @tag_attrs[tag] = attrs
54
- end
55
- attr_reader :tag_attrs
45
+ filename = "#{RAILS_ROOT}/#{base}/#{options[:src]}.dryml"
46
+ raise DrymlException, "No such taglib: #{options.inspect} #{filename}" unless File.exists?(filename)
47
+ File.new(filename)
48
+ end
49
+
50
+ end
51
+
52
+ def initialize(file, renames)
53
+ @file = file
54
+ @renames = renames
55
+ load
56
+ end
57
+
58
+ def reload
59
+ load if @file.mtime > @last_load_time
60
+ end
61
+
62
+ def load
63
+ @module = Module.new do
64
+
65
+ @tag_attrs = {}
66
+ @tag_aliases = {}
56
67
 
57
- def delayed_alias_method_chain(tag, feature)
58
- @tag_aliases[tag] = feature
68
+ class << self
69
+
70
+ def included(base)
71
+ @tag_aliases.each do |tag, feature|
72
+ base.send(:alias_method_chain, tag, feature)
73
+ end
74
+ end
75
+
76
+ def _register_tag_attrs(tag, attrs)
77
+ @tag_attrs[tag] = attrs
78
+ end
79
+ attr_reader :tag_attrs
80
+
81
+ def delayed_alias_method_chain(tag, feature)
82
+ @tag_aliases[tag] = feature
83
+ end
84
+
59
85
  end
60
86
 
61
87
  end
62
-
88
+ @file.rewind
89
+ template = Template.new(@file.read, @module, @file.path, @renames)
90
+ template.compile([], [])
91
+ @last_load_time = @file.mtime
63
92
  end
64
- @file.rewind
65
- template = Template.new(@file.read, @module, @file.path)
66
- template.compile([], [])
67
- @last_load_time = @file.mtime
68
- end
69
-
70
- def import_into(class_or_module, as)
71
- if as
72
- # Define a method on class_or_module named whatever 'as'
73
- # is. The first time the method is called it creates and
74
- # returns an object that provides the taglib's tags as
75
- # methods. On subsequent calls the object is cached in an
76
- # instance variable "@_#{as}_taglib"
77
-
78
- taglib_module = @module
79
- ivar = "@_#{as}_taglib"
80
- class_or_module.send(:define_method, as) do
81
- instance_variable_get(ivar) or begin
82
- as_class = Class.new(TemplateEnvironment) { include taglib_module }
83
- as_object = as_class.new
84
- as_object.copy_instance_variables_from(self)
85
- instance_variable_set(ivar, as_object)
86
- end
93
+
94
+ def import_into(class_or_module, as)
95
+ if as
96
+ # Define a method on class_or_module named whatever 'as'
97
+ # is. The first time the method is called it creates and
98
+ # returns an object that provides the taglib's tags as
99
+ # methods. On subsequent calls the object is cached in an
100
+ # instance variable "@_#{as}_taglib"
101
+
102
+ taglib_module = @module
103
+ ivar = "@_#{as}_taglib"
104
+ class_or_module.send(:define_method, as) do
105
+ instance_variable_get(ivar) or begin
106
+ as_class = Class.new(TemplateEnvironment) { include taglib_module }
107
+ as_object = as_class.new
108
+ as_object.copy_instance_variables_from(self)
109
+ instance_variable_set(ivar, as_object)
110
+ end
111
+ end
112
+ else
113
+ class_or_module.send(:include, @module)
114
+ class_or_module.tag_attrs.update(@module.tag_attrs) if @module.respond_to?(:tag_attrs)
87
115
  end
88
- else
89
- class_or_module.send(:include, @module)
90
- class_or_module.tag_attrs.update(@module.tag_attrs) if @module.respond_to?(:tag_attrs)
91
116
  end
117
+
92
118
  end
93
-
119
+
94
120
  end
121
+
95
122
  end
@@ -28,12 +28,11 @@ module Hobo::Dryml
28
28
  end
29
29
  end
30
30
 
31
- def initialize(src, environment, template_path)
31
+ def initialize(src, environment, template_path, renames={})
32
32
  @src = src
33
-
34
33
  @environment = environment # a class or a module
35
-
36
34
  @template_path = template_path.sub(/^#{Regexp.escape(RAILS_ROOT)}/, "")
35
+ @class_renames = renames
37
36
 
38
37
  @builder = Template.build_cache[@template_path] || DRYMLBuilder.new(@template_path)
39
38
  @builder.set_environment(environment)
@@ -41,7 +40,7 @@ module Hobo::Dryml
41
40
  @last_element = nil
42
41
  end
43
42
 
44
- attr_reader :tags, :template_path
43
+ attr_reader :tags, :template_path, :class_renames
45
44
 
46
45
  def compile(local_names=[], auto_taglibs=[])
47
46
  now = Time.now
@@ -144,7 +143,8 @@ module Hobo::Dryml
144
143
 
145
144
  when "include"
146
145
  include_element(el)
147
- # return nothing - the include has no presence in the erb source
146
+ # return just the newlines to keep line-number matching - the
147
+ # include has no presence in the erb source
148
148
  tag_newlines(el)
149
149
 
150
150
  when "set-theme"
@@ -179,15 +179,11 @@ module Hobo::Dryml
179
179
  def include_element(el)
180
180
  require_toplevel(el)
181
181
  require_attribute(el, "as", /^#{DRYML_NAME}$/, true)
182
- if el.attributes["src"]
183
- @builder.add_build_instruction(:include,
184
- :name => el.attributes["src"],
185
- :as => el.attributes["as"])
186
- elsif el.attributes["module"]
187
- @builder.add_build_instruction(:module,
188
- :name => el.attributes["module"],
189
- :as => el.attributes["as"])
182
+ options = {}
183
+ %w(src module plugin bundle as).each do |attr|
184
+ options[attr.to_sym] = el.attributes[attr] if el.attributes[attr]
190
185
  end
186
+ @builder.add_build_instruction(:include, options)
191
187
  end
192
188
 
193
189
 
@@ -247,9 +243,12 @@ module Hobo::Dryml
247
243
  unsafe_name = el.attributes["tag"]
248
244
  name = Hobo::Dryml.unreserve(unsafe_name)
249
245
  if (for_type = el.attributes['for'])
250
- type_name = if for_type =~ /^[a-z]/
246
+ type_name = case for_type
247
+ when /^[a-z]/
251
248
  # It's a symbolic type name - look up the Ruby type name
252
249
  Hobo.field_types[for_type].name
250
+ when /^_.*_$/
251
+ rename_class(for_type)
253
252
  else
254
253
  for_type
255
254
  end.underscore.gsub('/', '__')
@@ -420,9 +419,9 @@ module Hobo::Dryml
420
419
  # holding a proc
421
420
  param_restore_local_name(name)
422
421
  elsif (call_type = polymorphic_call_type(el))
423
- "find_polymorphic_tag(:#{name.underscore}, #{call_type})"
422
+ "find_polymorphic_tag(:#{ruby_name name}, #{call_type})"
424
423
  else
425
- ":#{name.underscore}"
424
+ ":#{ruby_name name}"
426
425
  end
427
426
  "call_tag_parameter(#{to_call}, #{args})"
428
427
  else
@@ -430,9 +429,11 @@ module Hobo::Dryml
430
429
  # The tag is a proc available in a local variable
431
430
  "#{param_restore_local_name(name)}.call(#{attributes}, #{parameters})"
432
431
  elsif (call_type = polymorphic_call_type(el))
433
- "send(find_polymorphic_tag(:#{name.underscore}, #{call_type}), #{attributes}, #{parameters})"
432
+ "send(find_polymorphic_tag(:#{ruby_name name}, #{call_type}), #{attributes}, #{parameters})"
433
+ elsif attributes == "{}" && parameters == "{}"
434
+ "#{ruby_name name}.to_s"
434
435
  else
435
- "#{name.underscore}(#{attributes}, #{parameters})"
436
+ "#{ruby_name name}(#{attributes}, #{parameters})"
436
437
  end
437
438
  end
438
439
 
@@ -524,7 +525,7 @@ module Hobo::Dryml
524
525
 
525
526
 
526
527
  def param_restore_local_name(name)
527
- "_#{name.underscore}_restore"
528
+ "_#{ruby_name name}_restore"
528
529
  end
529
530
 
530
531
 
@@ -549,7 +550,7 @@ module Hobo::Dryml
549
550
 
550
551
 
551
552
  def param_content_local_name(name)
552
- "_#{name.underscore}__default_content"
553
+ "_#{ruby_name name}__default_content"
553
554
  end
554
555
 
555
556
 
@@ -767,6 +768,12 @@ module Hobo::Dryml
767
768
  @gensym_counter += 1
768
769
  "#{name}_#{@gensym_counter}"
769
770
  end
771
+
772
+ def rename_class(name)
773
+ name = name[1..-2]
774
+ name = class_renames[name] while class_renames.has_key?(name)
775
+ name
776
+ end
770
777
 
771
778
  end
772
779
 
@@ -31,7 +31,7 @@ module Hobo
31
31
  end
32
32
 
33
33
  def inspect
34
- "#<EnumString #{(values || []) * ' '}>"
34
+ name.blank? ? "#<EnumString #{(values || []) * ' '}>" : name
35
35
  end
36
36
  alias_method :to_s, :inspect
37
37
 
@@ -16,6 +16,13 @@ module Hobo
16
16
  def field(name, *args)
17
17
  type = args.shift
18
18
  options = args.extract_options!
19
+
20
+ @model.name_attribute = name.to_sym if options.delete(:name)
21
+ @model.primary_content_attribute = name.to_sym if options.delete(:description)
22
+ @model.creator_attribute = name.to_sym if options.delete(:creator)
23
+
24
+ @model.send(:login_attribute=, name.to_sym, options.delete(:validate)) if @model < User && options.delete(:login)
25
+
19
26
  @model.send(:set_field_type, name => type) unless
20
27
  type.in?(@model.connection.native_database_types.keys - [:text])
21
28
  @model.field_specs[name] = FieldSpec.new(@model, name, type, options)
@@ -15,6 +15,10 @@ module Hobo
15
15
  def super_user?
16
16
  false
17
17
  end
18
+
19
+ def administrator?
20
+ false
21
+ end
18
22
 
19
23
  end
20
24
 
@@ -54,8 +54,8 @@ module Hobo
54
54
  # TODO - what if you want if_available as a query param?
55
55
  if_available = params.delete(:if_available)
56
56
  return nil if if_available &&
57
- ((action.nil? && obj.respond_to?(:typed_id) && !linkable?(obj.class, :show, subsite)) ||
58
- (action.nil? && obj.is_a?(Class) && !linkable?(obj, :index, subsite)))
57
+ ((action.nil? && obj.respond_to?(:typed_id) && !linkable?(obj.class, :show, :subsite => subsite)) ||
58
+ (action.nil? && obj.is_a?(Class) && !linkable?(obj, :index, :subsite => subsite)))
59
59
 
60
60
  base = subsite.blank? ? base_url : "/#{subsite}#{base_url}"
61
61
 
@@ -195,7 +195,11 @@ module Hobo
195
195
 
196
196
  def can_edit?(*args)
197
197
  if args.empty?
198
- this_parent && this_field && can_edit?(this_parent, this_field)
198
+ if this_parent && this_field
199
+ can_edit?(this_parent, this_field)
200
+ else
201
+ can_edit?(this, nil)
202
+ end
199
203
  else
200
204
  object, field = args.length == 2 ? args : [this, args.first]
201
205
 
@@ -300,10 +304,11 @@ module Hobo
300
304
  end
301
305
 
302
306
 
303
- def create_model(model)
304
- n = model.new
305
- n.set_creator(current_user)
306
- n
307
+ def new_for_current_user(model_or_assoc=nil)
308
+ model_or_assoc ||= this
309
+ record = model_or_assoc.new
310
+ record.set_creator(current_user)
311
+ record
307
312
  end
308
313
 
309
314
 
@@ -356,11 +361,34 @@ module Hobo
356
361
  end
357
362
  end
358
363
 
359
- def linkable?(obj, action, subsite=self.subsite)
360
- Hobo::ModelRouter.linkable?(subsite, obj, action)
364
+ def linkable?(*args)
365
+ options = args.extract_options!
366
+ target = args.empty? || args.first.is_a?(Symbol) ? this : args.shift
367
+ action = args.first
368
+
369
+ if target.is_a?(Class)
370
+ klass = target
371
+ action ||= :index
372
+ elsif target.respond_to?(:member_class)
373
+ klass = target.member_class
374
+ action ||= :show
375
+ else
376
+ klass = target.class
377
+ action ||= :show
378
+ end
379
+
380
+ Hobo::ModelRouter.linkable?(subsite, klass, action.to_sym)
361
381
  end
362
382
 
363
383
 
384
+ # Convenience helper for the default app
385
+
386
+ def front_models
387
+ Hobo.models.select {|m| linkable?(m) && !(m < Hobo::User)}
388
+ end
389
+
390
+
391
+
364
392
  # debugging support
365
393
 
366
394
  def abort_with(*args)