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!
1 Like
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;
}