Reputation: 2618
The title might be misleading but I'm trying to do something very simple but cant figure it out.
Lets say I have a Question controller and show action and question id is the primary key with which I look up question details - so the URL looks like this
http://www.example.com/question/show/question_id/101
This works fine - So when the view is generated - the URL appears as shown above.
Now in the show action, what I want to do is, append the question title (which i get from database) to the URL - so when the view is generated - the URL shows up as
http://www.example.com/question/show/question_id/101/how-to-make-muffins
Its like on Stack overflow - if you take any question page - say
http://stackoverflow.com/questions/5451200/
and hit enter The question title gets appended to the url as
http://stackoverflow.com/questions/5451200/make-seo-sensitive-url-avoid-id-zend-framework
Thanks a lot
Upvotes: 0
Views: 1575
Reputation: 45721
You will have to add a custom route to your router, unless you can live with an url like:
www.example.com/question/show/question_id/101/{paramName}/how-to-make-muffins
You also, if you want to ensure that this parameter is always showing up, need to check if the parameter is set in the controller and issue a redirect if it is missing.
So, in your bootstrap file:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
public function _initRoutes ()
{
// Ensure that the FrontController has been bootstrapped:
$this->bootstrap('FrontController');
$fc = $this->getResource('FrontController');
/* @var $router Zend_Controller_Router_Rewrite */
$router = $fc->getRouter();
$router->addRoutes( array (
'question' => new Zend_Controller_Router_Route (
/* :controller and :action are special parameters, and corresponds to
* the controller and action that will be executed.
* We also say that we should have two additional parameters:
* :question_id and :title. Finally, we say that anything else in
* the url should be mapped by the standard {name}/{value}
*/
':controller/:action/:question_id/:title/*',
// This argument provides the default values for the route. We want
// to allow empty titles, so we set the default value to an empty
// string
array (
'controller' => 'question',
'action' => 'show',
'title' => ''
),
// This arguments contains the contraints for the route parameters.
// In this case, we say that question_id must consist of 1 or more
// digits and nothing else.
array (
'question_id' => '\d+'
)
)
));
}
}
Now that you have this route, you can use it in your views like so:
<?php echo $this->url(
array(
'question_id' => $this->question['id'],
'title' => $this->question['title']
),
'question'
);
// Will output something like: /question/show/123/my-question-title
?>
In your controller, you need to ensure that the title-parameter is set, or redirect to itself with the title set if not:
public function showAction ()
{
$question = $this->getQuestion($this->_getParam('question_id'));
if(!$this->_getParam('title', false)) {
$this->_helper->Redirector
->setCode(301) // Tell the client that this resource is permanently
// residing under the full URL
->gotoRouteAndExit(
array(
'question_id' => $question['id'],
'title' => $question['title']
)
);
}
[... Rest of your code ...]
}
Upvotes: 2
Reputation: 2870
This is done using a 301 redirect.
Fetch the question, filter out and/or replace URL-illegal characters, then construct the new URL. Pass it to the Redirector
helper (in your controller: $this->_redirect($newURL);
)
Upvotes: 0