Why I think you can’t overwrite translations in SW6
Fabian Blechschmidt
I’m building a Shopware 6 shop and we implement a custom theme for our customer. To change the HTML structure we change templates, which is fine, but from time to time we only want to replace a translation, so I tried it.
Use your own translation and „just do it“
Shopware 6 has a good explanation how to implement your own translation. So we implemented it but having a string which is already part of the default translation doesn’t change on the frontend.
So either by adding an autoloader json or your own translation via services.xml, loading PHP class and JSON file
return (new \Shopware\Core\System\Snippet\Files\SnippetFileCollectionFactory(new RewindableGenerator(function () {
yield 0 => (new \Prems\Plugin\PremsOnePageCheckout6\Resources\snippet\en_GB\SnippetFile_en_GB());
yield 1 => (new \Prems\Plugin\PremsOnePageCheckout6\Resources\snippet\de_DE\SnippetFile_de_DE());
yield 2 => ($this->services['SwagI18nItalian\\Resources\\app\\storefront\\snippet\\SnippetFile_it_IT'] ?? ($this->services['SwagI18nItalian\\Resources\\app\\storefront\\snippet\\SnippetFile_it_IT'] = new \SwagI18nItalian\Resources\app\storefront\snippet\SnippetFile_it_IT()));
yield 3 => ($this->services['SwagI18nItalian\\Resources\\app\\core\\snippet\\SnippetFile_it_IT'] ?? ($this->services['SwagI18nItalian\\Resources\\app\\core\\snippet\\SnippetFile_it_IT'] = new \SwagI18nItalian\Resources\app\core\snippet\SnippetFile_it_IT()));
yield 4 => (new \PayonePayment\Resources\translations\de_DE\SnippetFile_de_DE());
yield 5 => (new \PayonePayment\Resources\translations\en_GB\SnippetFile_en_GB());
yield 6 => ($this->services['SwagI18nFrench\\Resources\\app\\storefront\\snippet\\SnippetFile_fr_FR'] ?? ($this->services['SwagI18nFrench\\Resources\\app\\storefront\\snippet\\SnippetFile_fr_FR'] = new \SwagI18nFrench\Resources\app\storefront\snippet\SnippetFile_fr_FR()));
yield 7 => ($this->services['SwagI18nFrench\\Resources\\app\\core\\snippet\\SnippetFile_fr_FR'] ?? ($this->services['SwagI18nFrench\\Resources\\app\\core\\snippet\\SnippetFile_fr_FR'] = new \SwagI18nFrench\Resources\app\core\snippet\SnippetFile_fr_FR()));
yield 8 => (new \YourPlugin\Resources\snippet\de_DE\YourPlugin_de_DE());
yield 9 => (new \YourPlugin\Resources\snippet\en_GB\YourPlugin_en_GB());
}, 10), new \Shopware\Core\System\Snippet\Files\SnippetFileLoader(($this->services['kernel'] ?? $this->get('kernel', 1)), ($this->services['Doctrine\\DBAL\\Connection'] ?? $this->getConnectionService()), new \Shopware\Core\System\Snippet\Files\AppSnippetFileLoader(\dirname(__DIR__, 4)), ($this->privates['Shopware\\Core\\Framework\\App\\ActiveAppsLoader'] ?? $this->getActiveAppsLoaderService()))))->createSnippetFileCollection();
And when I saw that I was super happy, because the loading order is fine and I didn’t understand what is going on. But after debugging it even further I understood. It is hidden at the end of the last line.
While the translations are loaded, all translations, which have a php file to load are cached and therefore loaded first. After that Shopware 6 is autoloading all so called \Shopware\Core\System\Snippet\Files\GenericSnippetFile in \Shopware\Core\System\Snippet\Files\SnippetFileLoader::loadPluginSnippets and therefore the default translation inside the core (which is autoloader) is loaded AFTER all our translations.
Order of translation load
There is no definable order on loading translations, except:
Everything with a php file first
every generic translation after
How to fix?
Shyim had the brilliant idea to easily fix it (Thanks!). so I implemented a PR for that: