Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Hello,
J'ai la tête dans la guidon et ne comprend pas ma connerie
J'essaie tout bêtement (la honte) de foutre la langue dans un cookie.
En gros, si le param n'existe pas, je vérifie le cookie, s'il n'existe pas, je prend la langue du navigateur.
A la fin je fou la langue dans un cookie.
Tout ça dans un plugin tout ce qu'il y a de plus basique :
public function routeShutdown(Zend_Controller_Request_Abstract $request) { $lang = $request->getParam('lang', ''); if ($lang == '') { if (isset($_COOKIE['lang'])) { $lang = $_COOKIE['lang']; } else { $lang = new Zend_Locale(Zend_Locale::BROWSER); $lang = $lang->getLanguage(); } } $lang = mb_strtolower($lang); $locale = 'en_US'; switch ($lang) { case 'en': $locale = 'en_US'; break; case 'fr': $locale = 'fr_FR'; break; } $request->setParam('lang', $lang); setcookie('lang', $lang, time()-60*60*24*30, '/'); setcookie('lang', $lang, time()+60*60*24*30, '/'); // etc.... instance de Zend_Translate tout ça }
Sauf que si j'ai une erreur JS (oui vous avez bien lu), la valeur du cookie c'est du grand n'importe quoi....
J'ai du mal à y croire et je commence à devenir parano et à remettre tout l'internet en doute, WHAT THE FUCK ?
Voilà le déroulement de l'opération :
- J'avais l'erreur js suivante :
$this->headScript()->prependFile('js/_langs/'.$this->currentLocale().'/global.js');
Sachant que le dossier "en_US" n'existe pas et donc "en_US/global.js" non plus.
Le cookie n'existe pas encore, je charge la page, il me met bien "fr" dans mon cookie. Je clique sur la langue "us" dans le site, la page se recharge donc, je regarde mon cookie et dedans j'ai....attention.... "js" et non pas "en" !
Si je corrige l'erreur js d'inclusion de fichier, j'ai plus de problème.
Ca me semble incroyable, qui peut confirmer ?
Merci,
A+ benjamin.
Hors ligne
je pense que comme ton fichier n'existe pas, son appel ne passe pas par les rewrite du htaccess et arrive sur ton index.php
du coup ton routeur pense que le premier param de ton url est la langue, et comme tu appelle surement monsite.com/js/_langs/... et ben ton plugin pense qu'il y a un param lang qui vaut js
Hors ligne
Bien vu
J'aurais du m'aérer le cerveau et sortir la tête de ma soupe, parce que ça semble évident :p
Merci,
A+ benjamin.
Hors ligne
Je remonte le sujet pour pousser un coup de gueule
Existe-t-il une solution universelle avec Zend pour ajouter le paramètre langue en début d'url ?
J'ai l'impression que personne n'arrive vraiment à faire ce qu'il veut.
De mon côté j'étais tout content de mon plugin (qui n'a plus rien à voir avec celui ci-dessus), mais je me rend compte qu'il y a toujours un cas de figure où ça ne fonctionne pas.
Voilà ma méthode :
Dans la config je rédéfinis les routes :
; language routes resources.router.routes.default.route = "/:locale/:module/:controller/:action/*" resources.router.routes.default.defaults.module = front resources.router.routes.default.defaults.controller = index resources.router.routes.default.defaults.action = index ;resources.router.routes.default.reqs.locale = "^(en-us|fr-fr)$" resources.router.routes.default.defaults.locale = resources.router.routes.m.route = "/:locale/:module" resources.router.routes.m.defaults.module = front resources.router.routes.m.defaults.controller = index resources.router.routes.m.defaults.action = index ;resources.router.routes.m.reqs.locale = "^(en-us|fr-fr)$" resources.router.routes.m.defaults.locale = resources.router.routes.c.route = "/:locale/:controller" resources.router.routes.c.defaults.module = front resources.router.routes.c.defaults.controller = index resources.router.routes.c.defaults.action = index ;resources.router.routes.c.reqs.locale = "^(en-us|fr-fr)$" resources.router.routes.c.defaults.locale = resources.router.routes.ca.route = "/:locale/:controller/:action" resources.router.routes.ca.defaults.module = front resources.router.routes.ca.defaults.controller = index resources.router.routes.ca.defaults.action = index ;resources.router.routes.ca.reqs.locale = "^(en-us|fr-fr)$" resources.router.routes.ca.defaults.locale =
Et dans mon plugin :
class Tight_Controller_Plugin_Language extends Zend_Controller_Plugin_Abstract { // A RECUPERER DEPUIS UN FICHIER DE CONFIG private $_locales = array('en_US', 'fr_FR'); private $_defaultLocale = 'en_US'; public function routeShutdown(Zend_Controller_Request_Abstract $request) { // determines LOCALE $redirect = false; $throw404 = false; $locale = $this->_request->getParam('locale', ''); if ('' === $locale) { $redirect = true; if (isset($_COOKIE['localeId'])) { $locale = $_COOKIE['localeId']; } else { $locale = new Zend_Locale(Zend_Locale::BROWSER); $locale = $locale->toString(); } } else { $locale = str_replace(chr(45), chr(95), $locale); $throw404 = true; } $locale = mb_strtolower($locale); $inArray = false; foreach($this->_locales as $tLocale) { if ($locale == mb_strtolower($tLocale)) { $inArray = true; break; } } if (!$inArray && $throw404) { //throw new Zend_Controller_Action_Exception('Pages not found', 404); //ERREUR NON PRISE EN CHARGE PAR LE PLUGIN ErrorHandler !! } $parts = explode('_', $locale); $locale = mb_strtolower($parts[0]) . '_' . mb_strtoupper($parts[1]); $locale = new Zend_Locale($locale); $localeParam = mb_strtolower(str_replace(chr(95), chr(45), $locale->toString())); // Init Zend_Locale en Zend_Translate // Bootstrap object stored in front controller $bootstrap = Zend_Controller_Front::getInstance()->getParam('bootstrap'); $bootstrap->bootstrap('Locale'); $localeResource = $bootstrap->getResource('Locale'); $localeResource->setLocale($locale); $bootstrap->bootstrap('Translate'); $translate = $bootstrap->getResource('Translate'); $filePath = str_replace(chr(92), chr(47), APPLICATION_PATH . '/../etc/langs/' . $locale->toString() . '/home.csv'); $translate->getAdapter()->setLocale($locale); $translate->getAdapter()->addTranslation($filePath, $locale); Zend_Registry::set('Zend_Translate', $translate); $view = $bootstrap->getResource('view'); $view->setTranslator($translate); $mailer = $bootstrap->getResource('mailer'); $mailer->setTranslator($translate); $router = Zend_Controller_Front::getInstance()->getRouter(); $router->setGlobalParam('locale', $localeParam); setcookie('localeId', $locale->toString(), null, '/'); if ($redirect) { $url = $view->url(array( 'module' => $request->getModuleName(), 'controller' => $request->getControllerName(), 'action' => $request->getActionName(), 'locale' => $localeParam )); $this->_response->setRedirect($url, 301); } } }
Sauf qu'il y a deux problèmes majeurs :
1/ si je saisis http://www.monsite.com/fr-fr/ avec le slash de fin d'url, ça me redirige vers /index.php/fr-fr
2/ si l'utilisateur saisi dans l'url à la place de la langue un paramètre impossible (ex. "sqdqsd") il est impossible "d'handle" l'erreur et de la traiter comme les autres à l'aide du ErrorHandler.
Ces histoires de langues deviennent vraiment trop compliquées dès lors qu'on veut ajouter le paramètre dans l'URL, et c'est très problématique et fait perdre un temps de dév. très précieux ...
Aucune des solutions glanée sur la toile ne convient. Existe-t-il seulement un moyen efficace avec Zend, parce que ça me semble trop compliqué pour si peu ? J'imagine que c'est une config pointu des routes et une meilleure connaissance du framework qui permettent un bon résultat...
Je vois que ces questions sont très récurrentes.
Peut-on se mettre d'accord et proposer une solution efficace sur le forum ?
Je met tout de suite de côté les solutions à l'aide de sessions et/ou paramètres quelque conque dans l'url (c'est à dire pas en début d'url), qui certent fonctionnent, mais ne répondent pas bien au SEO. Ajouter un paramètre en début d'url pour "simuler" un dossier par langue n'est pas un caprice :p
Merci,
A+ Benjamin.
Dernière modification par Delprog (26-04-2010 20:47:17)
Hors ligne