[DX][D8] See if there is a backwards-compatible way to make `t()` be always available (get rid of `st()` and `get_t()`)
I missed the change record for https://www.drupal.org/node/1838310 in D8.x: Removed st() and get_t(), just use t() in place, simple!
It seems that the foundation for that was done in #1813762: Introduce unified interfaces, use dependency injection for interface translation and after all that, there was #2018411: Figure out a nice DX when working with injected translation as a follow-up.
Would it be possible to do the same in Backdrop, while not breaking backwards compatibility? It would be a nice DX+ to not have to consider what to use when adding translatable strings - just use t() everywhere.
Starting this as a task for now, to see if it is achievable without API breakages. We can then either change this issue to a feature request, or file a separate feature request issue later.
Supposing no module calls directly st(), it would be achievable by:
- Using a static variable for the name of the class that returns translated strings
- Changing
get_t()to always return't'
During the bootstrap, the class name stored in that static variable is changed from the name of the class that looks for translations in files (like st() does) to the name of the class that looks for translations in the database, via locale().
locale() is defined in a Backdrop core module, which means it cannot be called until the bootstrap phase is BACKDROP_BOOTSTRAP_FULL.
When a translation is necessary, t() will create an object using the value of that static variable as class name and use it to obtain the translation.
function t($string, array $args = array(), array $options = array()) {
$translator = new (get_translation_class());
if ($translator) {
// …
}
}
There are 30 Backdrop functions/methods that directly call st(). Their code should be checked to understand whether that is intentional or just a "I, function, I am called when database, theme, and localization system are possibly not yet available" case.
Supposing no module calls directly
st()...
Very good point 👍🏼 ...I guess that if this is possible, then we should remove usage in core, and leave things in for backwards compatibility for contrib and custom code. Then decide if it is to be removed in 2.0.
If there are modules that directly call st(), that can fixed with three lines more; otherwise, st() can be just removed.
function st($string, array $args = array(), array $options = array()) {
return t($string, $args, $options);
}
The standard profile uses st() also. I was going to file an issue about the impossibility of translating the welcome message that the standard profile creates for the Hero block during installation in https://github.com/backdrop/backdrop/blob/df0481c9cd7e4b1ebc77c3eed745426cdd195bd8/core/profiles/standard/standard.profile#L27
I was going to propose to use get_t(), but it would be much better to apply this approach here, I guess. So this is my two cents about it. Let's get rid of st()!