-
Notifications
You must be signed in to change notification settings - Fork 921
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
Add locale selector #5201
base: master
Are you sure you want to change the base?
Add locale selector #5201
Conversation
What's the advantage of adding the language icon to the sprite map (three times) as opposed to rendering an |
@AntonKhorev Currently, as I found in the project, for icons we use |
64c4f7e
to
e02866a
Compare
Thank you for the review @tomhughes I've updated accordingly |
Currently we use both app/assets/images/sprite.svg is mainly used for buttons inside Leaflet map views, where we don't entirely control html. |
@AntonKhorev Okay, thanks. I'll update it to |
e02866a
to
713eaaa
Compare
PR was updated to include SVG in the HTML. I tried several different methods to move SVG from sprite, including adding it to the SvgHelper module and adding separate file for it, but current solution turned out to be the most optimal one (SvgHelper had conflicts with the linter because of long lines and separate file was not sufficiently customizable with Bootstrap classes). |
app/views/layouts/_header.html.erb
Outdated
<li> | ||
<% if current_user && current_user.id %> | ||
<%= link_to(preferences_path) do %> | ||
<%= render "shared/language_selector", :hoverable => true, :black => true, :classes => "dropdown-item", :disabled => true %> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dropdown-item
here doesn't entirely work, and possibly other Bootstrap classes either don't work as expected or are missing. Some related odd behavior of language link/label:
- not logged in, no compact mode: no focus outline
- not logged in, compact mode: same + keyboard up/down controls stop working correctly
- logged in, no compact mode: focus outline is present but non-standard because no
nav-link
, but if you add it you'll need more css fixes - logged in, compact mode: keyboard controls also not working correctly, in a slightly different manner
Does this thing need to be inside the secondary menu, collapsible into "more"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll try to solve the focusing issue without any custom classes. In terms of collapsibility of the translation icon, purpose was to take as little space as possible when the screen is smaller. Without collapsing, HTML code will be shorter and with less "if-else"-es.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you still want this icon collapsing into More?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll try to move it out of the "More" and test with different resolutions. If it doesn't break any resolution, I'll keep it out of the "More". It will need less HTML code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated this PR. Tried several solutions and current one needed the smallest and cleanest code. Also, one CSS class was added .text-transparent
to make text and background of the <select>
tag visually hidden but still focusable.
Language selector will no more be moved to the compact menu. Visually it doesn't take much space and contextually it's more relevant to be as an icon than as a compacted menu button.
713eaaa
to
34d2e25
Compare
34d2e25
to
f5754b8
Compare
Looks like the languages you get from |
41cb49e
to
80708ff
Compare
<% unless disabled %> | ||
<select role="button" class="p-0 position-absolute top-0 start-0 w-100 h-100 language-change-trigger text-transparent bg-transparent <%= classes %>"> | ||
<% Locale.available | ||
.map { |locale| Language.find_by(:code => locale.to_s) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'll get a ton of db queries:
Language Load (0.2ms) SELECT "languages".* FROM "languages" WHERE "languages"."code" = $1 LIMIT $2 [["code", "af"], ["LIMIT", 1]]
↳ app/views/shared/_language_selector.html.erb:8
Language Load (0.3ms) SELECT "languages".* FROM "languages" WHERE "languages"."code" = $1 LIMIT $2 [["code", "ar"], ["LIMIT", 1]]
↳ app/views/shared/_language_selector.html.erb:8
Language Load (0.3ms) SELECT "languages".* FROM "languages" WHERE "languages"."code" = $1 LIMIT $2 [["code", "az"], ["LIMIT", 1]]
↳ app/views/shared/_language_selector.html.erb:8
Language Load (0.3ms) SELECT "languages".* FROM "languages" WHERE "languages"."code" = $1 LIMIT $2 [["code", "be"], ["LIMIT", 1]]
↳ app/views/shared/_language_selector.html.erb:8
Language Load (0.3ms) SELECT "languages".* FROM "languages" WHERE "languages"."code" = $1 LIMIT $2 [["code", "bg"], ["LIMIT", 1]]
↳ app/views/shared/_language_selector.html.erb:8
...
<% Locale.available | ||
.map { |locale| Language.find_by(:code => locale.to_s) } | ||
.select { |locale| locale } | ||
.sort_by { |locale| locale[:english_name] } | ||
.each do |language| %> | ||
<option class="form-select" value="<%= language.code %>" <%= "selected" if I18n.locale.to_s == language.code %>><%= language.name %></option> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using Language table is probably a bad idea. I tried this:
<% Locale.available | |
.map { |locale| Language.find_by(:code => locale.to_s) } | |
.select { |locale| locale } | |
.sort_by { |locale| locale[:english_name] } | |
.each do |language| %> | |
<option class="form-select" value="<%= language.code %>" <%= "selected" if I18n.locale.to_s == language.code %>><%= language.name %></option> | |
<% Locale.available | |
.select { |locale| I18n.exists? "shared.language_selector.language", :locale => locale, :fallback => false } | |
.sort_by { |locale| locale.to_s == "en" ? "English" : t(".language", :locale => locale) } | |
.each do |locale| %> | |
<option class="form-select" value="<%= locale.to_s %>" <%= "selected" if I18n.locale.to_s == locale.to_s %>><%= locale.to_s == "en" ? "English" : t(".language", :locale => locale) %></option> |
with this in locale file:
share:
language_selector:
language: THIS LANGUAGE NAME
Now translators have to add whatever is the appropriate representation of their language there, and then it will appear in the selector.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pushed code can be shortened as Language.where(:code => Locale.available.map {|locale| locale.to_s})
. This approach will also cause only one DB query. If there is no other reason for language not to be used, I'll push the code with this approach. Translating language names using i18n and not having one source for them, may cause duplicate translations or inconsistency (because of multiple functionalities using language names).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Translating language names using i18n and not having one source for them
i18n is going to be their one source
may cause duplicate translations or inconsistency (because of multiple functionalities using language names).
We already have two different functionalities using two different sets of languages: i18n and languages of diary entries.
80708ff
to
25fd157
Compare
This PR was updated according to the suggestion of @AntonKhorev. As described in the
Because of this, currently only English is shown in the list of language selector. At first, I thought to make a list of all language names in the config file, but when translations will be made, there will be a lot of duplication. The only downside of the current solution is that there will be only those languages shown, which have |
Those that have translations that are maintained, so not much of a downside. I also had a more defensive version of that key with |
This PR addresses "Language switcher on the homepage" issue mentioned in #1115
This PR is mainly based on #5077, #3618 and #4461. As solution using Wikimedia selector added external files, many lines of CSS and JS code, this version takes inspiration from #4461 and creates a reusable language selector using
<select>
tag.Language selector button, to be consistent, is not hidden when the user is logged in. Instead, it redirects to the "My Preferences" page, where user can change language preferences. When the user is logged out, clicking language selector opens language selection menu.
The reason for logged in user redirection instead of any complex functionality of preferred language change while clicking language selector, was compatibility with the PR #4461. After both PRs will be merged, there will be one smooth simple UX flow for logged in users. Plus, it makes finding language selection page much easier for new users.
Default view of the language selector:
Opened language selector:
Mobile view of the selector:
This PR has many different visual impacts, so to make description shorter instead of directly adding images, I'll add links to them.
LTR screenshots:
Medium resolution menu
Medium resolution menu hover
Small resolution menu
RTL screenshots:
Default view
Medium resolution menu
Small resolution menu