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

Internationalize/I18n the Dashboard Engine #497

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env-example
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
CHANGELOG_GITHUB_TOKEN=
GOOGLE_TRANSLATE_API_KEY=
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ gem 'rails'

platforms :ruby do
gem "activerecord-explain-analyze"
gem 'i18n-tasks'
gem "memory_profiler"
gem "pry-byebug"
gem "rbtrace"
Expand Down
18 changes: 18 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,21 @@ GEM
rake (>= 10.0)
globalid (1.0.0)
activesupport (>= 5.0)
highline (2.0.3)
html_tokenizer (0.0.7)
i18n (1.9.1)
concurrent-ruby (~> 1.0)
i18n-tasks (1.0.5)
activesupport (>= 4.0.2)
ast (>= 2.1.0)
better_html (~> 1.0)
erubi
highline (>= 2.0.0)
i18n
parser (>= 2.2.3.0)
rails-i18n
rainbow (>= 2.2.2, < 4.0)
terminal-table (>= 1.5.1)
jdbc-postgres (42.2.25)
kramdown (2.3.1)
rexml
Expand Down Expand Up @@ -300,6 +312,9 @@ GEM
nokogiri (>= 1.6)
rails-html-sanitizer (1.4.2)
loofah (~> 2.3)
rails-i18n (7.0.3)
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 8)
railties (6.1.4.6)
actionpack (= 6.1.4.6)
activesupport (= 6.1.4.6)
Expand Down Expand Up @@ -371,6 +386,8 @@ GEM
actionpack (>= 5.2)
activesupport (>= 5.2)
sprockets (>= 3.0.0)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
thor (1.2.1)
timers (4.3.3)
tomlrb (2.0.1)
Expand Down Expand Up @@ -410,6 +427,7 @@ DEPENDENCIES
gem-release
github_changelog_generator
good_job!
i18n-tasks
kramdown
kramdown-parser-gfm
mdl
Expand Down
127 changes: 127 additions & 0 deletions config/i18n-tasks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# i18n-tasks finds and manages missing and unused translations: https://github.com/glebm/i18n-tasks

# The "main" locale.
base_locale: en
## All available locales are inferred from the data by default. Alternatively, specify them explicitly:
# locales: [es, fr]
## Reporting locale, default: en. Available: en, ru.
# internal_locale: en

# Read and write translations.
data:
read:
- engine/config/locales/%{locale}.yml
- engine/config/locales/**/*.%{locale}.yml

# Locale files to write new keys to, based on a list of key pattern => file rules. Matched from top to bottom:
# `i18n-tasks normalize -p` will force move the keys according to these rules
write:
## For example, write devise and simple form keys to their respective files:
# - ['{devise, simple_form}.*', 'config/locales/\1.%{locale}.yml']
## Catch-all default:
# - config/locales/%{locale}.yml

# External locale data (e.g. gems).
# This data is not considered unused and is never written to.
external:
## Example (replace %#= with %=):
# - "<%#= %x[bundle info vagrant --path].chomp %>/templates/locales/%{locale}.yml"

## Specify the router (see Readme for details). Valid values: conservative_router, pattern_router, or a custom class.
# router: conservative_router

yaml:
write:
# do not wrap lines at 80 characters
line_width: -1

## Pretty-print JSON:
# json:
# write:
# indent: ' '
# space: ' '
# object_nl: "\n"
# array_nl: "\n"

# Find translate calls
search:
paths:
- engine/app
relative_roots:
- engine/app/controllers
- engine/app/helpers
- engine/app/views

## Directories where method names which should not be part of a relative key resolution.
# By default, if a relative translation is used inside a method, the name of the method will be considered part of the resolved key.
# Directories listed here will not consider the name of the method part of the resolved key
#
# relative_exclude_method_name_paths:
# -

## Files or `File.fnmatch` patterns to exclude from search. Some files are always excluded regardless of this setting:
## %w(*.jpg *.png *.gif *.svg *.ico *.eot *.otf *.ttf *.woff *.woff2 *.pdf *.css *.sass *.scss *.less *.yml *.json *.map)
exclude:
- app/assets/images
- app/assets/fonts
- app/assets/videos

## Alternatively, the only files or `File.fnmatch patterns` to search in `paths`:
## If specified, this settings takes priority over `exclude`, but `exclude` still applies.
# only: ["*.rb", "*.html.slim"]

## If `strict` is `false`, guess usages such as t("categories.#{category}.title"). The default is `true`.
# strict: true

## Multiple scanners can be used. Their results are merged.
## The options specified above are passed down to each scanner. Per-scanner options can be specified as well.
## See this example of a custom scanner: https://github.com/glebm/i18n-tasks/wiki/A-custom-scanner-example

## Translation Services
# translation:
# # Google Translate
# # Get an API key and set billing info at https://code.google.com/apis/console to use Google Translate
# google_translate_api_key: "AbC-dEf5"
# # DeepL Pro Translate
# # Get an API key and subscription at https://www.deepl.com/pro to use DeepL Pro
# deepl_api_key: "48E92789-57A3-466A-9959-1A1A1A1A1A1A"
# # deepl_host: "https://api.deepl.com"
# # deepl_version: "v2"

## Do not consider these keys missing:
# ignore_missing:
# - 'errors.messages.{accepted,blank,invalid,too_short,too_long}'
# - '{devise,simple_form}.*'

## Consider these keys used:
ignore_unused:
- "activerecord.attributes.*"
- "datetime.*"

## Exclude these keys from the `i18n-tasks eq-base' report:
# ignore_eq_base:
# all:
# - common.ok
# fr,es:
# - common.brand

## Exclude these keys from the `i18n-tasks check-consistent-interpolations` report:
# ignore_inconsistent_interpolations:
# - 'activerecord.attributes.*'

## Ignore these keys completely:
# ignore:
# - kaminari.*

## Sometimes, it isn't possible for i18n-tasks to match the key correctly,
## e.g. in case of a relative key defined in a helper method.
## In these cases you can use the built-in PatternMapper to map patterns to keys, e.g.:
#
# <%# I18n::Tasks.add_scanner 'I18n::Tasks::Scanners::PatternMapper',
# only: %w(*.html.haml *.html.slim),
# patterns: [['= title\b', '.page_title']] %>
#
# The PatternMapper can also match key literals via a special %{key} interpolation, e.g.:
#
# <%# I18n::Tasks.add_scanner 'I18n::Tasks::Scanners::PatternMapper',
# patterns: [['\bSpree\.t[( ]\s*%{key}', 'spree.%{key}']] %>
6 changes: 3 additions & 3 deletions engine/app/controllers/good_job/base_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module GoodJob
class BaseController < ActionController::Base # rubocop:disable Rails/ApplicationController
protect_from_forgery with: :exception

before_action :set_locale
around_action :switch_locale
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you prefer around_action over before_action?


content_security_policy do |policy|
policy.default_src(:none) if policy.default_src(*policy.default_src).blank?
Expand All @@ -30,8 +30,8 @@ def default_url_options(options = {})

private

def set_locale
I18n.locale = current_locale
def switch_locale(&action)
I18n.with_locale(current_locale, &action)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you prefer with_locale?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. I like that with_locale only changes the locale within the context of the block and then returns to the previous value. Because the Goodjob engine is running in the context of a parent application, I don't want to change the I18n.locale value globally because it might have an unexpected side effect in the parent application.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to know, yes, we don't want unexpected behavior 👍

Thank you for the info

end

def current_locale
Expand Down
12 changes: 0 additions & 12 deletions engine/app/helpers/good_job/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,5 @@ def status_badge(status)

content_tag :span, status.to_s, class: classes
end

def language_options
available_languages.map { |locale| language_option(locale) }.join
end

def language_option(locale)
link_to locale, url_for(locale: locale), class: "dropdown-item"
end

def available_languages
I18n.available_locales.reject { |locale| locale == I18n.locale }
end
end
end
29 changes: 16 additions & 13 deletions engine/app/views/good_job/shared/_navbar.erb
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,29 @@
</li>
<li class="nav-item">
<div class="nav-link">
<span class="badge bg-secondary"><%= t(".commig_soon") %></span>
<span class="badge bg-secondary"><%= t(".coming_soon") %></span>
</div>
</li>
</ul>
<div class="navbar-nav">
<div class="nav-item pe-2">
<div class="nav-item pe-2">
<div class="form-check">
<input type="checkbox" id="toggle-poll" name="toggle-poll" data-gj-action='change#togglePoll' <%= 'checked' if params[:poll].present? %>>
<label for="toggle-poll"><%= t(".live_poll") %></label>
</div>
<div class="nav-item">
<div class="dropdown">
<button class="btn btn-primary btn-sm dropdown-toggle" type="button" id="localeOptions" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<%= I18n.locale %>
</button>
<div class="dropdown-menu" aria-labelledby="localeOptions">
<%== language_options %>
</div>
</div>
</div>
</div>
<ul class="navbar-nav">
<li class="nav-item dropdown">
<a href="#" class="nav-link dropdown-toggle" type="button" id="localeOptions" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<%= I18n.locale %>
</a>

<ul class="dropdown-menu" aria-labelledby="localeOptions">
<% I18n.available_locales.reject { |locale| locale == I18n.locale }.each do |locale| %>
<li><%= link_to locale, url_for(locale: locale), class: "dropdown-item" %></li>
<% end %>
</ul>
</li>
</ul>
</div>
</div>
</nav>
57 changes: 48 additions & 9 deletions engine/config/locales/en.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,56 @@
---
en:
datetime:
distance_in_words:
about_x_hours:
one: about 1 hour
other: about %{count} hours
about_x_months:
one: about 1 month
other: about %{count} months
about_x_years:
one: about 1 year
other: about %{count} years
almost_x_years:
one: almost 1 year
other: almost %{count} years
half_a_minute: half a minute
less_than_x_minutes:
one: less than a minute
other: less than %{count} minutes
less_than_x_seconds:
one: less than 1 second
other: less than %{count} seconds
over_x_years:
one: over 1 year
other: over %{count} years
x_days:
one: 1 day
other: "%{count} days"
x_minutes:
one: 1 minute
other: "%{count} minutes"
x_months:
one: 1 month
other: "%{count} months"
x_seconds:
one: 1 second
other: "%{count} seconds"
x_years:
one: 1 year
other: "%{count} years"
good_job:
shared:
announcement:
work_in_progress_html: "🚧 GoodJob's dashboard is a work in progress. Please contribute ideas and code on <a href=\"https://github.com/bensheldon/good_job/issues\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Github</a>."
footer:
last_update_html: Last updated <time id="page-updated-at" datetime="%{time}">%{time}</time>
wording: Remember, you're doing a Good Job too!
navbar:
commig_soon: More views coming soon
coming_soon: More views coming soon
cron_schedules: Cron Schedules
current_time: Now is %{time}
executions: All Executions
jobs: All Jobs
name: GoodJob 👍
processes: Processes
live_poll: Live Poll
announcement:
work_in_progress_html: 🚧 GoodJob's dashboard is a work in progress. Please contribute ideas and code on <a href="https://github.com/bensheldon/good_job/issues" target="_blank" rel="nofollow noopener noreferrer">Github</a>.
footer:
last_update_html: Last updated <time id="page-updated-at" datetime="%{time}">%{time}</time>
wording: Remember, you're doing a Good Job too!
name: "GoodJob 👍"
processes: Processes
Loading