locastic/symfony-translation-bundle
Locastic Symfony Translation Bundle integrates translation management into Symfony applications, helping developers organize and maintain multilingual content alongside Symfony’s built-in translation component.
Install and inspect before wiring anything up.
composer require locastic/symfony-translation-bundle
With only 3 stars and 0 known dependents, treat the install as a code review exercise first. Open vendor/locastic/symfony-translation-bundle/ and read, in this order:
README.md — install/config snippets and stated Symfony version support*Bundle.php class — namespace and bundle name you must registerDependencyInjection/Configuration.php — the real config tree (this is the source of truth; READMEs for small bundles drift)composer.json — require constraints tell you which Symfony versions are actually supportedRegister the bundle manually. There is almost certainly no Flex recipe for a package this small. Add the bundle class to config/bundles.php:
return [
// ...
Locastic\SymfonyTranslationBundle\LocasticSymfonyTranslationBundle::class => ['all' => true],
];
Confirm the exact class name from the *Bundle.php file rather than guessing.
Create a minimal config file at config/packages/locastic_translation.yaml (match the vendor prefix used by the bundle's extension alias — check Configuration::getAlias()). Start with the smallest possible config: default locale, fallback locales, and whatever storage/loader option the bundle exposes.
First use case: pick one existing translation domain (e.g. messages) and route it through the bundle, then verify:
bin/console debug:translation en --domain=messages
bin/console debug:container translator
If the bundle provides a DB-backed loader or an editing UI, import a handful of existing YAML keys first rather than migrating the whole catalog. Verify a single key renders correctly in a controller and in Twig before expanding.
Keep YAML as the source of truth, use the bundle as an overlay. For a low-adoption bundle, the safest pattern is: existing translations/*.yaml files stay authoritative, and the bundle supplies an additional loader, admin UI, or locale-management layer on top. This lets you remove the bundle later without losing translations.
Decorate, don't replace, the translator. If the bundle swaps the translator service, prefer a decorator or a custom loader so the rest of the app keeps injecting Symfony\Contracts\Translation\TranslatorInterface unchanged:
final class BundleBackedTranslator implements TranslatorInterface
{
public function __construct(
private TranslatorInterface $inner,
private Repository $translations,
) {}
// delegate, then fall back to $this->translations
}
DB-backed catalogs need a cache warmer. Translation catalogs are compiled and cached in prod. If the bundle stores translations in a table, add a cache warmer or a kernel.terminate listener that clears the translation cache pool when rows change. Otherwise editors change a string and nothing happens until deploy.
Locale switching. If the bundle provides a locale listener or switcher, wire it as a request listener and expose it via a route (/_locale/{locale}) with an allow-list of supported locales. Validate the locale against %kernel.enabled_locales% or your own config — never trust the URL parameter.
Twig and controllers stay idiomatic:
{{ 'checkout.title'|trans({}, 'checkout') }}
$translator->trans('checkout.title', [], 'checkout');
Don't call bundle-specific services from templates; keep the translation API as the boundary.
Environment split. Enable any admin/editing UI only in dev and a protected admin environment. In prod, the bundle should only contribute a loader or a read-only cache.
Testing pattern. In a KernelTestCase, assert on rendered output rather than on bundle internals:
self::assertSame('Checkout', $translator->trans('checkout.title'));
Add one smoke test per configured locale, including a fallback locale, so a broken config fails CI rather than production.
Pin and constrain. Because the last release is April 2023, pin an exact version in composer.json and add a CI job that runs composer why-not symfony/framework-bundle 7 (or your target version) so an upgrade doesn't silently break.
Adoption risk is the headline gotcha. 3 stars, 0 dependents, and a last release in 2023 mean no community backstop. Read the source, check open issues, check the license, and budget for the possibility that you maintain a fork. Wrap the bundle behind your own service interface so replacement is a one-file change.
Symfony 7 compatibility is unverified. The 2023 release likely targets Symfony 5.4/6.x. Run composer update --dry-run and the test suite on your target Symfony before committing. Watch for removed/renamed services and the ContainerBuilder API changes.
No Flex recipe means manual wiring. Expect to write config/bundles.php and the config YAML yourself, and to debug the extension alias. If the config key doesn't match what the README shows, trust Configuration.php — then open an issue or patch the README.
Translation cache is the classic "it works in dev" trap. In prod, compiled catalogs are cached. After changing translations, always bin/console cache:clear (or the warmer) and verify with debug:translation. If the bundle writes to a DB, this is the #1 source of "the editor saved it but the site is unchanged".
Fallback locales hide missing keys. If en falls back to hr, a missing en key silently renders Croatian. Run debug:translation en --only-missing after every import to catch gaps introduced by the bundle's loader.
Bundle registration order and compiler passes. If the bundle registers a compiler pass that touches the translator, it can conflict with other bundles doing the same. Check getContainerExtension() and any CompilerPass classes; debug with bin/console debug:container translator --show-arguments.
Extension points to look for: a custom LoaderInterface implementation, an event dispatcher for post-write hooks, and a configurable cache pool. These are the seams to use instead of forking. If none exist, that's a strong signal to keep the bundle at the edge of your architecture.
Don't let it become critical path. Add a feature test that boots the kernel with the bundle disabled (or with an empty config) to prove your app still serves translations from YAML. If that test can't pass, the bundle is doing too much.
How can I help you explore Laravel packages today?