/ / richtiger Gebrauch von Sprachen im Zend Framework - zend-framework, uri, routes

richtiger Gebrauch von Sprachen im Zend Framework - zend-framework, uri, routes

Ich habe eine Zend-Anwendung mit zwei Modulen (admin und public) und für die Öffentlichkeit habe ich das folgende Plugin, um meine Friendly-URL zu parsen:

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();
}}

Es ist sehr nützlich, wenn ich Struktur wie verwenden möchte domain.com/en/about-us/mision/ weil ich die URL parsen kann und den ersten Parameter "en" bekomme und danach die mit "about-us / mission" verknüpfte Seite finde, aber was ist, wenn ich sie benutzen will? domain.com/en/user/profile/id/1/, Zend stellen "de"als Controller und"Benutzer"Als Aktion. Wie kann ich die Sprache in der URL richtig einstellen?

Antworten:

9 für die Antwort № 1

Dies ist ein häufiges Problem, also lassen Sie mich ein wenig verallgemeinern und formalisieren.

Nehmen wir an, Sie möchten, dass Ihre Web-App mehrere Sprachen unterstützt und Sie folgende Routing-Anforderungen haben:

http://domain.com/language-code/controller-name/action-name

Mit anderen Worten, Sie möchten "Sprachcode" als Gebietsschema verwenden und das vorherige mit dem Standard-Zend-Modul-Routing kombinieren.

Angenommen, Sie möchten Zend_Translate auch verwenden, um übersetzte Inhalte entsprechend dem Gebietsschema bereitzustellen.

Hier ist ein Code, den ich verwende und oft in Projekte mit ähnlichen Anforderungen "exportiere". Ich bin offen für weitere Diskussionen.

Relevante Konfigurationselemente:

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"

Hier die registrierte Plugin Sprache:

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")
);


}

}

Der Aktionshelfer:

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");

}

}

Der View-URL-Helper (überschreibt den Standard-URL). Sie müssen Ihre URLs entsprechend mit dem neuen Routing schreiben, den Sie verwenden:

    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);

}

}

Ich hoffe das hilft.


0 für die Antwort № 2

Ich würde sagen, dass Sie benutzerdefinierte Router verwenden sollten. Dies ist der Router für - Parameter aus URI bestimmen. Jetzt lassen Sie den Router einfach grundlos funktionieren. Weil du dann das Ergebnis der Arbeit änderst.

Schreiben von benutzerdefinierten Router ist nicht so schwierig und ich würde vorschlagen, dass Sie dies tun sollten. Du kannst dort etwas schreiben wie:

  1. explodieren durch /
  2. ist der erste Teil "en", "de" oder "es", wenn ja, lang = $ arr [0]
  3. arbeite als Standardroute für Zend_Router

Und Sie können viele weitere Optionen hinzufügen. Auch die Übereinstimmung kann viel schneller sein, da Sie die URI-Dekomposition logisch strukturieren können. Der normale Router ist dumm - er stimmt nur mit URI überein, um Regex zu routen, und stoppt, wenn eine Übereinstimmung gefunden wird.