title: Zend Framework URL based translation routes
body: <p>I am trying to implement URL based translation in Zend Framework so that my site is SEO friendly. This means that I want URLs like the below in addition to the default routes.</p>
  
  <pre><code>zend.local/en/module
  zend.local/en/controller
  zend.local/en/module/controller
  zend.local/en/controller/action
  </code></pre>
  
  <p>The above are the ones I have problems with right now; the rest <em>should</em> be OK. I have added a controller plugin that fetches a <code>lang</code> parameter so that I can set the locale and translation object in the <code>preDispatch</code> method. Here are some of my routes (stored in a .ini file):</p>
  
  <pre><code>; Language + module
  ; Language + controller
  resources.router.routes.lang1.type = "Zend_Controller_Router_Route_Regex"
  resources.router.routes.lang1.route = "(^[a-zA-Z]{2})/(\w+$)"
  resources.router.routes.lang1.defaults.controller = index
  resources.router.routes.lang1.defaults.action = index
  resources.router.routes.lang1.map.1 = "lang"
  resources.router.routes.lang1.map.2 = "module"
  
  
  ; Language + module + controller
  ; Language + controller + action
  resources.router.routes.lang2.type = "Zend_Controller_Router_Route_Regex"
  resources.router.routes.lang2.route = "(^[a-zA-Z]{2})/(\w+)/(\w+$)"
  resources.router.routes.lang2.defaults.module = default
  resources.router.routes.lang2.defaults.action = index
  resources.router.routes.lang2.map.1 = "lang"
  resources.router.routes.lang2.map.2 = "controller"
  resources.router.routes.lang2.map.3 = "action"
  </code></pre>
  
  <p>As the comments indicate, several URL structures will match the same route, which makes my application interpret the format incorrectly. For instance, the following two URLs will be matched by the <code>lang1</code> route:</p>
  
  <pre><code>zend.local/en/mymodule
  zend.local/en/mycontroller
  </code></pre>
  
  <p>In the first URL, "mymodule" is used as module name, which is correct. However, in the second URL, "mycontroller" is used as module name, which is not what I want. Here I want it to use the "default" module and "mycontroller" as controller. The same applies for the previous <code>lang2</code> route. So I don't know how to distinguish between if the URL is of the structure <code>/en/module</code> or <code>/en/controller</code>.</p>
  
  <p>To fix this, I experimented with the code below in my controller plugin.</p>
  
  <pre><code>// Get module names as array
  $dirs = Zend_Controller_Front::getInstance()-&gt;getControllerDirectory();
  $modules = array_keys($dirs);
  
  // Module variable contains a module that does not exist
  if (!in_array($request-&gt;getModuleName(), $modules)) {
     // Try to use it as controller name instead
     $request-&gt;setControllerName($request-&gt;getModuleName());
     $request-&gt;setModuleName('default');
  }
  </code></pre>
  
  <p>This works fine in the scenarios I tested, but then I would have to do something similar to make the <code>lang2</code> route work (which possibly involves scanning directories to get the list of controllers). This just seems like a poor solution, so if it is possible, I would love to accomplish all of this with routes only (or simple code that is not so "hacky"). I <em>could</em> also make routes for every time I want <code>/en/controller</code>, for instance, but that is a compromise that I would rather not go with. So, if anyone knows how to solve this, or know of another approach to accomplish the same thing, I am all ears!</p>