hobo 1.3.0.pre19 → 1.3.0.pre20

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 (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