Invalidate Latte language
- jeremy
- Member | 54
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 | 864
@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
@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 | 864
@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 | 1261
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 | 54
@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 | 864
@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)
- jeremy
- Member | 54
@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)