-
Notifications
You must be signed in to change notification settings - Fork 49
Translation parameters support #104
Comments
Placeholders with "%placeholder%" are already in use in the Zend-Form component. They have the huge benefit that you can preg_search your whole HTML body for unreplaced placeholders. If you forget the value for ":scored_points" the output will use the value of ":score" twice and scramble the output. if (preg_match_all('~%[a-z0-9-_]+%~iu', $response, $matches) > 0) {
// oh uh!
} Also the length of the placeholder is clearly marked, so the order of replacement is irrelevant. (Well except in erroneous (?) cases where you replace one placeholder with another, the value of parameter "%scored_points%" is "%score%"...). ":placeholder:" is in use in the zend-router component, but they are for route-parameters. "%placeholder%" in the form component is directly used for placeholder in translations. |
@MatthiasKuehneEllerhold Erroneous cases like the one you mentioned by replacing one placeholder with another is prevented with
|
Sorry if I mixed my points. You said for using I meant that the order of replacement is only relevant if we're using placeholders without end markers (e. g. ":placeholder"). If we're using end markers (e. g. "%placeholder%") the order is irrelevant except in the mentioned erroneous case. For example using message = 'You scored :score points with a :score_percentage% success!';
echo str_replace(
$message,
[
':score' => 50,
':score_percentage' => 99,
]
);
// Outputs "You scored 50 points with a 50_percentage% success!" Using either But using end-markers this can't happen: message = 'You scored %score% points with a %score_percentage%% success!';
echo str_replace(
$message,
[
'%score%' => 50,
'%score_percentage%' => 99,
]
);
// Outputs "You scored 50 points with a 99% success!" TL;DR: I think the end-markers are direly necessary. |
Yes, I understand you now. So basically we have 2 cases here. Having that sorted out, the next thing to decide is whether to use the Next thing on the list is whether the usage will be (1) or (2).
|
We're using internally (1) (no marks in the parameters) because this way its easier for the end user to define the parameters. And thats why we're using foreach and |
This repository has been closed and moved to laminas/laminas-i18n; a new issue has been opened at laminas/laminas-i18n#7. |
The Idea
Recently we talked on Slack about having parameters support for translated strings.
I made a research of how other frameworks are already doing it.
Other Frameworks
Here is the documentation on how it is implemented in Symfony and in Laravel.
Symfony
I like how Symfony uses PHP's
strtr
here: https://github.com/symfony/translation/blob/master/Formatter/MessageFormatter.php#L42-L45However, I don't like the usage with those percent
%
characters as they make the string less readable, e.g.You scored %scored_points% points and you pass the exam with %score%% success!
.Laravel
I don't like Laravel's replacement implementation as this is a fairly large amount of code for such a simple task. However, I like how they name their parameters with a leading colon
:
, eg.:scored_points
,:score
, which makes the string a little bit easier to read. The previous example would becomeYou scored :scored_points points and you pass the exam with :score% success!
My suggested approach
It will be best to use colon-prefixed parameters (readability) and
strtr
, which takes into account other parameters' names, regarding of the order they are defined (in contrast to Laravel's approach to usestr_replace
with sorted parameters), meaning that if the parameterized string contains both:score
and:scored_points
, the value for former would not overwrite the latter, unless the parameter has not been passed.Implementation
I want to do and will do a PR, but first I want to discuss with you the idea and what are the possible solutions, taking into account the current state of this component. I would like to hear your opinion and suggestions.
The current methods can be changed, thus introducing a BC Break (the feature will be released with the next major version). Currently there are 2 methods in the
TranslatorInterface
:translate
andtranslatePlural
, which may be modified as follows:The text was updated successfully, but these errors were encountered: