Language and Translation Hooks
The seven hooks over text: resolving a translation, saving one, sweeping a pack, and adding, removing or configuring a language.
Overview
Text travels two ways: a key resolves and reaches the screen, or a translation is saved and reaches the disk. Each end carries a filter.
Beside them sit the events of the pack itself: opening one, deleting one, changing its settings. A new pack is not born empty; it is copied from an existing language.
Reference
Changing a resolved text
Runs after a translation key resolves to text. Every piece of text in the system passes here: it is a hot path, so keep it light.
Hook::add('filter:i18n.translation', 10, function (&$value, $key, $lang) {
// Every text passes here: sift on the key first.
if ($key !== 'website/home/title') return;
$value = Acme::brandedTitle($lang);
});Adjusting translations before they are saved
Runs before translations are written to disk. The array you hold is what gets written.
Hook::add('filter:i18n.translation_save', 10, function (&$values, $id) {
// A value may be plain text or an array.
foreach ($values as $k => $v)
if (is_string($v)) $values[$k] = trim($v);
});Following a translation being saved
Runs after a translation key is saved.
Hook::add('action:i18n.translation_saved', 10, function ($key, $saved) {
// The list holds what CHANGED, not what was submitted.
foreach ($saved as $lang) Acme::invalidateCache($lang, $key);
});Following a bulk replacement
Runs after a word is replaced throughout one language pack.
Hook::add('action:i18n.bulk_replaced', 10, function ($lang, $word, $replacement, $changed) {
// The counter holds what changed, not what was selected.
Acme::auditSweep($lang, $word, $changed);
});Following a language being added
Runs after a new language pack is opened. The pack does not start empty: it is built as a copy of an existing one.
Hook::add('action:language.added', 10, function ($key, $copied_from) {
// The pack starts full of the source texts: put it in the translation queue.
Acme::queueTranslation($key, $copied_from);
});Following a language being deleted
Runs after a language pack is deleted.
Hook::add('action:language.deleted', 10, function ($key) {
Acme::dropTranslations($key);
});Following language settings changing
Runs after the settings of a language are saved.
Hook::add('action:language.settings_updated', 10, function ($id, $package) {
Acme::syncLocale($id, $package);
});Pitfalls
Every piece of text passes through it, hundreds of times on a single page. Sift on the key before doing anything heavy, and leave straight away for calls you do not care about.
The list carried by the translation save event holds only the languages whose value actually changed. Languages submitted unchanged are absent, so do not answer "which languages were sent" from it.
Related Articles
Thanks for your feedback!
Our support team is here around the clock for anything you can't find above.