Django1.4: Generische Möglichkeit, Sprachlinks in der Vorlage so einzustellen, dass sie mit i18n_patterns funktionieren?

8

Ich fing an, mit neuen i18n_patterns in Django 1.4 zu spielen. Grundsätzlich möchte ich Sprachlinks für jede meiner unterstützten Sprachen in allen Vorlagenheadern haben. Ich habe meinen Header als separate Vorlage implementiert, die in anderen Vorlagen enthalten ist.

Gibt es eine Möglichkeit, meinen Header generisch zu halten und dies zu lösen, ohne den aktuellen View-Namen oder die aktuelle URL im Template-Kontext zu übergeben? Ich denke, es kommt zu einer Frage, wie ich die aktuelle Ansicht oder URL aus der Vorlage in generischer Weise abrufen kann.

Übrigens habe ich festgestellt, dass mein früherer Ansatz mit der set_lang-Ansicht zum Ändern der aktiven Sprache mithilfe des Referrers mit url_patterns unterbrochen wird, da er nach dem Ändern der Sprache zurückkehrt, wenn er auf die referierte Ansicht umgeleitet wird.

Jede Hilfe, die den allgemeinen Ansatz zum Setzen von Sprachlinks in Templates, die mit url_patterns generisch verwendet werden sollen, findet, wäre willkommen!

    
user1039384 19.04.2012, 08:31
quelle

4 Antworten

1

Ich entschuldige mich für die lange Verzögerung. Vielen Dank für Ihre Antworten.

Zunächst zu den beiden Lösungsoptionen von Chris kommentieren: Weder benutzerdefinierte set_language noch Javascript sind gut für den Zweck, da die ganze Schönheit der URL-Muster SEO freundlich ist.

Darüber hinaus kann das einfache Ersetzen der Präfixsprache in der URL nicht als vollständige Lösung für URL-basierte URLs behandelt werden, da auch die gesamte URL übersetzbar ist. Bsp .: /en/profile/ für Englisch und /fr/profil/ für Französisch. Um ein solches Problem zu lösen, müssen die Viewfunc und die Argumente erfasst werden, um sie für verschiedene Sprachen umzukehren.

Zum Glück verwendet mein Projekt keine übersetzbaren URLs für jetzt und ich nahm den folgenden Ansatz.

  1. Fügen Sie django.core.context_processors.request zu TEMPLATE_CONTEXT_PROCESSORS hinzu, damit die Anfrage im Template-Rendering-Kontext verfügbar ist.

  2. Verwenden Sie RequestContext in Ansichten beim Rendern Ihrer Ansichten. Das ist für mich unabhängig vom Thema immer der Fall.

  3. Schreiben Sie eine ziemlich einfache templatetag , die den Kontext benötigt und ein Argument einen Sprachcode verwendet, um die aktuelle URL in der angegebenen Sprache zurückzugeben. Es stellt im Grunde sicher, dass die aktuelle URL ein gültiges Sprachcode-Präfix hat und gibt einfach eine andere Zeichenfolge zurück, die dieselbe aktuelle URL mit ersetztem Sprachcode ist.

ex:

%Vor%

Außerdem, wenn man nicht die gesamte Anfrage in den Kontext injizieren möchte, ist es ziemlich einfach, einen eigenen context_processor zu schreiben, der einfach den request.path als current_url_path zum Beispiel drückt und diesen stattdessen in deinem templatetag / p>

Ihre Kommentare sind wie immer willkommen!

    
user1039384 23.08.2012, 21:15
quelle
5

Grundsätzlich gibt es zwei verschiedene Ansätze zum Einstellen der Sprache. Sie können i18n_patterns verwenden, um Ihre URLs automatisch mit einem Sprachcode zu versehen, oder Sie können die django.views.i18n.set_language -Ansicht verwenden, um den Wert des Sprachcodes in der Benutzersitzung zu ändern (oder ein Cookie, wenn Ihr Projekt dies nicht tut) haben Sitzungsunterstützung).

Es ist erwähnenswert, dass der Algorithmus LocaleMiddleware verwendet, um die Sprache zu bestimmen:

  • Zuerst wird nach dem Sprachenpräfix in der angeforderten URL gesucht. Dies wird nur durchgeführt, wenn Sie die i18n_patterns-Funktion in Ihrer root URLconf verwenden. Weitere Informationen zum Sprachenpräfix und zur Internationalisierung von URL-Mustern finden Sie unter Internationalisierung: in URL-Mustern.

  • Wenn dies nicht der Fall ist, sucht es in der Sitzung des aktuellen Benutzers nach einem django_language-Schlüssel.

  • Wenn dies nicht der Fall ist, wird nach einem Cookie gesucht. Der Name des verwendeten Cookies wird in der Einstellung LANGUAGE_COOKIE_NAME festgelegt. (Der Standardname ist django_language.)

  • Wenn das nicht klappt, wird der Accept-Language-HTTP-Header betrachtet. Dieser Header wird von Ihrem Browser gesendet und teilt dem Server die von Ihnen bevorzugten Sprachen in der Reihenfolge ihrer Priorität mit. Django probiert jede Sprache in der Kopfzeile aus, bis sie eine mit verfügbaren Übersetzungen findet.

  • Wenn dies fehlschlägt, verwendet es die globale Einstellung LANGUAGE_CODE.

Das Problem, auf das Sie wahrscheinlich stoßen, ist, dass Sie set_language nicht zum Umleiten von einer URL verwenden können, die bereits mit einem Sprachenpräfix ausgeliefert wird, es sei denn, Sie übergeben einen Parameter next in den POST-Daten. Dies liegt daran, dass set_language standardmäßig auf den Referrer umleitet, der das vorherige Sprachenpräfix enthält, wobei LocaleMiddleware dann den Inhalt in der alten Sprache sieht und bereitstellt (weil er vor der Überprüfung nach einem Sprachenpräfix in der URL sucht) die Sitzungsvariable django_language ).

Ein Beispiel zur Verdeutlichung:

  1. Ihr Benutzer ist auf / de / news / article / 1000 und klickt auf den Link, der 'language = es' an set_language .

  2. posten wird
  3. set_language sieht 'language = es', überprüft, ob 'es' verfügbar ist und setzt dann die 'django_language' Sitzungsvariable (oder Cookie) auf 'es'

  4. Da Sie 'next' nicht gesetzt haben, wird es auf den Wert von request.META ['HTTP_REFERRER'] umgeleitet, was / de / news / article / 1000

  5. ist
  6. LocaleMiddleware ( Quelle ) sieht die 'en' Präfix in der URL, und aktiviert die 'en' Sprache und setzt request.LANGUAGE_CODE auf 'en'

Ich sehe zwei mögliche Lösungen:

  1. Schreiben Sie Ihre eigene set_language -Ansicht (siehe die Originalquelle hier ), die im Referrer nach einem Sprachpräfix suchen ( django.utils.translation.get_language_from_path verwenden) und dieses vor dem Weiterleiten an das Präfix der neu ausgewählten Sprache ändern.

  2. Verwenden Sie Javascript, um die gleiche Operation clientseitig auszuführen, und legen Sie den Parameter next POST fest. Wirklich, das ist irgendwie dumm; Es wäre wahrscheinlich einfacher, einfach JavaScript zu verwenden, um alle URLs dynamisch mit dem bevorzugten Sprachcode des Benutzers zu versehen, und vergiss set_language insgesamt.

Es scheint, dass diese neue set_language -Ansicht wahrscheinlich Djangos Standardverhalten sein sollte. Es wurde ein Ticket ausgelöst , das eine vorgeschlagene Implementierung enthielt, das Problem aber nicht wirklich beschrieben hat und anschließend geschlossen wurde. Ich schlage vor, ein neues Ticket mit einer besseren Beschreibung Ihres Anwendungsfalls, dem Problem, das durch die vorhandene set_language -Implementierung verursacht wird, und Ihrer vorgeschlagenen Lösung zu öffnen.

    
Chris Lawlor 17.05.2012 16:29
quelle
2

Nachdem ich heute das gleiche Problem mit Django 1.7 hatte, habe ich diese Lösung entwickelt - nicht sehr DRY, aber es scheint OK zu funktionieren (und alle meine Tests sind vorüber, also ...). Anstatt die eingebaute set_language-Ansicht zu verwenden, habe ich sie kopiert und eine kleine Anpassung vorgenommen - hier ist das Ergebnis:

%Vor%

Um es zusammenzufassen: Ich löse () die Ansichtsparameter für next auf und übergebe dann die Daten nach Aktivierung der neuen Sprache an reverse (). Hoffe, das hilft.

    
pgcd 08.04.2015 14:02
quelle
2

Eigentlich ist es nicht nötig, mit Ihrer Sichtweise herumzuspielen. Django hat ein praktisches Slice-Tag, also kannst du einfach {{ request.path|slice:'3:' }} als Link-URL verwenden. Dadurch wird das Sprachencode-Präfix deaktiviert, sodass die Sprache von der Funktion set_lang festgelegt wird.

    
Keith 12.08.2015 01:51
quelle