MaSa759
September 26, 2024, 8:21am
1
Hi,
I want to set up different languages for my application. Therefore I configured my routes like this:
[
'type' => 'segment',
'options' => [
'route' => '[/:lang]/',
'defaults' => [],
'constraints' => [
'lang' => '(de|en|fr)'
]
],
'may_terminate' => true,
'child_routes' => [ ... ]
]
All other routes are child-routes.
My expectations are like this:
default language (de)
/foo
/bar
english
/en/foo
/en/bar
french
/fr/foo
/fr/bar
Unfortunately the current configuration throws an exception: InvalidArgumentException: Missing parameter “lang” on generating the urls. If I set a default [‘lang’ => ‘de’] all generated links always have the default-language as part of the url
/de/foo
/de/bar
Is there a way around that?
zigu007
September 28, 2024, 11:47am
2
I assume you are using laminas-view Url Helper? One way could be to override the url generation method.
MaSa759
September 30, 2024, 5:32am
3
Redirects have the same issue. It is more a routing-problem, I guess.
MaSa759
September 30, 2024, 5:32am
4
Customizing the routers assemble()-method would be my idea, but I don’t see how the router could be overwritten. Is there a way?
I found the same issue was mentioned before:
But the provided solution doesen’t work anymore. Is there really no out-of-the-box-solution for that? As it is a pretty common SEO-requirement.
Omitting the url-segment, if it matches the default-value would be in my opinion the expected behaviour. Because currently, it is not really optional - it is required (at least for the assambly).
The reason given for that behaviour (Segment route always renders optional params if route has childs · Issue #6697 · zendframework/zendframework · GitHub ) is maybe better solved by adding constraints or redesigning the url concept.
You convinced me, overriding \Laminas\View\Helper\Url and \Laminas\Mvc\Controller\Plugin\Url seems to be the way to go. Thanks!
Please check the following library:
Auto detection of locale through different strategies for Zend Framework 2
It works as you need if you use optional constraint for lang.
The following is adapted from my route config that I use for multilingual web applications.
'routes' => [
'home' => [
'type' => Segment::class,
'options' => [
'route' => '[/:lang]/',
'constraints' => [
'lang' => '[de|en|fr]*'
],
'defaults' => [
'lang' => 'de',
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
'may_terminate' => true,
'child_routes' => [
'test' => [
'type' => Literal::class,
'options' => [
'route' => 'test/',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'test',
],
],
],
'test-segment' => [
'type' => Segment::class,
'options' => [
'route' => ':action/[:id/]',
'constraints' => [
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'test-segment',
],
],
],
]
],
],
And controller actions:
public function indexAction()
{
$lang = $this->params()->fromRoute('lang');
print $lang;
exit;
}
public function testAction()
{
$lang = $this->params()->fromRoute('lang');
print $lang;
exit;
}
public function testSegmentAction()
{
$lang = $this->params()->fromRoute('lang');
$id = $this->params()->fromRoute('id', 0);
print $lang;
print '<br>';
print $id;
exit;
}