• Subscribe to the RSS feed! RSS icon
  • Subscribe by Email
  • home
  • blog
  • dev
  • Recent Posts

    • Automatically upload screenshots in XFCE4
    • Zend Framework full page cache tips
    • No more Wordpress
    • Xdebug is full of awesome
    • Creating a chat bot with PHP and Dbus
    • A year in review: 2011
    • Notes on shell scripting
    • Listening to Dbus signals with PHP
    • Configuring 2 monitors with xrandr
    • A quick note on Dojo's data grids and dojox.data.HtmlStore
  • Recent Comments

    • Robert on Zend Framework full page cache tips
    • Stephen S. Musoke on Zend Framework full page cache tips
    • David on Zend Framework full page cache tips
    • Anon on A quick note on Dojo's data grids and dojox.data.HtmlStore
    • James on Communicating with Pidgin from PHP via D-Bus
    • Robert on A Zend Framework 2 EventManager use case
    • Jowee on A Zend Framework 2 EventManager use case
    • Jurian Sluiman on A Zend Framework 2 EventManager use case
    • Jurian Sluiman on A Zend Framework 2 EventManager use case
    • djozsef on Webkonf 2011 recap
  • Tags

    php, about, random, framework, zend, example, ubuntu, blog, site, zend framework, book, conference, me, python, wordpress, apache, introduction, lamp, linux, open source, review, script, setup, signals, ape, community, contributing, dbus, dojo, events, hack, mysql, netbeans, pidgin, plugin, pyqt, security, shell, svn, talk
  • Categories

    • Blablabla
    • Development
    • Free time
    • Places on the web
    • Programming
    • Software
    • Uncategorized
  • Archives

    • February, 2012
    • January, 2012
    • December, 2011
    • November, 2011
    • October, 2011
    • September, 2011
    • August, 2011
    • July, 2011
    • May, 2011
    • April, 2011
    • March, 2011
    • January, 2011
    • December, 2010
    • November, 2010
    • October, 2010
    • July, 2010
    • June, 2010
    • April, 2010
    • February, 2010
    • January, 2010
    • December, 2009
    • November, 2009
    • October, 2009
    • August, 2009
    • May, 2009
    • March, 2009
    • February, 2009
    • January, 2009
    • December, 2008
    • November, 2008
    • October, 2008
    • September, 2008

A hack for Zend Framework's translated route segments

by Robert Basic on April 14th, 2011

Today I came across on a little "gotcha" when using the translated route segments in a multilanguage web site and thought about sharing the dirty little hack I used to get around it.

Note: I’ve changed the title on this post. The first one sounded a bit like that ZF code itself contains a hack and not that I wrote a hack to solve a particular problem of mine. Sorry about that.

The set up of the router and translator is done "by the book", err, by the manual.

The problem

The web site's default locale, language, is English. If the user has no locale in the session/cookie, she, or he, will get the English version of the web site. If, for example, the user's first visit is on the http://example.com/news URL, there's no problem, the router will route that URI to the news module, index controller, index action and the user will get the news, in English, because the default locale is English.

But! If the user's first visit is on the http://example.com/vesti URL ("vesti" is "news" in Serbian), the router can't route that because it depends on the locale and the default locale is English and not Serbian, thus directing the user to the 404 page. Of course, that is not good, because the requested URL is perfectly valid, just in a different language and the user should get the news in Serbian and not an error page.

The solution dirty hack

I hacked up a front controller plugin which in the postDispatch hook, if needed, changes the web sites locale to Serbian and dispatches the request all over again. If all goes well, the router will now route correctly the URL and the user will get the content.

<?php

class App_Plugin_TranslatedRoute extends Zend_Controller_Plugin_Abstract
{

    public function postDispatch(Zend_Controller_Request_Abstract $request)
    {
        $request = $this->getRequest();
        $action = $request->getActionName();

        if($action != 'error') {
            return false;
        }

        $translator = Zend_Registry::get('Zend_Translate');
        $locale = $translator->getLocale();

        // English is the default
        // if the current locale is not the default, we might have been here earlier...
        if($locale != 'en') {
            return false;
        }

        $translator->setLocale('sr');
        Zend_Registry::set('Zend_Translate', $translator);

        $front = Zend_Controller_Front::getInstance();
        $front->getResponse()->clearBody();
        try {
            $front->dispatch();
        } catch(Exception $e) {
            // Haven't figured out a nicer way to redirect the user to the error controller
            header("Location: " . $request->getRequestUri());
            exit();
        }
    }
}

The hack for the hack

That terrible, ugly, I-should-have-never-written-it piece of code at the end, the one with the header("Location... code in it is a hack for a hack. If in the second dispatching some error occurs, which at this point is a "valid" error, the user should be directed to the error controller/action. I haven't figured out a nicer way to do this. I tried several different things like doing the dispatch for the 3rd time, setting the request's controller/action to the error controller/action and whatnot but to no avail, every time I just end up a with blank page (yes, with error reporting turned on. Y'know, I'm one of those nuts who develops with E_NOTICEs on).

If anyone has some tips on fixing this problem in a more cleaner way, please do share them.

Happy hackin'!

Tags: locale, route, translate, zend framework.
Categories: Development, Programming.
Comments: 3 comments.

Comments: 3

  • Sylvain Bucher

  • April 15th, 2011
You could also use Zend_Controller_Router_Route_Chain and do something like: domain.com/:lang/:controller/:action
  • Robert

  • April 15th, 2011
I know, (I even wrote about that earlier), but the project's requirement was to *not* have the language identifier in the URL.
  • Krzysztof Kotlarski

  • April 16th, 2011
I'd do it like this: 1. detect locale before dispatching first action (if locale is undefined let it be) 2. search for page in current locale (if locale is undefined search in all locales and set one based on the results) Btw. you dont have to use getRequest() when you get one in function parameter, you could also replace that "ugly" header() with Zend_Controller_Action_Helper_Redirector

Leave a Reply

Robert Basic © 2008 — 2012
Design & graphics by: Livia Radvanski
Coded by: Robert Basic
Home page last updated on November 30th, 2009.
Frameworks used: Zend Framework, Dojo, 960 Grid System