# Internationalization (i18n) Guide ## Installation ```bash composer require symfony/translation symfony/yaml ``` ## Core Implementation ### LocaleConfig Value Object ```php // src/Core/Application/ValueObjects/LocaleConfig.php final class LocaleConfig { public function __construct( public readonly string $defaultLocale, public readonly array $supportedLocales, public readonly string $fallbackLocale, ) {} public static function fromEnvironment(): self { return new self( $_ENV['APP_LOCALE'] ?? 'en', explode(',', $_ENV['APP_SUPPORTED_LOCALES'] ?? 'en,de,fr'), $_ENV['APP_FALLBACK_LOCALE'] ?? 'en', ); } } ``` ### Translation Manager ```php // src/Core/Internalization/TranslationManagerInterface.php interface TranslationManagerInterface { public function trans(string $key, array $parameters = [], ?string $domain = null): string; public function setLocale(string $locale): void; public function addResource(string $format, mixed $resource, string $locale, ?string $domain = null): void; } // src/Core/Internalization/TranslationManager.php final class TranslationManager implements TranslationManagerInterface { private Translator $translator; public function __construct(LocaleConfig $localeConfig) { $this->translator = new Translator($localeConfig->defaultLocale); $this->translator->setFallbackLocales([$localeConfig->fallbackLocale]); $this->translator->addLoader('yaml', new YamlFileLoader()); } public function trans(string $key, array $parameters = [], ?string $domain = null): string { return $this->translator->trans($key, $parameters, $domain); } public function setLocale(string $locale): void { $this->translator->setLocale($locale); } public function addResource(string $format, mixed $resource, string $locale, ?string $domain = null): void { $this->translator->addResource($format, $resource, $locale, $domain); } } ``` ### Bootstrapper ```php // src/Core/Application/Bootstrapper/TranslationInitializer.php class TranslationInitializer implements BootstrapperInterface { public function bootstrap(InflectableContainer $container): void { $container->set(LocaleConfig::class, LocaleConfig::fromEnvironment()); $container->bind(TranslationManagerInterface::class, TranslationManager::class, [LocaleConfig::class]); $this->loadTranslationFiles($container); } private function loadTranslationFiles(InflectableContainer $container): void { $manager = $container->get(TranslationManagerInterface::class); $config = $container->get(LocaleConfig::class); // Load framework translations foreach ($config->supportedLocales as $locale) { $file = dirname(__DIR__, 4) . "/translations/{$locale}/messages.yaml"; if (file_exists($file)) { $manager->addResource('yaml', $file, $locale, 'messages'); } } // Load module translations foreach (glob(dirname(__DIR__, 3) . '/Modules/*/translations/*/messages.yaml') as $file) { $parts = explode('/', $file); $locale = $parts[count($parts) - 2]; $manager->addResource('yaml', $file, $locale, 'messages'); } } } ``` ### Helper Functions ```php // src/Core/Internalization/helpers.php function trans(string $key, array $parameters = []): string { global $container; static $translator = null; $translator ??= $container->get(TranslationManagerInterface::class); return $translator->trans($key, $parameters); } function __(string $key, array $parameters = []): string { return trans($key, $parameters); } ``` ## Usage ### Directory Structure ``` translations/en/messages.yaml translations/de/messages.yaml src/Modules/{Module}/translations/en/messages.yaml ``` ### Translation Files (YAML) ```yaml # translations/en/messages.yaml welcome: title: "Welcome to Foundation" message: "Hello, %name%!" user: profile: "User Profile" ``` ### Controller Usage ```php class WelcomeController implements ControllerInterface { public function __construct(private readonly TranslationManagerInterface $translator) {} public function index(): ResponseInterface { $title = $this->translator->trans('welcome.title'); $message = __('welcome.message', ['%name%' => 'John']); // ... } } ``` ### Environment Configuration ```env APP_LOCALE=en APP_SUPPORTED_LOCALES=en,de,fr APP_FALLBACK_LOCALE=en ```