From c5cc7e020c8a6093b1aecdbe5006f3daa4646ab4 Mon Sep 17 00:00:00 2001 From: adamcreekroad Date: Fri, 30 Apr 2021 12:55:43 -0400 Subject: [PATCH] Improves I18n#t helper method, with specs --- ruby/hyper-i18n/lib/hyperstack/i18n.rb | 39 +++++++++++++++++-- ruby/hyper-i18n/spec/hyper_i18n_spec.rb | 7 ++++ .../spec/test_app/config/locales/en.yml | 2 + 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/ruby/hyper-i18n/lib/hyperstack/i18n.rb b/ruby/hyper-i18n/lib/hyperstack/i18n.rb index 4be1d0b3a..8e74e9d52 100644 --- a/ruby/hyper-i18n/lib/hyperstack/i18n.rb +++ b/ruby/hyper-i18n/lib/hyperstack/i18n.rb @@ -1,13 +1,46 @@ module Hyperstack module I18n - def t(attribute, opts = {}) - namespace = self.class.name.underscore.gsub(%r{::|/}, '.') + class MissingTranslationError < StandardError; end - Hyperstack::Internal::I18n.t("#{namespace}.#{attribute}", opts) + def t(key, opts = {}) + namespace = self.class.name.underscore.gsub(%r{::|/}, ".") + + translation = Hyperstack::Internal::I18n.t("#{namespace}.#{key}", opts) + + # If intially not found and has components namespace, see if it's set without it + if translation_missing?(translation) && translation =~ /components\./ + namespace = namespace.gsub("components.", "") + + translation = Hyperstack::Internal::I18n.t("#{namespace}.#{key}", opts) + end + + # If translation is still not found, try looking up just the key provided + if translation_missing?(translation) + translation = Hyperstack::Internal::I18n.t(key, opts) + end + + if translation_missing?(translation) + raise MissingTranslationError, "Missing translation: #{namespace}.#{key}" + end + + translation + rescue MissingTranslationError => e + # In the case of a missing translation return titleized key + + # HACK: In hyper-operation, String#titleize is patched to return the string as-is, + # so for now we have to manually titleize it + # TODO: Switch to use String#titleize if hyper-operation removes that patch + key.rpartition(".")[-1].split("_").map(&:capitalize).join(" ") end def l(time, format = :default, opts = {}) Hyperstack::Internal::I18n.l(time, format, opts) end + + protected + + def translation_missing?(translation) + translation.is_a?(String) && translation =~ /^translation missing:/ + end end end diff --git a/ruby/hyper-i18n/spec/hyper_i18n_spec.rb b/ruby/hyper-i18n/spec/hyper_i18n_spec.rb index 6a85d00c4..540e02025 100644 --- a/ruby/hyper-i18n/spec/hyper_i18n_spec.rb +++ b/ruby/hyper-i18n/spec/hyper_i18n_spec.rb @@ -16,11 +16,15 @@ class TestComponent DIV(id: :tp4) { l(Time.parse('1/1/2018 12:45'), '%B %d, %Y at %l:%M %P') } DIV(id: :tp5) { MyModel.model_name.human } DIV(id: :tp6) { MyModel.human_attribute_name('the_attribute') } + DIV(id: :tp7) { t(:hello) } + DIV(id: :tp8) { t(:hello_world) } + DIV(id: :tp9) { t(:that_other_key) } end end end end end + [['component rendering', :client_only], ['prerendering', :server_only]].each do |mode, flag| it "will translate during #{mode}", prerendering_on: flag == :server_only do mount 'Components::TestComponent', {}, render_on: flag @@ -30,6 +34,9 @@ class TestComponent expect(find('#tp4')).to have_content(::I18n.l(Time.parse('1/1/2018 12:45'), format: '%B %d, %Y at %l:%M %P')) expect(find('#tp5')).to have_content('My Model') expect(find('#tp6')).to have_content('The Attribute') + expect(find('#tp7')).to have_content('Hello world') + expect(find('#tp8')).to have_content('Hello World') + expect(find('#tp9')).to have_content('I am another key') end end end diff --git a/ruby/hyper-i18n/spec/test_app/config/locales/en.yml b/ruby/hyper-i18n/spec/test_app/config/locales/en.yml index 6244e97b0..9014a9c36 100644 --- a/ruby/hyper-i18n/spec/test_app/config/locales/en.yml +++ b/ruby/hyper-i18n/spec/test_app/config/locales/en.yml @@ -9,3 +9,5 @@ en: components: test_component: the_key: I am a key + test_component: + that_other_key: I am another key