We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

It would be convenient to just be able to use a templating filter multilingualism

It would be convenient to just be able to use a templating filter multilingualism

{# tr filter #} {{ Hello|translate }}



98.9k

If you have a service for multi-lingualism, you can use:

$compiler = $volt->getCompiler();

$compiler->addFilter('translate', function($resolvedArgs) {
    return '$this->trans->query(' . $resolvedArgs . ')';
});

If you pass a variable ($t) to your views, you can use:

$compiler = $volt->getCompiler();

$compiler->addFilter('translate', function($resolvedArgs) {
    return '$t->query(' . $resolvedArgs . ')';
});

If you have a static method, you can use:

$compiler = $volt->getCompiler();

$compiler->addFilter('translate', function($resolvedArgs) {
    return 'My\Translate::query(' . $resolvedArgs . ')';
});

If you have a PHP function, you can use:

$compiler = $volt->getCompiler();

$compiler->addFilter('translate', function($resolvedArgs) {
    return 'my_translate(' . $resolvedArgs . ')';
});

https://docs.phalcon.io/en/latest/reference/volt.html#id2

Almost perfect, but the placeholders passed to my filter are not being replaced by the values.

Here is how I assigned translator to volt as a filter:


// Translator
$di->set('translator', function() use ($app, $config) {

    $language = $app->request->getBestLanguage();

    $baseCatalogPathTemplate = APP_ROOT . "resources/translations/messages.%s.php";
    $languageCatalogPath = sprintf($baseCatalogPathTemplate, $language);
    $fallbackCatalogPath = sprintf($baseCatalogPathTemplate, $config->locale);

    $messagesCatalog = file_exists($languageCatalogPath) ? require $languageCatalogPath : require $fallbackCatalogPath;

    return new NativeArray(["content" => $messagesCatalog]);
});

// Template Engine
$di->set('view', function() {
    $view = new View();

    $view
        ->setViewsDir(__DIR__ . '/../resources/views/')
        ->registerEngines(array(
            '.volt' => function($view, $di) {
                $options = [
                    'compileAlways' => (APP_ENV != APP_ENV_PROD),
                    'compiledPath' => APP_ROOT . '/cache/views/'
                ];

                $volt = new Volt($view, $di);

                $volt->setOptions($options);

                $volt->getCompiler()->addFilter('trans', function($resolvedArgs) {
                    return '$this->translator->query(' . $resolvedArgs . ')';
                });

                return $volt;
            }
        ))
    ;

    return $view;
});

Here is a snippet from a volt template that is being translated, but the placeholders were not replaced with variables, as they should be:


{{ 'Foo has value %foo%'|trans(['%foo%': 'bar']) }}

Forget about my last comment, it works. The volt statement should be:

{{ 'Foo has value %foo%'|trans(['foo': 'bar']) }}

Another questions/suggestion: shouldn't the translator replace the placeholders by values if it doesn't find a translation to the message (a very common behaviour that we can find on other implementations, like in symfony translator)?