I18n will generate a I18nContextInterface
object at every request which is accessible via the resolver
service I18nContextResolverInterface
. Which means, that you're able to fetch the I18nContextInterface
via [DI] $contextResolver->getContext($request)
wherever a valid frontend-request is available!
The I18n Context contains a LocaleDefinitionInterface
object, which contains all locale information about the requested locale.
The I18n Context contains a RouteItemInterface
object, which terminates the right route process.
- If the i18n context gets resolved via request, the route item will be generated depending on the request attributes (static route, symfony route, document)
- If the i18n context gets resolved by a headless context generation or a simple
url(route_name, {})
, the route item will be generated depending on the route parameters (static route, symfony route, document)
The I18n Context contains a ZoneInterface
object, which holds all active zone information (allowed/active locales, bounded
domains)
Each ZoneInterface
object is able to contain one or more ZoneSiteInterface
objects. Each Site contains dedicated information
and also provides an SiteRequestContext
object. The site request context holds some important information (like host
, port
)
which are required when it comes to absolute URL generation!
I18n will decorate the router
service. This is required to provide a simple way generating URLs in different contexts (twig, API, command line).
The I18nRouter automatically takes care about the correct router context. If you need absolute URLs for example, just set UrlGeneratorInterface::ABSOLUTE_URL
and you're good to go.
Every LinkGenerator needs to implement the I18nLinkGeneratorInterface
and should extend from the AbstractRequestAwareLinkGenerator
!
This is required to:
- allow i18n to generate translatable static routes by itself.
- prevent the request from being used
- simplify the path construction
generate()
method anymore.
If you're supporting/using Object-Links within WYSIWYG/Link-Elements, the AbstractRequestAwareLinkGenerator
will do the job for you.
However, like this class already implies it by its class name, it requires a valid request and therefor it only should be used
for the generation of links inside WYSIWYG/Link-Elements.
<?php
namespace App\Service;
use I18nBundle\LinkGenerator\AbstractRequestAwareLinkGenerator;
use I18nBundle\LinkGenerator\I18nLinkGeneratorInterface;
use I18nBundle\Model\RouteItem\LinkGeneratorRouteItemInterface;
use Pimcore\Model\DataObject\ClassDefinition\LinkGeneratorInterface;
use Pimcore\Model\DataObject\Concrete;
class ObjectLinkGenerator extends AbstractRequestAwareLinkGenerator implements LinkGeneratorInterface, I18nLinkGeneratorInterface
{
public function getStaticRouteName(Concrete $object): string
{
return 'test_route';
}
public function generateRouteItem(Concrete $object, LinkGeneratorRouteItemInterface $linkGeneratorRouteItem): LinkGeneratorRouteItemInterface
{
$linkGeneratorRouteItem->getRouteParametersBag()->set('object_id', $object->getId());
return $linkGeneratorRouteItem;
}
// the generate() method is available via AbstractRequestAwareLinkGenerator
// and should ONLY be used for links which are coming from WYSIWYG/Link-Elements.
}
If you want to use the pimcore object preview, you may want to use the included generator.
Just add the Service @I18nBundle\PreviewGenerator\ObjectPreviewGenerator
in your class definition.
This will add:
- A locale selection (Default value: Current Admin-Users default locale. If not available, the first locale from the list will be selected)
- A site selection (Only, if Sites are available. Default value: Current Host. If not available, the first site from the list will be selected)
PIMCORE static routes are in yaml
format now and this allows us to determinate the static route patterns via container parameters:
i18n:
translations:
- key: 'myStaticRouteKey'
values:
de: 'meine-statische-route'
en: 'my-static-route'
pimcore:
staticroutes:
definitions:
60f02a5d-eb8f-4fb2-859a-0a3c77b472f9:
name: my_static_route
pattern: '/([a-zA-Z0-9-_]*)\/(?:%i18n.route.translations.myStaticRouteKey%)\/(.*?)$/' ## returns (meine-statische-route|my-static-route)
reverse: '/{%%_locale}/@myStaticRouteKey/%%object_id'
controller: App\Controller\DefaultController::staticRouteAction
variables: '_locale,object_id'
defaults: null
siteId: null
methods: null
priority: 1
creationDate: 1634472684
modificationDate: 1634472684
I18n also supports (localized) symfony routes.
You need to pass the _i18n
default flag (can be an array or just a boolean flag).
my_symfony_route:
path:
de: /de/i18n/symfony-default-rut
fr: /fr/i18n/symfony-default-ruteee
de_CH: /de-ch/i18n/symfony-default-route-guetzli
en: /en/i18n/symfony-default-route
controller: App\Controller\DefaultController::symfonyRouteAction
defaults:
_i18n: true
Every I18n translation key is available as a regex parameter (i18n.route.translations.TRANSLATION_KEY_NAME
).
This allows you to define translations at a global scope and is much cleaner to configure
i18n:
translations:
- key: 'mySymfonyRouteKey'
values:
de: 'meine-symfony-route'
en: 'my-symfony-route'
my_symfony_route:
path: /{_locale}/i18n/{matching_route_key}
controller: App\Controller\DefaultController::symfonyRouteAction
defaults:
_i18n:
translation_keys:
matching_route_key: mySymfonyRouteKey
requirements:
matching_route_key: '(%i18n.route.translations.mySymfonyRouteKey%)' ## returns (meine-symfony-route|my-symfony-route)
- Current Request Routes for Documents
- Current Request Routes for Static Routes
- Current Request Routes for Symfony Routes
Generating absolute URLs in CLI is easy!
I18n always requires the _i18n
parameter node in urlGenerator->generate
.
If this node is not present, the default route generation will be triggered.
dump($router->generate('my_non_i18n_aware_symfony_route', ['_locale' => 'en'], UrlGeneratorInterface::ABSOLUTE_URL));
I18n allows you to easily fetch the current context via a given request object. Read more about it here.
Generating a complete headless context object via twig or php api. Read more about it here.
Please check out the code examples doc section to learn more about accessing zone information.