2016-11-05 4 views
1

Ich habe gerade das grundlegende Pyramid "Hallo Welt" Vorlage Projekt erstellt und i18n Unterstützung hinzugefügt. Ich benutze Python 3.5 und Chameleon Vorlagen (.pt) mit gettext.Wie fügt man der URL in Pyramid Sprachencode hinzu?

Ich kann derzeit die Sprache über die Datei .ini ändern.

Jetzt möchte ich es dynamisch machen und den Sprachcode von der URL lesen. Daher werden URLs in /<language code>/page/{possible params} geändert, also zum Beispiel /fi/home. Ich möchte {language} nicht zu vorhandenen Routen/Sichten hinzufügen, so dass der Sprachencode-Parameter ausgeblendet wird und Sichten nichts davon wissen, außer wenn Links zu anderen Seiten in Vorlagen/Ansichten erstellt werden.

EDIT: Hier ist mein Versuch tweens von Mikko Ohtamaa erwähnt werden:

hinzugefügt __init__.py:

config.add_tween('myapp.tweens.LocalizerTween') 

tweens.py:

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("/") > 1 and len(request.path) > 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 

Redirect Sprache auf die Standard gibt Ausnahme:

Der Versuch, neue Wege zu setzen gibt:

AttributeError: can't set attribute 

Wenn ich request.path = newpath Kommentar aus und gehen Sie zu /fi/ und /en/ ich in der richtigen Sprache 404-Seite. Hier

Antwort

0

Lösung ist ein Beispiel, streng begrenzt auf den Umfang der Sprache bewusst Pfade (keine Lokalisierung Bindungen, usw.):

"""Self-contained language aware path routing example for Pyramid.""" 

from urllib.parse import urlunparse 
from urllib.parse import urlparse 
from wsgiref.simple_server import make_server 

from pyramid.config import Configurator 
from pyramid.httpexceptions import HTTPFound 
from pyramid.request import Request 
from pyramid.response import Response 


def redirect_to_default_language(request: Request): 
    """A view that redirects path language-free URLs to the default language URLs. 

    E.g. /greeter/foobar -> /en/greeter/foobar 
    """ 

    default_language = request.registry.settings["default_language"] 

    parts = urlparse(request.url) 
    new_path = "/{}{}".format(default_language, parts.path) 
    new_parts = [parts[0], parts[1], new_path, parts[3], parts[4], parts[5]] 
    language_redirected_url = urlunparse(new_parts) 
    return HTTPFound(language_redirected_url) 


def add_localized_route(config, name, pattern, factory=None, pregenerator=None, **kw): 
    """Create path language aware routing paths. 

    Each route will have /{lang}/ prefix added to them. 

    Optionally, if default language is set, we'll create redirect from an URL without language path component to the URL with the language path component. 
    """ 
    orig_factory = factory 

    def wrapper_factory(request): 
     lang = request.matchdict['lang'] 
     # determine if this is a supported lang and convert it to a locale, 
     # likely defaulting to your default language if the requested one is 
     # not supported by your app 
     request.path_lang = lang 

     if orig_factory: 
      return orig_factory(request) 

    orig_pregenerator = pregenerator 

    def wrapper_pregenerator(request, elements, kw): 
     if 'lang' not in kw: 
      # not quite right but figure out how to convert request._LOCALE_ back into a language url 
      kw['lang'] = request.path_lang 
     if orig_pregenerator: 
      return orig_pregenerator(elements, kw) 
     return elements, kw 

    if pattern.startswith('/'): 
     new_pattern = pattern[1:] 
    else: 
     new_pattern = pattern 

    new_pattern = '/{lang}/' + new_pattern 

    # Language-aware URL routed 
    config.add_route(name, new_pattern, factory=wrapper_factory, pregenerator=wrapper_pregenerator, **kw) 

    # Add redirect to the default language routes 
    if config.registry.settings.get("default_language"): 
     # TODO: This works only for the most simplest routes 
     fallback_route_name = name + "_language_redirect_fallback" 
     config.add_route(fallback_route_name, pattern) 
     config.add_view(redirect_to_default_language, route_name=fallback_route_name) 


def home(request): 
    """Example of language aware parameterless routing.""" 

    if request.path_lang == "fi": 
     msg = 'Hyvää päivää!' 
    else: 
     msg = 'Hello sir' 

    # This will use current language 
    # and automatically populate /{lang}/ matchdict 
    # as in wrapper_pregenerator() 
    another_url = request.route_url("greeter", name="mikko") 

    text = """{} 

    Also see {} 
    """.format(msg, another_url) 

    return Response(text) 


def greeter(request): 
    """Example of language aware matchdict routing.""" 
    name = request.matchdict["name"] 
    if request.path_lang == "fi": 
     return Response('Mitä kuuluu {}?'.format(name)) 
    else: 
     return Response('How are you {}?'.format(name)) 


if __name__ == '__main__': 
    config = Configurator() 

    # Map all /lang/ free URLs to this language 
    config.registry.settings["default_language"] = "en" 

    # Set up config.add_localized_route 
    config.add_directive('add_localized_route', add_localized_route) 

    # Parameterless routing 
    # This will create 
    # -/
    # - /fi/ 
    # - /en/ 
    # patterns 
    config.add_localized_route('home', '/') 
    config.add_view(home, route_name='home') 

    # Match dict routing 
    # This will create 
    # - /greet/mikko 
    # - /en/greet/mikko 
    # - /fi/greet/mikko 
    # patterns 
    config.add_localized_route('greeter', '/greet/{name}') 
    config.add_view(greeter, route_name='greeter') 

    # Run the web server 
    app = config.make_wsgi_app() 
    server = make_server('0.0.0.0', 8080, app) 
    server.serve_forever() 
Verwandte Themen