Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Raise error if translations are used in initializer #1666

Merged
merged 7 commits into from
Mar 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ nav_order: 5

## main

* Raise error if translations are used in initializer.

*Joel Hawksley*

## v3.0.0.rc5

* Fix bug where `mkdir_p` failed due to incorrect permissions.
Expand Down
6 changes: 3 additions & 3 deletions lib/view_component/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ def config
attr_writer :config
end

class ViewContextCalledBeforeRenderError < StandardError; end

include ViewComponent::Slotable
include ViewComponent::Translatable
include ViewComponent::WithContentHelper

ViewContextCalledBeforeRenderError = Class.new(StandardError)

RESERVED_PARAMETER = :content

# For CSRF authenticity tokens in forms
Expand Down Expand Up @@ -197,7 +197,7 @@ def helpers
if view_context.nil?
raise(
ViewContextCalledBeforeRenderError,
"`#helpers` can't be used during initialization, as it depends " \
"`#helpers` can't be used during initialization as it depends " \
"on the view context that only exists once a ViewComponent is passed to " \
"the Rails render pipeline.\n\n" \
"It's sometimes possible to fix this issue by moving code dependent on " \
Expand Down
11 changes: 11 additions & 0 deletions lib/view_component/translatable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,17 @@ def store_translations(locale, data, options = EMPTY_HASH)
end

def translate(key = nil, **options)
if view_context.nil?
raise(
ViewComponent::Base::ViewContextCalledBeforeRenderError,
"`#translate` can't be used during initialization as it depends " \
"on the view context that only exists once a ViewComponent is passed to " \
"the Rails render pipeline.\n\n" \
"It's sometimes possible to fix this issue by moving code dependent on " \
"`#translate` to a `#before_render` method: https://viewcomponent.org/api.html#before_render--void."
)
end

return super unless i18n_backend
return key.map { |k| translate(k, **options) } if key.is_a?(Array)

Expand Down
2 changes: 0 additions & 2 deletions performance/components/translatable_component.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# frozen_string_literal: true

class Performance::TranslatableComponent < ViewComponent::Base
include ViewComponent::Translatable

def initialize(key)
@key = key
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class InitializerTranslationsComponent < ViewComponent::Base
def initialize
@title = t(".title")
end
end
1 change: 0 additions & 1 deletion test/sandbox/app/components/translatable_component.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# frozen_string_literal: true

class TranslatableComponent < ViewComponent::Base
include ViewComponent::Translatable
end
8 changes: 8 additions & 0 deletions test/sandbox/test/rendering_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,14 @@ def test_renders_component_with_translations
assert_selector("h2", text: I18n.t("translations_component.subtitle"))
end

def test_renders_component_with_initializer_translations
err =
assert_raises ViewComponent::Base::ViewContextCalledBeforeRenderError do
render_inline(InitializerTranslationsComponent.new)
end
assert_includes err.message, "can't be used during initialization"
end

def test_renders_component_with_rb_in_its_name
render_inline(EditorbComponent.new)

Expand Down