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_Plugi
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:
resources.frontController.plugins.Language = Plugin_Language
resources.frontController.actionHelperPaths.Controller_Helper = APPLICATION_PATH "/controllers/helpers"
; Locale
resources.locale.default = "en_US"
resources.locale.force = false
; Translate
resources.translate.adapter = "Csv"
resources.translate.data = APPLICATION_PATH "/languages"
resources.translate.locale = "auto"
resources.translate.disableNotices = true
resources.translate.scan = directory
; Routes
resources.router.routes.module.type = Zend_Controller_Router_Route_Module
resources.router.routes.module.abstract = On
resources.router.routes.language.type = Zend_Controller_Router_Route
resources.router.routes.language.route = ":language"
resources.router.routes.language.reqs.language = "^[a-z]{2}$"
resources.router.routes.language.defaults.language = "en"
resources.router.routes.default.type = Zend_Controller_Router_Route_Chain
resources.router.routes.default.chain = "language,module"
; View
resources.view.helperPath.View_Helper = APPLICATION_PATH "/views/helpers"
Here the registered Plugin language:
class Plugin_Language extends Zend_Controller_Plugin_Abstract {
public function routeStartup(Zend_Controller_Request_Abstract $request){
if (substr($request->getRequestUri(), 0, -1) == $request->getBaseUrl()){
/* Access to the Base Url (no language information) */
/* Get current locale language (autodetected) */
$language = Zend_Registry::get("Zend_Locale")->getLanguage();
/* If requested language isn't available set to the default one */
if (!Zend_Registry::get('Zend_Translate')->isAvailable($language)){
Zend_Registry::set(
"Zend_Locale",
new Zend_Locale("default")
);
$language = Zend_Registry::get("Zend_Locale")->getLanguage();
Zend_Registry::get("Zend_Translate")->setLocale(
Zend_Registry::get('Zend_Locale')
);
}
/* Modifiy Request Uri with Language info from current Locale */
$request->setRequestUri($request->getRequestUri().$language."/");
$request->setParam("language", $language);
}
}
public function routeShutdown(Zend_Controller_Request_Abstract $request){
/* Get language from request param */
$language = $request->getParam("language");
/* If requested language isn't available set to the default one */
if (!Zend_Registry::get('Zend_Translate')->isAvailable($language))
throw new Zend_Controller_Router_Exception('Translation language is not available', 404);
/* Set the locale */
Zend_Registry::set(
"Zend_Locale",
new Zend_Locale($language)
);
/* Set the traslator */
Zend_Registry::get("Zend_Translate")->setLocale(
Zend_Registry::get("Zend_Locale")
);
}
}
The action helper:
class Controller_Helper_Language extends Zend_Controller_Action_Helper_Abstract {
/**
*
* Get Current language
*
* @return mixed string|null
*/
public function getCurrent(){
if (!Zend_Registry::isRegistered("Zend_Locale"))
return null;
return Zend_Registry::get("Zend_Locale")->getLanguage();
}
/**
*
* Get translator
*
* @return mixed Zend_Translate|null
*
*/
public function getTranslator(){
if (!Zend_Registry::isRegistered("Zend_Translate"))
return null;
return Zend_Registry::get("Zend_Translate");
}
}
The view url helper (overriding default one). You have to write your urls accordingly with the new routing you are using:
class View_Helper_Url extends Zend_View_Helper_Url {
protected function _getCurrentLanguage(){
return Zend_Controller_Action_HelperBroker::getStaticHelper('Language')
->getCurrent();
}
public function Url($urlOptions = array(), $name = null, $reset = true, $encode = true){
$urlOptions = array_merge(
array(
"language" => $this->_getCurrentLanguage()
),
$urlOptions
);
return parent::url($urlOptions,$name,$reset,$encode);
}
}
Hope this help.
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.