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

Compiling volt templates

Hi, guys! Please help to solve one problem: We implement multi-lingual support and have translation files, like this: $messages = array( 'test' => '%num% {{ plural(%num%, ["page", "pages"]) }}' );

We use Phalcon\Translate\Adapter\NativeArray to translate text: $t->_("test", array("num" => 5))

It will produce: 5 {{ plural(5, ["page", "pages"]) }};

But, we need to compile this result to receive: 5 pages

Function plural is already implemented and added to volt compiler.

This clearly substitutes your text for multi-lingual and does not recompile the volt expression and function for that matter.

I have not tested this but you could consider adding the multilingual capability in your volt function plural. I am thinking something like this:


$translator = $this->di->get('translator');

function plural($pages) use ($translator) {
    if ($pages > 9) {
        return $pages . ' ' . $translator->translate('pages');
    } else {
        return $pages . ' ' . $translator->translate('page');
    }
}

and then the code in volt will be

{{ plural(5) }}


1.9k

Nikolas, thanks. But, indeed, your solution does not answer the question of a topic. As kudmni wrote, function plural is already implemented and it works. The problem is - after applying some translation function _t string 5 {{ plural(5, ["page", "pages"]) }}; is returned. How to make volt to render it again - i.e. to apply plural function (but, certainly, it can contain any other volt function).

@edim24 I am not sure you can, unless you have _t render the string again and I don't think that it is possible but I might be wrong.

Volt functions are string replacements so to speak. They produce strings that would be then parsed by the template. So in this instance the function does what it is supposed to i.e. it produces the {{ plural(5, ['page', 'pages'] }} and that is what is printed on screen. Once the plural is printed on screen volt has completed its cycle and _t will not be called to do its magic.

Thanks, Nikolaos! But your solution doesn't solve our problem. We rejected double compiling of template. Instead of this, we modified function t to parse translated text and process plural templates in it. Here are code examples: en.php php<?php return array( 'total_pages' => 'Total: %num% {{ plural(%num%, "page", "pges") }}' ); Template code: html{{ t('total_pages', {'num': 100500}) }} Function t source code php$compiler->addFunction('t', function($resolvedArgs, $exprArgs) use ($compiler) { $translateKey = $compiler->expression($exprArgs[0]['expr']); $placeholders = empty($exprArgs[1]['expr']) ? 'null' : $compiler->expression($exprArgs[1]['expr']); $language = empty($exprArgs[2]['expr']) ? 'null' : $compiler->expression($exprArgs[2]['expr']); return '$this->lng->getPluralTranslation(' . $translateKey . ', ' . $placeholders . ', ' . $language . ')'; }); Function getPluralTranslation translates text, then finds plural templates and replaces it with right plural forms. As result we have: textTotal: 100500 pages Cons of our solution are: we implement only one function (plural). To support other volt functions (in texts to translate) we need to modify getPluralTranslation.