diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 194ca71a6..1d20235cc 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -10,6 +10,10 @@ nav_order: 6 ## main +* Fix `Component.translate` raising `UncaughtThrowError` for keys missing from the sidecar translations, and `NoMethodError` for components without sidecar translations. It now falls back to the global translations, like the instance method does. Fix `translate` returning the `default:` value instead of an existing global translation. + + *Andrii Furmanets* + * Only recompile components when a template or a translation file changed, instead of before every request, when templates aren't cached. Pages render about twice as fast in development. *Clément Joubert* diff --git a/lib/view_component/translatable.rb b/lib/view_component/translatable.rb index 815a1325e..c4d532451 100644 --- a/lib/view_component/translatable.rb +++ b/lib/view_component/translatable.rb @@ -59,7 +59,11 @@ def translate(key = nil, **options) locale = options.delete(:locale) || ::I18n.locale key = __vc_i18n_key(key, options.delete(:scope)) - __vc_i18n_backend.translate(locale, key, options) + if __vc_i18n_backend&.exists?(locale, key) + __vc_i18n_backend.translate(locale, key, options) + else + ::I18n.translate(key, locale: locale, **options) + end end alias_method :t, :translate @@ -102,17 +106,8 @@ def translate(key = nil, **options) __vc_html_escape_translation_options!(options) if as_html - if key.start_with?(__vc_i18n_scope + ".") - translated = - catch(:exception) do - __vc_i18n_backend.translate(locale, key, options) - end - - # Fallback to the global translations - if translated.is_a? ::I18n::MissingTranslation - return @view_context.translate(key, locale: locale, **options) - end - + if __vc_i18n_backend.exists?(locale, key) + translated = __vc_i18n_backend.translate(locale, key, options) translated = __vc_html_safe_translation(translated) if as_html translated else diff --git a/test/sandbox/test/translatable_test.rb b/test/sandbox/test/translatable_test.rb index bd1cdc0e8..806cf1caa 100644 --- a/test/sandbox/test/translatable_test.rb +++ b/test/sandbox/test/translatable_test.rb @@ -165,6 +165,32 @@ def test_translating_from_the_class assert_equal({sidecar: "This is coming from the sidecar"}, TranslatableComponent.translate(".from")) end + def test_translating_from_the_class_falls_back_to_global_translations + assert_equal "This is coming from Rails", TranslatableComponent.t("from.rails") + assert_equal "Relative key from Rails", TranslatableComponent.t(".relative_rails_key") + assert_equal "Translation missing: en.translatable_component.missing", TranslatableComponent.t(".missing") + assert_equal "Default", TranslatableComponent.t(".missing", default: "Default") + + assert_raises(I18n::MissingTranslationData) do + TranslatableComponent.t(".missing", raise: true) + end + end + + def test_translating_from_the_class_without_sidecar_translations + assert_equal "OH NO! (you shouldn't see me)", MyComponent.t(".message") + assert_equal "This is coming from Rails", MyComponent.translate("from.rails") + end + + def test_default_does_not_shadow_global_translations + assert_equal "This is coming from Rails", TranslatableComponent.t("from.rails", default: "Default") + assert_equal "Relative key from Rails", TranslatableComponent.t(".relative_rails_key", default: "Default") + assert_equal "Default", TranslatableComponent.t(".missing", default: "Default") + + assert_equal "This is coming from Rails", translate("from.rails", default: "Default") + assert_equal "Relative key from Rails", translate(".relative_rails_key", default: "Default") + assert_equal "Default", translate(".missing", default: "Default") + end + def test_inheriting_and_overriding_translations render_inline(TranslatableSubclassComponent.new)