I have a CakePHP website with many internal links, that are build with the HtmlHelper
:
/app/View/MyController/myaction.ctp
<?php
echo $this->Html->link(
$item['Search']['name'],
array(
'controller' => 'targetcontroller',
'action' => 'targetaction',
$profileId,
$languageId
)
);
?>
It works fine with the default route:
/app/Config/routes.php
Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
The generated links look like that: /mycontroller/myaction/$profileId/$languageId
.
Now I want to use search engine friendly URLs (with profile names and ISO-639-1 language codes instead of IDs) for a part of the website and added a new Route:
/app/Config/routes.php
Router::connect(
'/:iso6391/:name.html',
array('controller' => 'mycontroller', 'action' => 'myaction'),
array(
'iso6391' => '[a-zA-Z]+',
'name' => '[0-9a-zA-ZäöüßÄÖÜ\-]+',
)
);
And it also works fine and the incomming URIs like /producer/en/TestName.html
are interpreted correctly.
But the HtmlHelper
is still generating the old URIs like /mycontroller/myaction/1/1
.
The docu says:
Reverse routing is a feature in CakePHP that is used to allow you to easily change your URL structure without having to modify all your code. By using routing arrays to define your URLs, you can later configure routes and the generated URLs will automatically update.
Well, the HtmlHelper
gets a routing array as input, that means: I'm using the reverse routing.
Why does it not work? How to make the HtmlHelper
generate the new URLs (without changing the HtmlHelper#link(...)
calls)?
Bit of explanation first
You are technically not using reverse routing. You see, the output link,
/mycontroller/myaction/1/1
definitively doesn't match/iso/name.html
. Like, in no way. So, the routing skips that rule because it doesn't apply.Code
Try this
But for that, you have to change your routing a bit, because you are not passing the parameters (check the docs for examples)
And you have to mind the first string match
/:iso6391/:name.html
. Do you want to match this route to every controller and action in your project, or just the one controller and the one view. If it is for all projects, just for precaution, use thisif is just for, say, Controller1 and action "view", use
The detail you need to consider is the extension you use
.html
, is that really necessary in the url? If it is, add it as a parameter in the Html#linkand also add
parseExtensions
to the routing file. Read this. Would be easier if you don't add the extension, but that's up to you.In the end, you still have to change your calls to
Html->link
...