Invalidate Latte language

jeremy
Member | 46
+
0
-

Hi, is it possible to invalidate cached Latte based on language? Or do I have to delete all Latte cache when specific language translations get updated.

For example:

{_'path:to:translation'}

Caches the template with the translated value and it doesn't call the translate function when the page loads again, which is what I want, but I need to invalidate the cache if the value of the translation changes.

I know that I can solve that by using dynamic translations like so:

{var $translation = 'path:to:translation'}
{_$translation}

But I'd prefer to just cache the translated values.

m.brecher
Generous Backer | 729
+
0
-

@jeremy

but I need to invalidate the cache if the value of the translation changes.

Delete all /temp/cache/latte files after changes of any one source latte file xxxx.latte is a standard way in Nette Framework. If you have multi-language latte files, than it is necessary delete all /temp/cache/latte files also in case of changes of the translations (usually stored in a database).

Dynamic translations you have mentioned in your sample:

{var $translation = ‘path:to:translation’}
{_$translation}

need also deleting all cached latte files in case of any change, so it solves nothing.

If you inspect latte cached files carefully, you see, that it would be theoretically possible to delete by hand only those cached files that have changed, but such a procedure would be extremely complicated with permanent risk that you forgot delete all changed files. So deleting all cached files is the best way.

Last edited by m.brecher (2023-07-19 04:25)

dakur
Member | 493
+
0
-

@jeremy What you are talking about are probably not cached templates, but cached translations. Templates do not contain any translated texts, they just contain calls to translator which resolve the correct translations.

But as this resolving (specifically parsing from whatever format (e.g. .neon) to plain PHP arrays) is expensive, resolved translations are cached – therefore you need to remove temp/translation (not sure about the folder name and path, but it has the translation/translator word in it).

According to what translation package you use, it might have some caching configuration to customize the experience to your needs. Note that on production instance, you should always cache the translations, otherwise you run into performance issues quickly. On the other hand, on development machine, it makes sense to disable the cache. But many packages handle this automatically. What do you use?

Last edited by dakur (2023-07-19 10:08)

m.brecher
Generous Backer | 729
+
0
-

@dakur

Templates do not contain any translated texts

Latte creates for every language one compiled file with translated text. The translations are automatically taken from the translator but only in debugMode = true, thats why it is necessary on production server delete cached latte files. You can prove this by inspecting compiled latte files in multilanguage Nette project.

Marek Bartoš
Nette Blogger | 1161
+
+1
-

Whether translated messages are stored in compiled Latte files and therefore permanently cached depends on how TranslatorExtension was registered. To prevent translations being cached by Latte and let the caching be done (optionally) by translator itself, simply does not add any cache key – see https://github.com/…xtension.php#…

jeremy
Member | 46
+
0
-

@m.brecher

{var $pageTitle = 'pageTitle:default'}
{_'pageTitle:default'}
{_$pageTitle}

Equals to this in the cached file:

$pageTitle = 'pageTitle:default' /* line 26 */;

echo LR\Filters::escapeHtmlText('Dashboard') /* line 27 */;

echo LR\Filters::escapeHtmlText(($this->filters->translate)($pageTitle)) /* line 28 */;

So dynamic translations in my case at least don't require deleting all cached latte.
I have my own NeonTranslator that decodes all found locale files and saves all the translations to a single one-dimensional array.
For example locale/en.neon:

forms:
	fields:
		name: Name
		...
	errors:
		required: Required
	...

is then saved as:

[
	forms:fields:name => 'Name',
	forms:errors:required => 'Required'
	...
]

After that I cache the array and if ‘en’ locale files are changed, added or deleted, I delete the cache for that specific language.
I wanted to do the same for the latte cache that have the ‘en’ key, but at least for now I don't think that's possible in a simple way.
For the time being I can either stop using the locale key when registering the translator ($this->setTranslator($translator, $locale)) or delete the entire cache/latte directory whenever translations change.
I am gonna go with the latter, but it would be nice if in the future deleting cached latte based on the provided locale key was possible.

@dakur @MarekBartoš

m.brecher
Generous Backer | 729
+
0
-

@MarekBartoš

Whether translated messages are stored in compiled Latte files and therefore permanently cached depends on how TranslatorExtension was registered

let the caching be done (optionally) by translator itself, simply does not add any cache key

I implement template translations this simple way:

abstract class BasePresenter extends Presenter
{
    public function beforeRender()
    {
        parent::beforeRender();
        $this->template->setTranslator( $this->translator, $this->lang);
		// .....
    }
}

Translator is my own class, no extension, having just one deppendency – database, no manipulation with cache key. In this base case Latte cached translations in compiled template files in production mode by default.

Last edited by m.brecher (2023-07-20 12:25)

m.brecher
Generous Backer | 729
+
0
-

@jeremy

So dynamic translations in my case at least don't require deleting all cached latte.

Yes, you are right, I was wrong.

I delete the cache for that specific language.

It is some native solution for this in Latte ? Or you use some extension for this ?

jeremy
Member | 46
+
0
-

@m.brecher

It is some native solution for this in Latte ? Or you use some extension for this ?

I made my own translator that works that way. If a locale hasn't been cached yet, then I compile all the neon files for that specific language and use a cache callback function to check if any of the files is changed, added or removed. It also checks if all files are valid and if not, then it either throws an exception or caches the rest of the valid files depending on if production mode is on/off.
That allows me to delete the cache just for 1 language. I wanted to do the same with latte cache, but it's not possible right now, at least not easily.

Last edited by jeremy (2023-07-20 13:42)