hobo 1.3.0.pre19 → 1.3.0.pre20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/CHANGES.txt +282 -234
  2. data/VERSION +1 -1
  3. data/lib/generators/hobo/admin_subsite/templates/controller.rb.erb +5 -5
  4. data/lib/generators/hobo/assets/templates/dryml-support.js +2 -2
  5. data/lib/generators/hobo/i18n/templates/hobo.it.yml +1 -1
  6. data/lib/generators/hobo/rapid/templates/hobo-rapid.js +64 -64
  7. data/lib/generators/hobo/rapid/templates/ie7-recalc.js +21 -21
  8. data/lib/generators/hobo/rapid/templates/lowpro.js +31 -31
  9. data/lib/generators/hobo/rapid/templates/reset.css +1 -1
  10. data/lib/generators/hobo/rapid/templates/themes/clean/public/stylesheets/clean.css +15 -15
  11. data/lib/generators/hobo/rapid/templates/themes/clean/public/stylesheets/rapid-ui.css +3 -3
  12. data/lib/generators/hobo/rapid/templates/themes/clean/views/clean.dryml +1 -1
  13. data/lib/generators/hobo/setup_wizard/setup_wizard_generator.rb +15 -14
  14. data/lib/generators/hobo/subsite/templates/controller.rb.erb +1 -1
  15. data/lib/generators/hobo/user_controller/templates/controller.rb.erb +2 -2
  16. data/lib/hobo.rb +1 -0
  17. data/lib/hobo/controller.rb +6 -6
  18. data/lib/hobo/controller/authentication_support.rb +1 -1
  19. data/lib/hobo/controller/model.rb +10 -10
  20. data/lib/hobo/controller/user.rb +6 -6
  21. data/lib/hobo/engine.rb +6 -0
  22. data/lib/hobo/extensions/action_view/translation_helper.rb +20 -0
  23. data/lib/hobo/extensions/active_model/translation.rb +1 -1
  24. data/lib/hobo/extensions/i18n.rb +16 -0
  25. data/lib/hobo/helper.rb +2 -2
  26. data/lib/hobo/helper/translations.rb +61 -80
  27. data/lib/hobo/model/lifecycles/lifecycle.rb +5 -1
  28. data/lib/hobo/model/lifecycles/transition.rb +1 -0
  29. data/lib/hobo/rapid/generators/rapid/cards.dryml.erb +2 -2
  30. data/lib/hobo/rapid/generators/rapid/forms.dryml.erb +2 -2
  31. data/lib/hobo/rapid/generators/rapid/pages.dryml.erb +7 -7
  32. data/lib/hobo/rapid/taglibs/rapid.dryml +1 -1
  33. data/lib/hobo/rapid/taglibs/rapid_core.dryml +8 -8
  34. data/lib/hobo/rapid/taglibs/rapid_document_tags.dryml +2 -2
  35. data/lib/hobo/rapid/taglibs/rapid_forms.dryml +9 -9
  36. data/lib/hobo/rapid/taglibs/rapid_generics.dryml +1 -1
  37. data/lib/hobo/rapid/taglibs/rapid_i18n.dryml +0 -17
  38. data/lib/hobo/rapid/taglibs/rapid_lifecycles.dryml +5 -5
  39. data/lib/hobo/rapid/taglibs/rapid_navigation.dryml +1 -1
  40. data/lib/hobo/rapid/taglibs/rapid_plus.dryml +6 -6
  41. data/lib/hobo/rapid/taglibs/rapid_user_pages.dryml +8 -8
  42. data/test/permissions/test_permissions.rb +103 -103
  43. metadata +15 -14
  44. data/lib/hobo/rapid/taglibs/rapid_translations.dryml +0 -36
@@ -7,4 +7,4 @@
7
7
  <stylesheet name="application" param="app-stylesheet"/>
8
8
  </stylesheets:>
9
9
  </old-page>
10
- </extend>
10
+ </extend>
@@ -78,6 +78,17 @@ module Hobo
78
78
  :update => true
79
79
  end
80
80
 
81
+ def user_options
82
+ if wizard?
83
+ say_title 'User Resource'
84
+ @user_resource_name = ask("Choose a name for the user resource [<enter>=user|<custom_name>]:", 'user')
85
+ @activation_email = @invite_only ? false : yes_no?("Do you want to send an activation email to activate the user?")
86
+ else
87
+ @user_resource_name = options[:user_resource_name]
88
+ @activation_email = options[:activation_email]
89
+ end
90
+ end
91
+
81
92
  def site_options
82
93
  if wizard?
83
94
  say_title 'Invite Only Option'
@@ -99,8 +110,8 @@ NOTE: You might want to sign up as the administrator before adding this!
99
110
  end
100
111
  inject_into_file 'app/controllers/application_controller.rb', <<EOI, :after => "protect_from_forgery\n" if private_site
101
112
  include Hobo::Controller::AuthenticationSupport
102
- before_filter :except => :login do
103
- login_required unless User.count == 0
113
+ before_filter :except => [:login, :forgot_password] do
114
+ login_required unless #{@user_resource_name.camelize}.count == 0
104
115
  end
105
116
  EOI
106
117
  end
@@ -113,17 +124,6 @@ EOI
113
124
  invoke 'hobo:rapid'
114
125
  end
115
126
 
116
- def user_options
117
- if wizard?
118
- say_title 'User Resource'
119
- @user_resource_name = ask("Choose a name for the user resource [<enter>=user|<custom_name>]:", 'user')
120
- @activation_email = @invite_only ? false : yes_no?("Do you want to send an activation email to activate the user?")
121
- else
122
- @user_resource_name = options[:user_resource_name]
123
- @activation_email = options[:activation_email]
124
- end
125
- end
126
-
127
127
  def front_controller
128
128
  if wizard?
129
129
  say_title 'Front Controller'
@@ -201,8 +201,9 @@ EOI
201
201
  environment "config.i18n.default_locale = #{default_locale.to_sym.inspect}"
202
202
  end
203
203
  ls = (locales - %w[en]).map {|l| ":#{l}" }
204
+ lstr = ls.to_sentence
204
205
  invoke 'hobo:i18n', locales
205
- say( "NOTICE: You should manually install in 'config/locales' also the official Rails locale #{ls.size==1 ? 'file' : 'files'} for #{ls.to_sentence} that your application will use.", Color::YELLOW) unless ls.empty?
206
+ say( "NOTICE: You should manually install in 'config/locales' also the official Rails locale #{ls.size==1 ? 'file' : 'files'} for #{lstr} that your application will use.", Color::YELLOW) unless ls.empty?
206
207
  end
207
208
 
208
209
  def git_repo
@@ -1,5 +1,5 @@
1
1
  class <%= subsite_name %>::<%= subsite_name %>SiteController < ApplicationController
2
2
 
3
3
  hobo_controller
4
-
4
+
5
5
  end
@@ -8,7 +8,7 @@ class <%= class_name %>Controller < ApplicationController
8
8
  hobo_create do
9
9
  if valid?
10
10
  self.current_user = this
11
- flash[:notice] = I18n.t("hobo.messages.you_are_site_admin", :default=>"You are now the site administrator")
11
+ flash[:notice] = t("hobo.messages.you_are_site_admin", :default=>"You are now the site administrator")
12
12
  redirect_to home_page
13
13
  end
14
14
  end
@@ -18,7 +18,7 @@ class <%= class_name %>Controller < ApplicationController
18
18
  def do_accept_invitation
19
19
  do_transition_action :accept_invitation do
20
20
  self.current_user = this
21
- flash[:notice] = I18n.t("hobo.messages.you_signed_up", :default=>"You have signed up")
21
+ flash[:notice] = t("hobo.messages.you_signed_up", :default=>"You have signed up")
22
22
  end
23
23
  end
24
24
  <% end -%>
data/lib/hobo.rb CHANGED
@@ -17,6 +17,7 @@ module Hobo
17
17
  class Error < RuntimeError; end
18
18
  class PermissionDeniedError < RuntimeError; end
19
19
  class UndefinedAccessError < RuntimeError; end
20
+ class I18nError < RuntimeError; end
20
21
 
21
22
  # Empty class to represent the boolean type.
22
23
  class Boolean; end
@@ -71,12 +71,12 @@ module Hobo
71
71
 
72
72
  def ajax_update_response(page_path, render_specs, results={})
73
73
  if page_path
74
- rr = ActionController::Routing::Routes.recognize_path(page_path)
75
- identifier = view_context.view_paths.find( rr[:action],
76
- rr[:controller],
74
+ controller, action = controller_action_from_page_path(page_path)
75
+ identifier = view_context.view_paths.find( action,
76
+ controller,
77
77
  false,
78
78
  view_context.lookup_context.instance_variable_get('@details')).identifier
79
- renderer = Dryml.page_renderer(view_context, identifier, [], rr[:controller])
79
+ renderer = Dryml.page_renderer(view_context, identifier, [], controller)
80
80
  end
81
81
 
82
82
  render :update do |page|
@@ -131,7 +131,7 @@ module Hobo
131
131
  results_hash = Hobo.find_by_search(query)
132
132
  all_results = results_hash.values.flatten.select { |r| r.viewable_by?(current_user) }
133
133
  if all_results.empty?
134
- render :text => "<p>"+ I18n.t("hobo.live_search.no_results", :default=>["Your search returned no matches."]) + "</p>"
134
+ render :text => "<p>"+ t("hobo.live_search.no_results", :default=>["Your search returned no matches."]) + "</p>"
135
135
  else
136
136
  # TODO: call one tag that renders all the search results with headings for each model
137
137
  render_tags(all_results, :search_card, :for_type => true)
@@ -156,7 +156,7 @@ module Hobo
156
156
  elsif render :not_found, :status => 404
157
157
  # cool
158
158
  else
159
- render(:text => I18n.t("hobo.messages.not_found", :default=>["The page you requested cannot be found."]) , :status => 404)
159
+ render(:text => t("hobo.messages.not_found", :default=>["The page you requested cannot be found."]) , :status => 404)
160
160
  end
161
161
  end
162
162
 
@@ -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 => I18n.t("hobo.messages.unauthenticated", :default=>["Couldn't authenticate you"]), :status => '401 Unauthorized'
70
+ render :text => t("hobo.messages.unauthenticated", :default=>["Couldn't authenticate you"]), :status => '401 Unauthorized'
71
71
  end
72
72
  end
73
73
  false
@@ -552,7 +552,7 @@ module Hobo
552
552
 
553
553
 
554
554
  def create_response(new_action, options={}, &b)
555
- flash_notice (ht( :"#{@this.class.name.tableize}.messages.create.success", :default=>["The #{@this.class.model_name.human} was created successfully"])) if valid?
555
+ flash_notice (ht( :"#{@this.class.to_s.underscore}.messages.create.success", :default=>["The #{@this.class.model_name.human} was created successfully"])) if valid?
556
556
 
557
557
  response_block(&b) or
558
558
  if valid?
@@ -566,7 +566,7 @@ module Hobo
566
566
  errors = this.errors.full_messages.join("\n")
567
567
  wants.html { re_render_form(new_action) }
568
568
  wants.js { render(:status => 500,
569
- :text => ht( :"#{this.class.name.pluralize.underscore}.messages.create.error", :errors=>errors,:default=>["Couldn't create the #{this.class.name.titleize.downcase}.\n #{errors}"])
569
+ :text => ht( :"#{this.class.to_s.underscore}.messages.create.error", :errors=>errors,:default=>["Couldn't create the #{this.class.name.titleize.downcase}.\n #{errors}"])
570
570
  )}
571
571
  end
572
572
  end
@@ -577,7 +577,7 @@ module Hobo
577
577
  options = args.extract_options!
578
578
 
579
579
  self.this ||= args.first || find_instance
580
- changes = options[:attributes] || attribute_parameters or raise RuntimeError, I18n.t("hobo.messages.update.no_attribute_error", :default=>["No update specified in params"])
580
+ changes = options[:attributes] || attribute_parameters or raise RuntimeError, t("hobo.messages.update.no_attribute_error", :default=>["No update specified in params"])
581
581
  this.user_update_attributes(current_user, changes)
582
582
 
583
583
  # Ensure current_user isn't out of date
@@ -590,7 +590,7 @@ module Hobo
590
590
 
591
591
  def update_response(in_place_edit_field=nil, options={}, &b)
592
592
 
593
- flash_notice (ht(:"#{@this.class.name.pluralize.underscore}.messages.update.success", :default=>["Changes to the #{@this.class.model_name.human} were saved"])) if valid?
593
+ flash_notice (ht(:"#{@this.class.name.to_s.underscore}.messages.update.success", :default=>["Changes to the #{@this.class.model_name.human} were saved"])) if valid?
594
594
 
595
595
  response_block(&b) or
596
596
  if valid?
@@ -617,7 +617,7 @@ module Hobo
617
617
  errors = @this.errors.full_messages.join("\n")
618
618
  wants.html { re_render_form(:edit) }
619
619
  wants.js { render(:status => 500,
620
- :text => ht(:"#{@this.class.name.pluralize.underscore}.messages.update.error",:default=>["There was a problem with that change.\n#{errors}"], :errors=>errors)
620
+ :text => ht(:"#{@this.class.to_s.underscore}.messages.update.error",:default=>["There was a problem with that change.\n#{errors}"], :errors=>errors)
621
621
  ) }
622
622
  end
623
623
  end
@@ -628,7 +628,7 @@ module Hobo
628
628
  options = args.extract_options!
629
629
  self.this ||= args.first || find_instance
630
630
  this.user_destroy(current_user)
631
- flash_notice ht( :"#{model.name.pluralize.underscore}.messages.destroy.success", :default=>["The #{model.name.titleize.downcase} was deleted"])
631
+ flash_notice ht( :"#{model.to_s.underscore}.messages.destroy.success", :default=>["The #{model.name.titleize.downcase} was deleted"])
632
632
  destroy_response(options, &b)
633
633
  end
634
634
 
@@ -669,7 +669,7 @@ module Hobo
669
669
  errors = this.errors.full_messages.join("\n")
670
670
  wants.html { re_render_form(name) }
671
671
  wants.js { render(:status => 500,
672
- :text => ht(:"#{@this.class.name.pluralize.underscore}.messages.creator.error", :default=>["Couldn't do creator #{name}.\n#{errors}"], :name=>name, :errors=>errors)
672
+ :text => ht(:"#{@this.class.to_s.underscore}.messages.creator.error", :default=>["Couldn't do creator #{name}.\n#{errors}"], :name=>name, :errors=>errors)
673
673
  )}
674
674
  end
675
675
  end
@@ -711,7 +711,7 @@ module Hobo
711
711
  errors = this.errors.full_messages.join("\n")
712
712
  wants.html { re_render_form(name) }
713
713
  wants.js { render(:status => 500,
714
- :text => ht(:"#{@this.class.name.pluralize.underscore}.messages.transition.error", :default=>["Couldn't do transition #{name}.\n#{errors}"], :name=>name, :errors=>errors)
714
+ :text => ht(:"#{@this.class.to_s.underscore}.messages.transition.error", :default=>["Couldn't do transition #{name}.\n#{errors}"], :name=>name, :errors=>errors)
715
715
  )}
716
716
  end
717
717
  end
@@ -767,11 +767,11 @@ module Hobo
767
767
  if render :permission_denied, :status => 403
768
768
  # job done
769
769
  else
770
- render :text => I18n.t("hobo.messages.permission_denied", :default=>["Permission Denied"]), :status => 403
770
+ render :text => t("hobo.messages.permission_denied", :default=>["Permission Denied"]), :status => 403
771
771
  end
772
772
  end
773
773
  wants.js do
774
- render :text => I18n.t("hobo.messages.permission_denied", :default=>["Permission Denied"]), :status => 403
774
+ render :text => t("hobo.messages.permission_denied", :default=>["Permission Denied"]), :status => 403
775
775
  end
776
776
  end
777
777
  end
@@ -62,8 +62,8 @@ module Hobo
62
62
  end
63
63
 
64
64
  login_attr = model.human_attribute_name(model.login_attribute)
65
- options.reverse_merge!(:success_notice => ht(:"users.messages.login.success", :default=>["You have logged in."]),
66
- :failure_notice => ht(:"users.messages.login.error", :login=>login_attr, :default=>["You did not provide a valid #{login_attr} and password."]))
65
+ options.reverse_merge!(:success_notice => ht(:"#{model.to_s.underscore}.messages.login.success", :default=>["You have logged in."]),
66
+ :failure_notice => ht(:"#{model.to_s.underscore}.messages.login.error", :login=>login_attr, :default=>["You did not provide a valid #{login_attr} and password."]))
67
67
 
68
68
  if request.post?
69
69
  user = model.authenticate(params[:login], params[:password])
@@ -113,7 +113,7 @@ module Hobo
113
113
  def hobo_do_signup(&b)
114
114
  do_creator_action(:signup) do
115
115
  if valid?
116
- flash[:notice] = ht(:"users.messages.signup.success", :default=>["Thanks for signing up!"])
116
+ flash[:notice] = ht(:"#{model.to_s.underscore}.messages.signup.success", :default=>["Thanks for signing up!"])
117
117
  end
118
118
  response_block(&b) or if valid?
119
119
  self.current_user = this if this.account_active?
@@ -127,7 +127,7 @@ module Hobo
127
127
 
128
128
 
129
129
  def hobo_logout(options={})
130
- options = options.reverse_merge(:notice => ht(:"users.messages.logout", :default=>["You have logged out."]),
130
+ options = options.reverse_merge(:notice => ht(:"#{model.to_s.underscore}.messages.logout", :default=>["You have logged out."]),
131
131
  :redirect_to => base_url)
132
132
 
133
133
  logout_current_user
@@ -155,7 +155,7 @@ module Hobo
155
155
  do_transition_action :reset_password do
156
156
  response_block(&b) or if valid?
157
157
  self.current_user = this
158
- flash[:notice] = ht(:"users.messages.reset_password", :default=>["Your password has been reset"])
158
+ flash[:notice] = ht(:"#{model.to_s.underscore}.messages.reset_password", :default=>["Your password has been reset"])
159
159
  respond_to do |wants|
160
160
  wants.html { redirect_to(home_page) }
161
161
  wants.js { hobo_ajax_response }
@@ -167,7 +167,7 @@ module Hobo
167
167
 
168
168
  def hobo_update_with_account_flash(*args)
169
169
  hobo_update_without_account_flash(*args) do
170
- flash[:notice] = ht(:"users.messages.update.success", :default=>["Changes to your account were saved"]) if valid? && @this == current_user
170
+ flash[:notice] = ht(:"#{model.to_s.underscore}.messages.update.success", :default=>["Changes to your account were saved"]) if valid? && @this == current_user
171
171
  yield if block_given?
172
172
  end
173
173
  end
data/lib/hobo/engine.rb CHANGED
@@ -14,6 +14,7 @@ module Hobo
14
14
  h.rapid_generators_path = Pathname.new File.expand_path('lib/hobo/rapid/generators', Hobo.root)
15
15
  h.auto_taglibs_path = Pathname.new File.expand_path('app/views/taglibs/auto', Rails.root)
16
16
  h.read_only_file_system = !!ENV['HEROKU_TYPE']
17
+ h.show_translation_keys = false
17
18
  end
18
19
 
19
20
  ActiveSupport.on_load(:action_controller) do
@@ -35,6 +36,7 @@ module Hobo
35
36
 
36
37
  ActiveSupport.on_load(:action_view) do
37
38
  require 'hobo/extensions/action_view/tag_helper'
39
+ require 'hobo/extensions/action_view/translation_helper'
38
40
  end
39
41
 
40
42
  ActiveSupport.on_load(:before_initialize) do
@@ -44,6 +46,10 @@ module Hobo
44
46
  Dryml::DrymlGenerator.enable([h.rapid_generators_path], h.auto_taglibs_path)
45
47
  end
46
48
 
49
+ initializer 'hobo.i18n' do |app|
50
+ require 'hobo/extensions/i18n' if app.config.hobo.show_translation_keys
51
+ end
52
+
47
53
  initializer 'hobo.routes' do |app|
48
54
  h = app.config.hobo
49
55
  # generate at first boot, so no manual generation is required
@@ -0,0 +1,20 @@
1
+ ActionView::Helpers::TranslationHelper.module_eval do
2
+
3
+ # we need to remove the <span> tag because it will mess up
4
+ # the dryml tags when ht is used in some place
5
+ # we redefine the method since we cannot catch the rescued exception
6
+ # although the only difference is the rescue block
7
+ def translate(key, options = {})
8
+ translation = I18n.translate(scope_key_by_partial(key), options.merge!(:raise => true))
9
+ if html_safe_translation_key?(key) && translation.respond_to?(:html_safe)
10
+ translation.html_safe
11
+ else
12
+ translation
13
+ end
14
+ rescue I18n::MissingTranslationData => e
15
+ keys = I18n.normalize_keys(I18n.locale, key, options[:scope]).join('.')
16
+ "[MISSING: #{keys}]"
17
+ end
18
+ alias_method :t, :translate
19
+
20
+ end
@@ -21,7 +21,7 @@ ActiveModel::Translation.class_eval do
21
21
  # otherwise it returns "".
22
22
  def attribute_help(attribute, options = {})
23
23
  defaults = lookup_ancestors.map do |klass|
24
- :"#{self.i18n_scope}.attribute_help.#{klass.model_name.underscore}.#{attribute}"
24
+ :"#{self.i18n_scope}.attribute_help.#{klass.to_s.underscore}.#{attribute}"
25
25
  end
26
26
 
27
27
  defaults << :"attribute_help.#{attribute}"
@@ -0,0 +1,16 @@
1
+ I18n.module_eval do
2
+ class << self
3
+
4
+ def translate_with_show_keys(key, options = {})
5
+ translation = translate_without_show_keys(key, options)
6
+ keys = normalize_keys(locale, key, options[:scope]).join('.')
7
+ "[#{keys}]" + translation
8
+ end
9
+ alias_method_chain :translate, :show_keys
10
+
11
+ alias_method :t_without_show_keys, :t
12
+ alias_method :t, :translate_with_show_keys
13
+
14
+ end
15
+ end
16
+
data/lib/hobo/helper.rb CHANGED
@@ -113,7 +113,7 @@ module Hobo
113
113
  def app_name(add_subsite=true)
114
114
  an = Rails.application.config.hobo.app_name
115
115
  if add_subsite && subsite
116
- subsite_name = I18n.t 'hobo.admin.subsite_name', :default => subsite.titleize
116
+ subsite_name = t 'hobo.admin.subsite_name', :default => subsite.titleize
117
117
  an = an + " - #{subsite_name}"
118
118
  end
119
119
  an
@@ -127,7 +127,7 @@ module Hobo
127
127
 
128
128
 
129
129
  def recognize_page_path
130
- ActionController::Routing::Routes.recognize_path(params[:page_path])
130
+ Rails.application.routes.recognize_path(params[:page_path])
131
131
  end
132
132
 
133
133
  def url_for_page_path(options={})
@@ -2,92 +2,73 @@ module Hobo
2
2
  module Helper
3
3
  module Translations
4
4
 
5
- # --- Translation Helper --- #
6
- #
7
- # Uses RoR native I18n.translate.
8
- #
9
- # Adds some conventions for easier hobo translation.
10
- # 1. Assumes the first part of the key to be a model name (e.g.: users.index.title -> user)
11
- # 2. Tries to translate the model by lookup for: (e.g.: user-> activerecord.models.user)
12
- # 3. Adds a default fallback to the beginning of the fallback chain
13
- # by replacing the first part of the key with "hobo" and using the translated model name
14
- # as additional attribute. This allows us to have default translations
15
- # (e.g.: hobo.index.title: "{{model}} Index")
16
- #
17
- # Is also used as a tag in the dryml-view files. The syntax is:
18
- # <ht key="my.app">My Application</ht>
19
- # --> Will lookup the "my.app"-key for your locale and replaces the "My Application" content
20
- # if found.
21
- #
22
- # <ht key="my" app="Program">My Application</ht>
23
- # --> Will look up both the "my"- and "app"-key for your locale, and replaces the
24
- # "My Application" with the "my"-key contents (interpolated using the "app"-key.
25
- # sample.en.yml-file:
26
- # "no":
27
- # my: "Mitt {{app}}"
28
- # The output should be: Mitt Program
29
- #
30
- # The "count" option is passed to the I18n.t method as is
31
- #
32
- def ht(key, options={})
33
-
34
- # Check if called as a tag, i.e. like this <ht></ht>
35
- if (key.class == Hash)
36
- if key.has_key?(:default) && !key[:default].blank?
37
- Rails.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."
38
- end
39
- defaults = options[:default];
40
- # Swap key and options, remove options[:key]
41
- options = key
42
- key = options.delete(:key) # returns value for options[:key] as well as deleting it
43
- # Set options[:default] to complete the tag-argument-conversion process.
44
- options[:default] = (defaults.class == Proc) ? [defaults.call(options)] : (options[:default].blank? ? [] : [options[:default]])
45
- else
46
- # Not called as a tag. Prepare options[:default].
47
- if options[:default].nil?
48
- options[:default]=[]
49
- elsif options[:default].class != Array
50
- options[:default] = [options[:default]]
51
- end
52
- end
5
+ # simple wrapper around the translate helper
6
+ # it implements a dryml <translate> and a <t> tag
53
7
 
54
- # assume the first part of the key to be the model
55
- keys = key.to_s.split(".")
56
- if keys.length > 1
57
- model = keys.shift()
58
- subkey = keys.join(".")
59
- else
60
- subkey = key
61
- end
8
+ def translate(*args)
9
+ key, options = normalize_args(*args)
10
+ super key.to_sym, options
11
+ end
12
+ alias_method :t, :translate
62
13
 
63
- # will skip useless code in case the first part of the key is 'hobo'
64
- model = '' if model.eql?('hobo')
65
-
66
- unless model.blank?
67
- klass = begin
68
- model.singularize.camelize.constantize
69
- rescue NameError
70
- end
71
- # add :"hobo.#{key}" as the first fallback
72
- options[:default].unshift("hobo.#{subkey}".to_sym)
73
- # translate the model
74
- # the singularize method is used because Hobo does not keep the ActiveRecord convention in its tags
75
- # no default needed because human_name defaults to the model name
76
- # try because Hobo class is not an ActiveRecord::Base subclass
77
- translated_pluralized_model = klass.try.model_name.try.human(:count=>options[:count]||1)
78
- options[:model] = translated_pluralized_model
79
- end
14
+ =begin
15
+
16
+ hobo_translate / ht
17
+
18
+ Wrapper around the Rails :translate helper with hobo added features.
19
+
20
+ It can be used as a regular helper or as a dryml tag.
21
+
22
+ Hobo Added Features
80
23
 
81
- key_prefix = "<span class='translation-key'>#{key}</span>" if defined?(HOBO_SHOW_LOCALE_KEYS) && HOBO_SHOW_LOCALE_KEYS
24
+ The first part of the key must be a model name (e.g.: user.index.title -> user). This method will add a "model" interpolation variable set to the translated and pluralized Model.model_name.human. Besides, it will add a default 'hobo.' fallback, (e.g.: hobo.index.title) at the beginning of the fallback chain.
82
25
 
83
- Rails.logger.info "..translate(#{key}, #{options.inspect}) to #{I18n.locale}" if defined?(HOBO_VERBOSE_TRANSLATIONS)
26
+ You can also pass any other :translate option like for example :count.
84
27
 
85
- translation = I18n.translate(key.to_sym, options)
86
- if translation.respond_to? :to_str
87
- key_prefix ? translation.to_str+key_prefix : translation
88
- else
89
- "translation invalid: #{key}"
28
+ Example:
29
+
30
+ <%= ht :key=>'user.index.title', :default=>'Index' %>
31
+ <ht key="user.index.title">Index</ht>
32
+ #=> "Index" # if "user.index.title" or "hobo.index.title" is not found
33
+ #=> "User Index" # with the below en.yml file
34
+
35
+ === en.yml ===
36
+ en:
37
+ hobo:
38
+ index:
39
+ title: %{model} Index
40
+
41
+ =end
42
+
43
+ def hobo_translate(*args)
44
+ key, options = normalize_args(*args)
45
+ keys = key.to_s.split(".")
46
+ model_name = keys.shift
47
+ model_class = begin model_name.camelize.constantize; rescue; end
48
+ unless model_class && model_class < ActiveRecord::Base
49
+ raise Hobo::I18nError, %(wrong model name: "#{model_name}" (extracted from translation key). You might want to use the translate/t tag/method instead.)
50
+ end
51
+ options[:default].unshift("hobo.#{keys.join(".")}".to_sym)
52
+ options[:model] = model_class.model_name.human(:count=>options[:count]||1)
53
+ translate key.to_sym, options
54
+ end
55
+ alias_method :ht, :hobo_translate
56
+
57
+ private
58
+
59
+ def normalize_args(key, options={})
60
+ if (key.class == Hash) # called as a tag
61
+ if key.has_key?(:default) && !key[:default].blank?
62
+ Rails.logger.warn "hobo-i18n: 'default' should not be used as an attribute on *translate tags. 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."
63
+ end
64
+ defaults = options[:default]
65
+ options = key
66
+ key = options.delete(:key)
67
+ # Set options[:default] to complete the tag-argument-conversion process.
68
+ options[:default] = defaults.call(options) if defaults.class == Proc
90
69
  end
70
+ options[:default] = Array.wrap options[:default]
71
+ [key, options]
91
72
  end
92
73
 
93
74
  end