How to add language code to URL in Pyramid?
<p>I've just created the basic Pyramid "hello world" template project and added i18n support. I'm using Python 3.5 and Chameleon templates (<code>.pt</code>) with gettext.</p>

<p>I can currently change the language through the <code>.ini</code> file. </p>

<p>Now I would like to make it dynamic and read the language code from the URL. So URLs are changed to <code>/&lt;language code&gt;/page/{possible params}</code> so for example <code>/fi/home</code>. I don't want to add <code>{language}</code> to existing routes/views so that the language code parameter is hidden and views don't know anything about it except when creating links to other pages in templates/views.</p>

<p>EDIT: Here's my attempt using <a href="http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/hooks.html#registering-tweens" rel="nofollow noreferrer">tweens</a> mentioned by Mikko Ohtamaa:</p>

<p>Added to <code>__init__.py</code>:</p>

<pre><code>config.add_tween('myapp.tweens.LocalizerTween')
</code></pre>

<p><code>tweens.py</code>:</p>

<pre><code>import logging

from pyramid.registry import Registry
from pyramid.request import Request

log = logging.getLogger(__name__)


class LocalizerTween(object):
  """
  Set translator based on URL
  """
  def __init__(self, handler, registry: Registry):
    self.handler = handler
    self.registry = registry

  def __call__(self, request: Request):
    if request.path.count("/") &gt; 1 and len(request.path) &gt; 3:
      request.locale_name = request.path[1:].split("/", 1)[0]
    else:
      # Redirect to default language
      from pyramid.settings import aslist
      import pyramid.httpexceptions as exc
      raise exc.HTTPFound("/" + aslist(request.registry.settings['pyramid.default_locale_name'])[0] + "/")

    newpath = request.path[1:]
    newpath = newpath[newpath.find("/"):]
    log.debug("new path: %s", newpath)

    request.path = newpath

    response = self.handler(request)
    return response
</code></pre>

<p>Redirect to default language gives exception:</p>

<pre><code>pyramid.httpexceptions.HTTPFound: The resource was found at
</code></pre>

<p>Trying to set new path gives:</p>

<pre><code>AttributeError: can't set attribute
</code></pre>

<p>If I comment out <code>request.path = newpath</code> and go to <code>/fi/</code> and <code>/en/</code> I get 404 page in correct language.</p>