I have an Zend application with two modules (admin and public) and for public I have the following plugin to parse my friendly-url:
class Custom_Controller_Plugin_Initializer extends Zend_Controller_Plugin_Abstract {
protected $_front;
protected $_request;
public function __construct() {
$this->_front = Zend_Controller_Front::getInstance();
$this->_request = $this->_front->getRequest();
}
public function preDispatch(Zend_Controller_Request_Abstract $request) {
//checking if the url ends with "/"
$requestUri = $this->_request->getRequestUri();
$path = parse_url($requestUri, PHP_URL_PATH);
$query = parse_url($requestUri, PHP_URL_QUERY);
if (substr($path, -1) != '/') {
header('location: ' . $path . (isset($query) ? '/?' . $query : '/'));
die();
}
// exploding the uri to get the parts.
$uri = explode('/', substr($path, strlen(Zend_Controller_Front::getInstance()->getBaseUrl()) + 1));
$modelLanguage = new Model_Db_Language();
//checking if the first part is of 2 characters and if it's a registered language
if ($modelLanguage->checkLanguage($uri[0])) {
$language = $uri[0];
unset($uri[0]); //deleting the language from the uri.
$uri = array_values($uri);
} else {
$language = $modelLanguage->autoLanguage();
if (!$uri[0] == '' && (strlen($uri[0]) == 2)) {
$uri[0] = $language;
header('location: ' . Zend_Controller_Front::getInstance()->getBaseUrl() . '/' . implode($uri) . (isset($query) ? '/?' . $query : '/'));
die();
}
}
//remember that the language was deleted from the uri
$this->_request->setParam('requestUri', implode('/', $uri));
switch ($uri[0]) {
case 'search':
unset($uri[0]);
$this->_request->setParam('s', urldecode($uri[2]));
$this->_request->setModuleName('public');
$this->_request->setControllerName('content');
$this->_request->setActionName('search');
$this->_request->setParam('template', 'search');
break;
}
$this->_initTranslation($language);
$this->_initInterface();
}}
It is very usefull if I wanna use structure like domain.com/en/about-us/mision/
because I can parse the url and get the first param "en" and after that find the page associated to "about-us/mission" but what about if I wanna use domain.com/en/user/profile/id/1/
, Zend set "en" as controller and "user" as action. How can I set the language in the url and properly?
I'd say that you should use custom router. This is what router is for - determining parameters from URI. Now you just let the router do work for no reason. Because you then change the result of it's work.
Writing custom router is not that difficult and I would suggest you should do so. You can write there something like:
And you can add many more options. Also matching may be much faster because you can logically strucutre the URI decomposition. Normal router is dumb - it just matches URI to route regex and stops when match is found.
This is a common problem so let me generalize and formalize a little bit.
Let's say you want your web app to support multiple languages and you have the following routing requirements:
http://domain.com/language-code/controller-name/action-name
In other words you want to use "language-code" as locale and combine the previous with the default Zend module routing.
Let's assume you also want to use Zend_Translate to provide translated content according to the locale.
Here is some code I use and often "export" into project with similar requirements, I'm open to discuss further.
Relevant config items:
Here the registered Plugin language:
The action helper:
The view url helper (overriding default one). You have to write your urls accordingly with the new routing you are using:
Hope this help.