hobo 0.8.10 → 0.9.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.
- data/CHANGES.txt +126 -2
- data/Rakefile +4 -1
- data/bin/hobo +1 -1
- data/doctest/scopes.rdoctest +11 -4
- data/dryml_generators/rapid/cards.dryml.erb +8 -2
- data/dryml_generators/rapid/forms.dryml.erb +5 -4
- data/dryml_generators/rapid/pages.dryml.erb +150 -65
- data/lib/hobo.rb +1 -1
- data/lib/hobo/accessible_associations.rb +2 -0
- data/lib/hobo/authentication_support.rb +1 -1
- data/lib/hobo/controller.rb +11 -3
- data/lib/hobo/dryml/dryml_doc.rb +1 -1
- data/lib/hobo/fake_initializer.rb +14 -0
- data/lib/hobo/hobo_helper.rb +94 -6
- data/lib/hobo/lifecycles.rb +17 -2
- data/lib/hobo/lifecycles/lifecycle.rb +1 -1
- data/lib/hobo/lifecycles/transition.rb +12 -4
- data/lib/hobo/model.rb +25 -22
- data/lib/hobo/model_controller.rb +42 -37
- data/lib/hobo/model_router.rb +11 -7
- data/lib/hobo/permissions.rb +12 -10
- data/lib/hobo/permissions/associations.rb +1 -1
- data/lib/hobo/static_tags +21 -0
- data/lib/hobo/user.rb +7 -3
- data/lib/hobo/user_controller.rb +7 -7
- data/lib/hobo/view_hints.rb +10 -3
- data/rails_generators/hobo/USAGE +4 -0
- data/rails_generators/hobo_admin_site/USAGE +16 -0
- data/rails_generators/hobo_front_controller/hobo_front_controller_generator.rb +11 -2
- data/rails_generators/hobo_front_controller/templates/controller.rb +6 -0
- data/rails_generators/hobo_front_controller/templates/summary.dryml +103 -0
- data/rails_generators/hobo_model_resource/USAGE +38 -0
- data/rails_generators/hobo_rapid/USAGE +3 -0
- data/rails_generators/hobo_rapid/templates/hobo-rapid.js +7 -3
- data/rails_generators/hobo_rapid/templates/themes/clean/public/stylesheets/clean.css +4 -0
- data/rails_generators/hobo_rapid/templates/themes/clean/public/stylesheets/rapid-ui.css +5 -0
- data/rails_generators/hobo_subsite/USAGE +16 -0
- data/rails_generators/hobo_subsite/hobo_subsite_generator.rb +1 -1
- data/rails_generators/hobo_user_controller/templates/controller.rb +2 -2
- data/rails_generators/hobo_user_model/templates/model.rb +6 -1
- data/taglibs/rapid.dryml +1 -0
- data/taglibs/rapid_core.dryml +4 -4
- data/taglibs/rapid_forms.dryml +29 -21
- data/taglibs/rapid_generics.dryml +3 -1
- data/taglibs/rapid_lifecycles.dryml +14 -9
- data/taglibs/rapid_navigation.dryml +1 -1
- data/taglibs/rapid_plus.dryml +1 -0
- data/taglibs/rapid_summary.dryml +300 -0
- data/taglibs/rapid_support.dryml +1 -1
- data/taglibs/rapid_user_pages.dryml +21 -19
- data/test/permissions/test_permissions.rb +1 -1
- metadata +12 -4
data/lib/hobo.rb
CHANGED
@@ -26,6 +26,8 @@ module Hobo
|
|
26
26
|
|
27
27
|
def find_or_create_and_update(owner, association_name, finder, record_hash_or_string)
|
28
28
|
if record_hash_or_string.is_a?(String)
|
29
|
+
return nil if record_hash_or_string.blank?
|
30
|
+
|
29
31
|
# An ID or a name - the passed block will find the record
|
30
32
|
record = find_by_name_or_id(finder, record_hash_or_string)
|
31
33
|
|
@@ -67,7 +67,7 @@ module Hobo
|
|
67
67
|
accepts.xml do
|
68
68
|
headers["Status"] = "Unauthorized"
|
69
69
|
headers["WWW-Authenticate"] = %(Basic realm="Web Password")
|
70
|
-
render :text => "Couldn't authenticate you", :status => '401 Unauthorized'
|
70
|
+
render :text => ht("hobo.messages.unauthenticated", :default=>["Couldn't authenticate you"], :status => '401 Unauthorized')
|
71
71
|
end
|
72
72
|
end
|
73
73
|
false
|
data/lib/hobo/controller.rb
CHANGED
@@ -23,6 +23,7 @@ module Hobo
|
|
23
23
|
Thread.current['Hobo.current_controller'] = nil # should avoid memory-leakage
|
24
24
|
end
|
25
25
|
@included_taglibs = []
|
26
|
+
rescue_from ActionController::RoutingError, :with => :not_found
|
26
27
|
end
|
27
28
|
Hobo::HoboHelper.add_to_controller(klass)
|
28
29
|
end
|
@@ -108,9 +109,10 @@ module Hobo
|
|
108
109
|
|
109
110
|
def render_tags(objects, tag, options={})
|
110
111
|
for_type = options.delete(:for_type)
|
112
|
+
base_tag = tag
|
111
113
|
|
112
114
|
results = objects.map do |o|
|
113
|
-
tag = tag_renderer.find_polymorphic_tag(
|
115
|
+
tag = tag_renderer.find_polymorphic_tag(base_tag, o.class) if for_type
|
114
116
|
tag_renderer.send(tag, options.merge(:with => o))
|
115
117
|
end.join
|
116
118
|
|
@@ -154,8 +156,14 @@ module Hobo
|
|
154
156
|
request.env['HTTP_CACHE_CONTROL'] =~ /max-age=\s*0/
|
155
157
|
end
|
156
158
|
|
157
|
-
def not_found
|
158
|
-
|
159
|
+
def not_found(error)
|
160
|
+
if "not_found_response".in?(self.class.superclass.instance_methods)
|
161
|
+
super
|
162
|
+
elsif render_tag("not-found-page", {}, :status => 404)
|
163
|
+
# cool
|
164
|
+
else
|
165
|
+
render(:text => ht(:"hobo.messages.not_found", :default=>["The page you requested cannot be found."]) , :status => 404)
|
166
|
+
end
|
159
167
|
end
|
160
168
|
|
161
169
|
end
|
data/lib/hobo/dryml/dryml_doc.rb
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
# really what we want is a reference to the Initializer used in
|
2
|
+
# config/boot.rb. But since we can't monkey patch that file, we'll
|
3
|
+
# use a fake instead.
|
4
|
+
|
5
|
+
# this is used by the rapid_summary tag with_plugins
|
6
|
+
module Hobo
|
7
|
+
class FakeInitializer
|
8
|
+
attr_reader :configuration
|
9
|
+
|
10
|
+
def initialize(config = Rails.configuration)
|
11
|
+
@configuration = config
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/hobo/hobo_helper.rb
CHANGED
@@ -45,7 +45,7 @@ module Hobo
|
|
45
45
|
|
46
46
|
|
47
47
|
def subsite
|
48
|
-
params[:controller].match(/([^\/]+)\//)._?[1]
|
48
|
+
params[:controller]._?.match(/([^\/]+)\//)._?[1]
|
49
49
|
end
|
50
50
|
|
51
51
|
|
@@ -192,12 +192,20 @@ module Hobo
|
|
192
192
|
|
193
193
|
|
194
194
|
def first_item?
|
195
|
-
|
195
|
+
if scope.repeat_collection.respond_to? :each_pair
|
196
|
+
this == scope.repeat_collection.first.try.last
|
197
|
+
else
|
198
|
+
this == scope.repeat_collection.first
|
199
|
+
end
|
196
200
|
end
|
197
201
|
|
198
202
|
|
199
203
|
def last_item?
|
200
|
-
|
204
|
+
if scope.repeat_collection.respond_to? :each_pair
|
205
|
+
this == scope.repeat_collection.last.try.last
|
206
|
+
else
|
207
|
+
this == scope.repeat_collection.last
|
208
|
+
end
|
201
209
|
end
|
202
210
|
|
203
211
|
|
@@ -476,12 +484,16 @@ module Hobo
|
|
476
484
|
|
477
485
|
# --- ViewHint Helpers --- #
|
478
486
|
|
479
|
-
def this_field_name
|
480
|
-
this_parent.class.try.
|
487
|
+
def this_field_name
|
488
|
+
key = "#{this_parent.class.try.name.underscore}.#{this_field.to_s}"
|
489
|
+
default = this_parent.class.try.view_hints.try.field_name(this_field) || this_field
|
490
|
+
I18n.t(key, :default => default, :scope => [:activerecord, :attributes], :count => 1)
|
481
491
|
end
|
482
492
|
|
483
493
|
def this_field_help
|
484
|
-
this_parent.class.try.
|
494
|
+
key = "#{this_parent.class.try.name.pluralize.underscore}.hints.#{this_field.to_s}"
|
495
|
+
default = this_parent.class.try.view_hints.try.field_help[this_field.to_sym] || ""
|
496
|
+
I18n.t(key,:default=>default)
|
485
497
|
end
|
486
498
|
|
487
499
|
|
@@ -499,6 +511,82 @@ module Hobo
|
|
499
511
|
logger.debug("###################\n")
|
500
512
|
args.first unless args.empty?
|
501
513
|
end
|
514
|
+
|
515
|
+
# --- Translation Helper --- #
|
516
|
+
#
|
517
|
+
# Uses RoR native I18n.translate.
|
518
|
+
#
|
519
|
+
# Adds some conventions for easier hobo translation.
|
520
|
+
# 1. Assumes the first part of the key to be a model name (e.g.: users.index.title -> user)
|
521
|
+
# 2. Tries to translate the model by lookup for: (e.g.: user-> activerecord.models.user)
|
522
|
+
# 3. Adds a default fallback to the beginning of the fallback chain
|
523
|
+
# by replacing the first part of the key with "hobo" and using the translated model name
|
524
|
+
# as additional attribute. This allows us to have default translations
|
525
|
+
# (e.g.: hobo.index.title: "{{model}} Index")
|
526
|
+
#
|
527
|
+
# Is also used as a tag in the dryml-view files. The syntax is:
|
528
|
+
# <ht key="my.app">My Application</ht>
|
529
|
+
# --> Will lookup the "my.app"-key for your locale and replaces the "My Application" content
|
530
|
+
# if found.
|
531
|
+
#
|
532
|
+
# <ht key="my" app="Program">My Application</ht>
|
533
|
+
# --> Will look up both the "my"- and "app"-key for your locale, and replaces the
|
534
|
+
# "My Application" with the "my"-key contents (interpolated using the "app"-key.
|
535
|
+
# sample.en.yml-file:
|
536
|
+
# "no":
|
537
|
+
# my: "Mitt {{app}}"
|
538
|
+
# The output should be: Mitt Program
|
539
|
+
#
|
540
|
+
# Otherwise with features as the ht method, step 1, 2 and 3 above.
|
541
|
+
def ht(key, options={})
|
542
|
+
|
543
|
+
# Check if called as a tag, i.e. like this <ht></ht>
|
544
|
+
if (key.class == Hash)
|
545
|
+
if key.has_key?(:default) && !key[:default].blank?
|
546
|
+
logger.warn "hobo-i18n: 'default' should not be used as an attribute on the ht-tag. If used, then you need to make sure that the tags inner-contents are not used. These are normally treated as defaults automatically, but if there is a default attribute then that inner-content will be hidden from this method - and will not be replaced with the translation found."
|
547
|
+
end
|
548
|
+
defaults = options[:default];
|
549
|
+
# Swap key and options, remove options[:key]
|
550
|
+
options = key
|
551
|
+
key = options.delete(:key) # returns value for options[:key] as well as deleting it
|
552
|
+
# Set options[:default] to complete the tag-argument-conversion process.
|
553
|
+
options[:default] = (defaults.class == Proc) ? [defaults.call(options)] : (options[:default].blank? ? [] : [options[:default]])
|
554
|
+
else
|
555
|
+
# Not called as a tag. Prepare options[:default].
|
556
|
+
if options[:default].blank?
|
557
|
+
options[:default]=[]
|
558
|
+
elsif options[:default].class != Array
|
559
|
+
options[:default] = [options[:default]]
|
560
|
+
end
|
561
|
+
end
|
562
|
+
|
563
|
+
# assume the first part of the key to be the model
|
564
|
+
keys = key.to_s.split(".")
|
565
|
+
if keys.length > 1
|
566
|
+
model = keys.shift()
|
567
|
+
subkey = keys.join(".")
|
568
|
+
else
|
569
|
+
subkey = key
|
570
|
+
end
|
571
|
+
|
572
|
+
# add :"hobo.#{key}" as the first fallback
|
573
|
+
options[:default].unshift("hobo.#{subkey}".to_sym)
|
574
|
+
|
575
|
+
# translate the model
|
576
|
+
unless model.blank?
|
577
|
+
translated_model = I18n.translate( "activerecord.models.#{model.singularize.underscore}", :default=>model).titleize
|
578
|
+
options[:model] = translated_model
|
579
|
+
end
|
580
|
+
|
581
|
+
begin
|
582
|
+
key_prefix = "<span class='translation-key'>#{key}</span>" if HOBO_SHOW_LOCALE_KEYS
|
583
|
+
rescue
|
584
|
+
puts "Set HOBO_SHOW_LOCALE_KEYS=true in your environment to get all locale keys displayed"
|
585
|
+
end
|
586
|
+
|
587
|
+
logger.info "..translate(#{key}, #{options.inspect}) to #{I18n.locale}"
|
588
|
+
I18n.translate(key.to_sym, options)+(key_prefix ? key_prefix:"")
|
589
|
+
end
|
502
590
|
|
503
591
|
end
|
504
592
|
|
data/lib/hobo/lifecycles.rb
CHANGED
@@ -20,7 +20,9 @@ module Hobo
|
|
20
20
|
:key_timestamp_field => :key_timestamp,
|
21
21
|
:key_timeout => 999.years)
|
22
22
|
|
23
|
-
|
23
|
+
# use const_defined so that subclasses can define lifecycles
|
24
|
+
# TODO: figure out how to merge with parent, if desired
|
25
|
+
if self.const_defined?(:Lifecycle)
|
24
26
|
lifecycle = self::Lifecycle
|
25
27
|
else
|
26
28
|
# First call
|
@@ -35,6 +37,10 @@ module Hobo
|
|
35
37
|
|
36
38
|
default = lifecycle.default_state ? { :default => lifecycle.default_state.name.to_s } : {}
|
37
39
|
declare_field(options[:state_field], :string, default)
|
40
|
+
unless options[:index] == false
|
41
|
+
index_options = { :name => options[:index] } unless options[:index] == true
|
42
|
+
index(options[:state_field], index_options || {})
|
43
|
+
end
|
38
44
|
never_show options[:state_field]
|
39
45
|
attr_protected options[:state_field]
|
40
46
|
|
@@ -76,7 +82,16 @@ module Hobo
|
|
76
82
|
|
77
83
|
|
78
84
|
def lifecycle
|
79
|
-
@lifecycle ||= self.class::Lifecycle
|
85
|
+
@lifecycle ||= if defined? self.class::Lifecycle
|
86
|
+
self.class::Lifecycle.new(self)
|
87
|
+
else
|
88
|
+
# search through superclasses
|
89
|
+
current = self.class.superclass
|
90
|
+
until (defined?(current::Lifecycle) || current.nil? || !current.respond_to?(:lifecycle)) do
|
91
|
+
current = current.superclass
|
92
|
+
end
|
93
|
+
current.class::Lifecycle.new(self) if defined? current::Lifecycle
|
94
|
+
end
|
80
95
|
end
|
81
96
|
|
82
97
|
end
|
@@ -20,11 +20,19 @@ module Hobo
|
|
20
20
|
|
21
21
|
|
22
22
|
def extract_attributes(attributes)
|
23
|
-
|
24
|
-
|
23
|
+
model = lifecycle.model
|
24
|
+
params = options.fetch(:params, [])
|
25
|
+
allowed = params.dup
|
26
|
+
params.each do |p|
|
27
|
+
if (refl = model.reflections[p]) && refl.macro == :belongs_to
|
28
|
+
allowed << refl.primary_key_name.to_s
|
29
|
+
allowed << refl.options[:foreign_type] if refl.options[:polymorphic]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
attributes & allowed
|
25
33
|
end
|
26
|
-
|
27
|
-
|
34
|
+
|
35
|
+
|
28
36
|
def change_state(record)
|
29
37
|
record.lifecycle.become(get_state(record, end_state))
|
30
38
|
end
|
data/lib/hobo/model.rb
CHANGED
@@ -85,6 +85,7 @@ module Hobo
|
|
85
85
|
@models_loaded = true
|
86
86
|
end
|
87
87
|
|
88
|
+
@model_names ||= Set.new
|
88
89
|
# ...but only return the ones that registered themselves
|
89
90
|
@model_names.map do |name|
|
90
91
|
name.safe_constantize || (@model_names.delete name; nil)
|
@@ -137,8 +138,18 @@ module Hobo
|
|
137
138
|
require 'active_record/viewhints_validations_interceptor'
|
138
139
|
include Hobo::ViewHintsValidationsInterceptor
|
139
140
|
|
141
|
+
# TODO: should this be an inheriting_cattr_accessor as well? Probably.
|
140
142
|
attr_accessor :creator_attribute
|
141
|
-
|
143
|
+
inheriting_cattr_accessor :name_attribute => Proc.new { |c|
|
144
|
+
names = c.columns.*.name + c.public_instance_methods
|
145
|
+
NAME_FIELD_GUESS.detect {|f| f.in? names }
|
146
|
+
}
|
147
|
+
|
148
|
+
inheriting_cattr_accessor :primary_content_attribute => Proc.new { |c|
|
149
|
+
names = c.columns.*.name + c.public_instance_methods
|
150
|
+
PRIMARY_CONTENT_GUESS.detect {|f| f.in? names }
|
151
|
+
}
|
152
|
+
|
142
153
|
|
143
154
|
def named(*args)
|
144
155
|
raise NoNameError, "Model #{name} has no name attribute" unless name_attribute
|
@@ -157,21 +168,6 @@ module Hobo
|
|
157
168
|
end
|
158
169
|
|
159
170
|
|
160
|
-
def name_attribute
|
161
|
-
@name_attribute ||= begin
|
162
|
-
names = columns.*.name + public_instance_methods
|
163
|
-
NAME_FIELD_GUESS.detect {|f| f.in? names }
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
|
168
|
-
def primary_content_attribute
|
169
|
-
@primary_content_attribute ||= begin
|
170
|
-
names = columns.*.name + public_instance_methods
|
171
|
-
PRIMARY_CONTENT_GUESS.detect {|f| f.in? names }
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
171
|
def dependent_collections
|
176
172
|
reflections.values.select do |refl|
|
177
173
|
refl.macro == :has_many && refl.options[:dependent]
|
@@ -203,6 +199,9 @@ module Hobo
|
|
203
199
|
belongs_to_without_test_methods(name, options, &block)
|
204
200
|
refl = reflections[name]
|
205
201
|
if options[:polymorphic]
|
202
|
+
# TODO: the class lookup in _is? below is incomplete; a polymorphic association to an STI base class
|
203
|
+
# will fail to match an object of a derived type
|
204
|
+
# (ie X belongs_to Y (polymorphic), Z is a subclass of Y; @x.y_is?(some_z) will never pass)
|
206
205
|
class_eval %{
|
207
206
|
def #{name}_is?(target)
|
208
207
|
target.class.name == self.#{refl.options[:foreign_type]} && target.id == self.#{refl.primary_key_name}
|
@@ -214,7 +213,7 @@ module Hobo
|
|
214
213
|
else
|
215
214
|
class_eval %{
|
216
215
|
def #{name}_is?(target)
|
217
|
-
target.class
|
216
|
+
target.class <= ::#{refl.klass.name} && target.id == self.#{refl.primary_key_name}
|
218
217
|
end
|
219
218
|
def #{name}_changed?
|
220
219
|
#{refl.primary_key_name}_changed?
|
@@ -345,7 +344,7 @@ module Hobo
|
|
345
344
|
|
346
345
|
refl.klass.reflections.values.find do |r|
|
347
346
|
r.macro.in?(reverse_macros) &&
|
348
|
-
r.klass
|
347
|
+
r.klass >= self &&
|
349
348
|
!r.options[:conditions] &&
|
350
349
|
r.primary_key_name == refl.primary_key_name
|
351
350
|
end
|
@@ -434,14 +433,18 @@ module Hobo
|
|
434
433
|
attr = self.class.creator_attribute
|
435
434
|
return unless attr
|
436
435
|
|
437
|
-
|
438
|
-
|
436
|
+
attr_type = self.class.creator_type
|
437
|
+
|
438
|
+
# Is creator an instance, a string field or an association?
|
439
|
+
if !attr_type.is_a?(Class)
|
440
|
+
# attr_type is an instance - typically AssociationReflection for a polymorphic association
|
441
|
+
self.send("#{attr}=", user)
|
442
|
+
elsif self.class.attr_type(attr)._? <= String
|
439
443
|
# Set it to the name of the current user
|
440
444
|
self.send("#{attr}=", user.to_s) unless user.guest?
|
441
445
|
else
|
442
446
|
# Assume user is a user object, but don't set if we've got a type mismatch
|
443
|
-
|
444
|
-
self.send("#{attr}=", user) if t.nil? || user.is_a?(t)
|
447
|
+
self.send("#{attr}=", user) if attr_type.nil? || user.is_a?(attr_type)
|
445
448
|
end
|
446
449
|
end
|
447
450
|
|
@@ -383,7 +383,7 @@ module Hobo
|
|
383
383
|
(!destroyed && object_url(@this)) ||
|
384
384
|
|
385
385
|
# Then the show page of the 'owning' object if there is one
|
386
|
-
|
386
|
+
object_url(owning_object) ||
|
387
387
|
|
388
388
|
# Last try - the index page for this model
|
389
389
|
object_url(@this.class) ||
|
@@ -391,6 +391,11 @@ module Hobo
|
|
391
391
|
# Give up
|
392
392
|
home_page
|
393
393
|
end
|
394
|
+
|
395
|
+
def owning_object
|
396
|
+
method = @this.class.dependent_on.detect {|m| !@this.send(m).nil?}
|
397
|
+
method ? @this.send(method) : nil
|
398
|
+
end
|
394
399
|
|
395
400
|
|
396
401
|
def url_for_page_path
|
@@ -457,9 +462,9 @@ module Hobo
|
|
457
462
|
|
458
463
|
def find_owner_and_association(owner_association)
|
459
464
|
refl = model.reflections[owner_association]
|
460
|
-
|
461
|
-
id = params["#{
|
462
|
-
owner = klass.find(id)
|
465
|
+
owner_name = refl.macro == :has_many ? owner_association.to_s.singularize : owner_association
|
466
|
+
id = params["#{owner_name}_id"]
|
467
|
+
owner = refl.klass.find(id)
|
463
468
|
instance_variable_set("@#{owner_association}", owner)
|
464
469
|
[owner, owner.send(model.reverse_reflection(owner_association).name)]
|
465
470
|
end
|
@@ -486,7 +491,7 @@ module Hobo
|
|
486
491
|
|
487
492
|
def hobo_show(*args, &b)
|
488
493
|
options = args.extract_options!
|
489
|
-
self.this ||= find_instance(options)
|
494
|
+
self.this ||= args.first || find_instance(options)
|
490
495
|
response_block(&b)
|
491
496
|
end
|
492
497
|
|
@@ -544,7 +549,7 @@ module Hobo
|
|
544
549
|
|
545
550
|
|
546
551
|
def create_response(new_action, options={}, &b)
|
547
|
-
flash_notice "The #{@this.class.name.titleize.downcase} was created successfully" if valid?
|
552
|
+
flash_notice (ht( :"#{@this.class.name.pluralize.underscore}.messages.create.success", :default=>["The #{@this.class.name.titleize.downcase} was created successfully"])) if valid?
|
548
553
|
|
549
554
|
response_block(&b) or
|
550
555
|
if valid?
|
@@ -554,10 +559,12 @@ module Hobo
|
|
554
559
|
end
|
555
560
|
else
|
556
561
|
respond_to do |wants|
|
562
|
+
# errors is used by the translation helper, ht, below.
|
563
|
+
errors = this.errors.full_messages.join("\n")
|
557
564
|
wants.html { re_render_form(new_action) }
|
558
565
|
wants.js { render(:status => 500,
|
559
|
-
:text => ("Couldn't create the #{this.class.name.titleize.downcase}.\n"
|
560
|
-
|
566
|
+
:text => ht( :"#{this.class.name.pluralize.underscore}.messages.create.error", :errors=>errors,:default=>["Couldn't create the #{this.class.name.titleize.downcase}.\n #{errors}"])
|
567
|
+
)}
|
561
568
|
end
|
562
569
|
end
|
563
570
|
end
|
@@ -567,7 +574,7 @@ module Hobo
|
|
567
574
|
options = args.extract_options!
|
568
575
|
|
569
576
|
self.this ||= args.first || find_instance
|
570
|
-
changes = options[:attributes] || attribute_parameters or raise RuntimeError, "No update specified in params"
|
577
|
+
changes = options[:attributes] || attribute_parameters or raise RuntimeError, ht(:"hobo.messages.update.no_attribute_error", :default=>["No update specified in params"])
|
571
578
|
this.user_update_attributes(current_user, changes)
|
572
579
|
|
573
580
|
# Ensure current_user isn't out of date
|
@@ -579,7 +586,8 @@ module Hobo
|
|
579
586
|
|
580
587
|
|
581
588
|
def update_response(in_place_edit_field=nil, options={}, &b)
|
582
|
-
|
589
|
+
|
590
|
+
flash_notice (ht(:"#{@this.class.name.pluralize.underscore}.messages.update.success", :default=>["Changes to the #{@this.class.name.titleize.downcase} were saved"])) if valid?
|
583
591
|
|
584
592
|
response_block(&b) or
|
585
593
|
if valid?
|
@@ -602,10 +610,12 @@ module Hobo
|
|
602
610
|
end
|
603
611
|
else
|
604
612
|
respond_to do |wants|
|
613
|
+
# errors is used by the translation helper, ht, below.
|
614
|
+
errors = @this.errors.full_messages.join("\n")
|
605
615
|
wants.html { re_render_form(:edit) }
|
606
616
|
wants.js { render(:status => 500,
|
607
|
-
:text => ("There was a problem with that change.\n"
|
608
|
-
|
617
|
+
:text => ht(:"#{@this.class.name.pluralize.underscore}.messages.update.error",:default=>["There was a problem with that change.\n#{errors}"], :errors=>errors)
|
618
|
+
) }
|
609
619
|
end
|
610
620
|
end
|
611
621
|
end
|
@@ -615,7 +625,7 @@ module Hobo
|
|
615
625
|
options = args.extract_options!
|
616
626
|
self.this ||= args.first || find_instance
|
617
627
|
this.user_destroy(current_user)
|
618
|
-
flash_notice "The #{model.name.titleize.downcase} was deleted"
|
628
|
+
flash_notice ht( :"#{model.name.pluralize.underscore}.messages.destroy.success", :default=>["The #{model.name.titleize.downcase} was deleted"])
|
619
629
|
destroy_response(options, &b)
|
620
630
|
end
|
621
631
|
|
@@ -652,10 +662,12 @@ module Hobo
|
|
652
662
|
else
|
653
663
|
this.exempt_from_edit_checks = true
|
654
664
|
respond_to do |wants|
|
665
|
+
# errors is used by the translation helper, ht, below.
|
666
|
+
errors = this.errors.full_messages.join("\n")
|
655
667
|
wants.html { re_render_form(name) }
|
656
668
|
wants.js { render(:status => 500,
|
657
|
-
:text => ("Couldn't do creator #{name}.\n"
|
658
|
-
|
669
|
+
:text => ht(:"#{@this.class.name.pluralize.underscore}.messages.creator.error", :default=>["Couldn't do creator #{name}.\n#{errors}"], :name=>name, :errors=>errors)
|
670
|
+
)}
|
659
671
|
end
|
660
672
|
end
|
661
673
|
end
|
@@ -663,12 +675,13 @@ module Hobo
|
|
663
675
|
|
664
676
|
def prepare_transition(name, options)
|
665
677
|
key = options.delete(:key) || params[:key]
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
678
|
+
|
679
|
+
# we don't use find_instance here, as it fails for key_holder transitions on objects that Guest can't view
|
680
|
+
record = model.find(params[:id])
|
681
|
+
record.exempt_from_edit_checks = true
|
682
|
+
record.lifecycle.provided_key = key
|
683
|
+
self.this = record
|
684
|
+
|
672
685
|
this.lifecycle.find_transition(name, current_user) or raise Hobo::PermissionDeniedError
|
673
686
|
end
|
674
687
|
|
@@ -691,10 +704,12 @@ module Hobo
|
|
691
704
|
end
|
692
705
|
else
|
693
706
|
respond_to do |wants|
|
707
|
+
# errors is used by the translation helper, ht, below.
|
708
|
+
errors = this.errors.full_messages.join("\n")
|
694
709
|
wants.html { re_render_form(name) }
|
695
710
|
wants.js { render(:status => 500,
|
696
|
-
:text => ("Couldn't do transition #{name}.\n"
|
697
|
-
|
711
|
+
:text => ht(:"#{@this.class.name.pluralize.underscore}.messages.transition.error", :default=>["Couldn't do transition #{name}.\n#{errors}"], :name=>name, :errors=>errors)
|
712
|
+
)}
|
698
713
|
end
|
699
714
|
end
|
700
715
|
end
|
@@ -748,28 +763,17 @@ module Hobo
|
|
748
763
|
if render_tag("permission-denied-page", { }, :status => 403)
|
749
764
|
# job done
|
750
765
|
else
|
751
|
-
render :text => "Permission Denied", :status => 403
|
766
|
+
render :text => ht(:"hobo.messages.permission_denied", :default=>["Permission Denied"]), :status => 403
|
752
767
|
end
|
753
768
|
end
|
754
769
|
wants.js do
|
755
|
-
render :text => "Permission Denied", :status => 403
|
770
|
+
render :text => ht(:"hobo.messages.permission_denied", :default=>["Permission Denied"]), :status => 403
|
756
771
|
end
|
757
772
|
end
|
758
773
|
end
|
759
774
|
end
|
760
775
|
|
761
776
|
|
762
|
-
def not_found(error)
|
763
|
-
if "not_found_response".in?(self.class.superclass.instance_methods)
|
764
|
-
super
|
765
|
-
elsif render_tag("not-found-page", {}, :status => 404)
|
766
|
-
# cool
|
767
|
-
else
|
768
|
-
render(:text => "The page you requested cannot be found.", :status => 404)
|
769
|
-
end
|
770
|
-
end
|
771
|
-
|
772
|
-
|
773
777
|
def this
|
774
778
|
@this ||= (instance_variable_get("@#{model.name.underscore}") ||
|
775
779
|
instance_variable_get("@#{model.name.underscore.pluralize}"))
|
@@ -794,7 +798,8 @@ module Hobo
|
|
794
798
|
def render_with_hobo_model(*args, &block)
|
795
799
|
options = args.extract_options!
|
796
800
|
self.this = options[:object] if options[:object]
|
797
|
-
this
|
801
|
+
# this causes more problems than it solves, and Tom says it's not supposed to be here
|
802
|
+
# this.user_view(current_user) if this && this.respond_to?(:user_view)
|
798
803
|
render_without_hobo_model(*args + [options], &block)
|
799
804
|
end
|
800
805
|
|