-
-
Notifications
You must be signed in to change notification settings - Fork 6
feat: Use associative array for strings on keyboard search page 🗺️ #604
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
Conversation
mcdurdin
left a comment
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.
This is a nice clean start. But I am asking for a bunch of changes to make it more extensible long-term. Thanks!
_includes/locale/Locale.php
Outdated
| public const CROWDIN_LOCALES = array( | ||
| 'en', | ||
| 'es-ES', | ||
| 'fr-FR' | ||
| ); |
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 think this should be in a separate file, or perhaps determined on a per-domain basis, because we have multiple l10n domains (i.e. keyboards is one localization domain). See my comments re filenames and folder names further down
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.
with the glob refactor below, this can go away
_includes/locale/Locale.php
Outdated
| public static function validateLocale($locale) { | ||
| return in_array($locale, Locale::CROWDIN_LOCALES); | ||
| } |
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.
This may not be viable because we may not have localizations for a given l10n domain.
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.
Can you give an example?
We can set the list of available languages on
https://crowdin.com/project/keymancom/settings#languages
(would need the sil_ltops login to add custom languages)
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.
removed with the glob refactor.
_includes/locale/Locale.php
Outdated
| private static $langArrayEn = []; | ||
|
|
||
| /** | ||
| * Return the current locale. Fallback to 'en' |
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.
Fallback should really be through a path, e.g. given es-ES, we should fallback first to es, then to en.
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.
So should setLocale() split on dashes for determining fallback.
e.g. with es-ES we end up with
self::$currentLocales = ['es', 'es-ES', 'en'];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.
There are algorithms for fallback already. See https://cldr.unicode.org/development/development-process/design-proposals/language-distance-data
That might be too much for us. @srl295 may have suggestions on simpler approaches.
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.
Moved to calculateFallbackLocales() where we can always reimplement in a TODO
_includes/locale/Locale.php
Outdated
| 'es-ES', | ||
| 'fr-FR' |
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.
These should be minimal BCP-47 tags - i.e. we would use es-419 for Latin America and Caribbean, es for Spain. Similar for French, should be just fr, not fr-FR (we would use fr-CA for example).
_includes/locale/Locale.php
Outdated
| * @param $s - the format string | ||
| * @param $args - optional remaining args to the format string | ||
| */ | ||
| public static function _s($s, ...$args) { |
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.
Ditto on no _ needed. I would have the one public function though (and make _m into a private getString()):
public static function m($domain, $id, ...args) {
$str = self::getString($domain, $id);
if(count($args) == 0) return $str;
return vsprintf($str, $args);
}
_includes/locale/Locale.php
Outdated
| * Return the current locale. Fallback to 'en' | ||
| * @return $currentLocale | ||
| */ | ||
| public static function currentLocale() { |
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.
This should return an array of available locales in priority order, e.g. for es-ES, we'd go ['es-ES', 'es', 'en']. This way, we can support fallback more neatly in the future, even if we initially only go with one fallback to en.
keyboards/index.php
Outdated
| $head_options = [ | ||
| 'title' =>'Keyboard Search', | ||
| 'description' => 'Keyman Keyboard Search', | ||
| 'title' =>Locale::_m('page_title'), |
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.
| 'title' =>Locale::_m('page_title'), | |
| 'title' => _m('page_title'), |
keyboards/index.php
Outdated
| use Keyman\Site\com\keyman\templates\Foot; | ||
| use Keyman\Site\com\keyman\Locale; | ||
|
|
||
| Locale::localize('keyboards'); |
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.
// To make the localization inserts cleaner and DRY, we can do this:
| Locale::localize('keyboards'); | |
| function _m($id) { return Locale::m('keyboards', $id); } |
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.
Will it get messy if every page we localize has to add?
function_m($id) {...}or should we just move it to Localize.php()?
| if(isset($_REQUEST['lang'])) { | ||
| \Keyman\Site\com\keyman\Locale::overrideCurrentLocale($_REQUEST['lang']); | ||
| } else if (isset($_SESSION['lang'])) { | ||
| \Keyman\Site\com\keyman\Locale::overrideCurrentLocale($_SESSION['lang']); | ||
| } | ||
| $_SESSION['lang'] = \Keyman\Site\com\keyman\Locale::currentLocale(); | ||
|
|
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.
It would be good to look at best practices around embedding locale in query strings vs path or domain etc. We need to consider our technology stack in making this decision.
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.
Yep, I've copied this as a bullet point on the issue to investigate
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.
From SO: "Does the locale belong on the path or as a request parameter on the URL?
https://stackoverflow.com/a/16471122
If you need it as request parameter or part of the url depends of what you want to achieve. If you want to serve static content, you should have it be part of the path. If you want to act dynamically on the chosen locale, you should use it as request parameter, since you don't want to have your scripts replicated several times over different paths just to add different locales.
| * @param $id - the id for the string | ||
| * @param $args - optional remaining args to the format string | ||
| */ | ||
| public static function m($domain, $id, ...$args) { |
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.
Why m?
I might overlook the obvious, but currently I have a hard time seeing a connection between m and getting a localized string. I could make sense of s, t, or l, but for m I'm missing the association (which then makes it harder to use the function if I can't remember it).
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'm open to any clear name. In the previous iteration #516, we were using Locale::_s() for formatted strings.
That version was also using _ gettext, but we're not setting locales this time.
739ee14 to
70f48e6
Compare
|
|
||
| return [ | ||
| # Page Title | ||
| "page_title" => "Keyboard Search", |
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 think this is ready for another round of review comments. This one is still unresolved.
For now, I'm just using |
Can we use the |
| 'description' => 'Keyman Keyboard Search', | ||
| 'title' => _m('page_title'), | ||
| 'description' => _m('page_description'), | ||
| 'language' => isset($_SESSION['lang']) ? $_SESSION['lang'] : 'en', |
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.
This will set the lang attribute for the entire page.
Unless we need to apply it separately to all the
tags involving localized strings below...
Maybe as a starting point? We do eventually need a way for:
|
* Remove CROWDIN_LOCALES * Update setLocale to parse the locale for the fallback tags
Moved to calculateFallbackLocales() so we can replace as TODO
6b929d9 to
76c9d0a
Compare
e687164 to
ed1c38b
Compare
mcdurdin
left a comment
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.
Let's go with this -- it's reasonably generalized now and we can at least move forward with some localization!
_includes/2020/templates/Menu.php
Outdated
| private static function render_globe_dropdown(): void { | ||
| ?> | ||
| <p> | ||
| <div id="ui-language" class="menu-item"> |
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.
This will result in two divs with the same id, which is not really right. We need to keep them unique.
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.
Updated to pass a div number so we can assign "id" = ui-language or ui-language1
in f1f8a62
|
Hmm. something to chase down on why the link checker is now 7x longer
|
|
And the link checker is back to 20 min with 4fe6b0c |
Prerequisites
Test Results
|


Replaces the PR chain #516 in addressing #384 of localizing the keyboard search
From the A19S11 sprint design meeting, we pivoted from using .po locale files to localizing strings in associative arrays.
This PR reuses earlier Locale.php work to go in that direction on the main keyboard search page.
For now, locale is passed with the query parameter
lang=(e.g.lang=esorlang=fr).This also adds a globe icon to the top right for selecting UI language (passing the lang parameter)
Limitation: Currently session is set in keyboards/session.php so the rest of the site is ignoring the lang query parameter
TODO's on follow-on PRs
User Testing
Setup - Run the keyman.com and website-local-proxy sites locally with docker