GettextTranslator – plurály
- kybermonty
- Člen | 10
Zdravím,
zajímalo by mě, jak konkrétně rozjedu plurály přes GettextTranslator
v Nette.
Například ve formuláři mám tuto validaci:
addRule(Form::MIN_LENGTH, 'The password is too short: it must be at least %d characters', 3);
A chtěl bych udělat překlad pro 3 tvary slova characters – znak, znaky, znaků.
Našel jsem, že v PO souboru se množné čísla zapisují nějak takto:
msgid "The password is too short: it must be at least %d character"
msgid_plural "The password is too short: it must be at least %d characters"
msgstr[0] "Heslo je moc krátké: musí mít minimálně %d znak"
msgstr[1] "Heslo je moc krátké: musí mít minimálně %d znaky"
msgstr[2] "Heslo je moc krátké: musí mít minimálně %d znaků"
Ale netuším, jak tohle konkrétně rozjet v implementaci formuláře, případně jestli se dají řešit plurály i v šabloně.
Díky za jakýkoliv tip.
- romansklenar
- Člen | 655
V dokumentaci tohoto doplňku jsou i příklady použití na formuláři i na šabloně. Co konkrétně ti není jasné?
- kybermonty
- Člen | 10
Není mi jasné, proč se v PO souboru uvádějí dvě verze zdrojového překladu – msgid a msgid_plural – když ve formuláři mám jen jednu verzi.
- romansklenar
- Člen | 655
Pokud ještě nebudou v po souboru řetězce přeloženy, tak by se měl jako plurál českého plurálu použít ten anglický. Nejspíš proto.
- kybermonty
- Člen | 10
Díky, teď je mi to už jasné.
Ale zjistil jsem, že formulář v Nette hází špatný překlad, protože Translatoru předává jenom řetězec bez parametru. Např. v mém příkladu:
addRule(Form::MIN_LENGTH, 'The password is too short: it must be at least %d character', 3);
Se Translatoru nepředá parametr 3, takže se character přeloží jako „znak“.
Dá se to vyřešit tak, že v Forms\Renderers\InstantClientScript.php a v Forms\Rules.php se změní
$rule->control->translate($rule->message)
na
$rule->control->translate($rule->message, $rule->arg)
A v Forms\Controls\FormControl.php se upraví metoda validate:
public function translate($s, $p = NULL)
{
$translator = $this->getTranslator();
if ($translator === NULL) {
return $s;
}
if ($p == NULL || !is_int($p)) {
return $translator->translate($s);
}
return $translator->translate($s, $p);
}
To is_int trochu bije do očí, ale je to jenom takový nástřel řešení.
- David Grudl
- Nette Core | 8228
Oříšek je v tom, jestli se dá paušálně považovat argument validátoru za počet pro translátor.
Dejme tomu, že asi jo. Fixed.