1
0
mirror of https://github.com/django/django.git synced 2025-07-04 09:49:12 +00:00

i18n: implemented the proposed syntax change to {% trans %} and {% blocktrans %}

git-svn-id: http://code.djangoproject.com/svn/django/branches/i18n@1061 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Georg Bauer 2005-11-03 11:25:18 +00:00
parent df1e0ef61b
commit b60d7ff985
20 changed files with 558 additions and 184 deletions

View File

@ -5,6 +5,8 @@ import os
import sys import sys
import getopt import getopt
from django.utils.translation import templateize
localedir = None localedir = None
if os.path.isdir(os.path.join('conf', 'locale')): if os.path.isdir(os.path.join('conf', 'locale')):
@ -44,29 +46,6 @@ if lang is not None:
elif all: elif all:
languages = [el for el in os.listdir(localedir) if not el.startswith('.')] languages = [el for el in os.listdir(localedir) if not el.startswith('.')]
dot_re = re.compile('\S')
def blank(src):
return dot_re.sub('p', src)
def templateize(src):
o = []
going = 1
while going:
start = src.find('{')
if start >= 0 and src[start+1] in ('{', '%'):
o.append(blank(src[:start]))
end = src.find(src[start+1] == '{' and '}}' or '%}', start)
if end >= 0:
o.append(src[start:end+2])
src = src[end+2:]
else:
o.append(blank(src[start:]))
going = 0
else:
o.append(blank(src))
going = 0
return ''.join(o)
for lang in languages: for lang in languages:
print "processing language", lang print "processing language", lang

View File

@ -7,44 +7,45 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Django 1.0\n" "Project-Id-Version: Django 1.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2005-10-24 00:03+0200\n" "POT-Creation-Date: 2005-11-03 12:21+0100\n"
"PO-Revision-Date: 2005-10-08 00:03+0200\n" "PO-Revision-Date: 2005-10-08 00:03+0200\n"
"Last-Translator: Georg Bauer <gb@bofh.ms>\n" "Last-Translator: Georg Bauer <gb@bofh.ms>\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-1\n" "Content-Type: text/plain; charset=iso-8859-1\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: contrib/admin/templates/admin/object_history.html:4 #: contrib/admin/templates/admin/object_history.html:5
#: contrib/admin/templates/admin/base.html:28 #: contrib/admin/templates/admin/500.html:4
#: contrib/admin/templates/registration/password_change_done.html:3 #: contrib/admin/templates/admin/base.html:29
#: contrib/admin/templates/registration/password_reset_form.html:3 #: contrib/admin/templates/registration/password_change_done.html:4
#: contrib/admin/templates/registration/logged_out.html:3 #: contrib/admin/templates/registration/password_reset_form.html:4
#: contrib/admin/templates/registration/password_reset_done.html:3 #: contrib/admin/templates/registration/logged_out.html:4
#: contrib/admin/templates/registration/password_change_form.html:3 #: contrib/admin/templates/registration/password_reset_done.html:4
#: contrib/admin/templates/registration/password_change_form.html:4
msgid "Home" msgid "Home"
msgstr "Start" msgstr "Start"
#: contrib/admin/templates/admin/object_history.html:4 #: contrib/admin/templates/admin/object_history.html:5
msgid "History" msgid "History"
msgstr "Geschichte" msgstr "Geschichte"
#: contrib/admin/templates/admin/object_history.html:17 #: contrib/admin/templates/admin/object_history.html:18
msgid "Date/time" msgid "Date/time"
msgstr "Datum/Zeit" msgstr "Datum/Zeit"
#: contrib/admin/templates/admin/object_history.html:18 models/auth.py:47 #: contrib/admin/templates/admin/object_history.html:19 models/auth.py:47
msgid "User" msgid "User"
msgstr "Benutzer" msgstr "Benutzer"
#: contrib/admin/templates/admin/object_history.html:19 #: contrib/admin/templates/admin/object_history.html:20
msgid "Action" msgid "Action"
msgstr "Aktion" msgstr "Aktion"
#: contrib/admin/templates/admin/object_history.html:25 #: contrib/admin/templates/admin/object_history.html:26
msgid "DATE_WITH_TIME_FULL" msgid "DATE_WITH_TIME_FULL"
msgstr "j. N Y, H:i" msgstr "j. N Y, H:i"
#: contrib/admin/templates/admin/object_history.html:35 #: contrib/admin/templates/admin/object_history.html:36
msgid "" msgid ""
"This object doesn't have a change history. It probably wasn't added via this " "This object doesn't have a change history. It probably wasn't added via this "
"admin site." "admin site."
@ -52,23 +53,27 @@ msgstr ""
"Dieses Objekt hat keine Änderungsgeschichte. Es wurde möglicherweise nicht " "Dieses Objekt hat keine Änderungsgeschichte. Es wurde möglicherweise nicht "
"über diese Verwaltungsseiten angelegt." "über diese Verwaltungsseiten angelegt."
#: contrib/admin/templates/admin/base_site.html:3 #: contrib/admin/templates/admin/base_site.html:4
msgid "Django site admin" msgid "Django site admin"
msgstr "Django Systemverwaltung" msgstr "Django Systemverwaltung"
#: contrib/admin/templates/admin/base_site.html:6 #: contrib/admin/templates/admin/base_site.html:7
msgid "Django administration" msgid "Django administration"
msgstr "Django Verwaltung" msgstr "Django Verwaltung"
#: contrib/admin/templates/admin/500.html:5 #: contrib/admin/templates/admin/500.html:4
msgid "Server error"
msgstr "Serverfehler"
#: contrib/admin/templates/admin/500.html:6
msgid "Server error (500)" msgid "Server error (500)"
msgstr "Serverfehler (500)" msgstr "Serverfehler (500)"
#: contrib/admin/templates/admin/500.html:8 #: contrib/admin/templates/admin/500.html:9
msgid "Server Error <em>(500)</em>" msgid "Server Error <em>(500)</em>"
msgstr "Serverfehler <em>(500)</em>" msgstr "Serverfehler <em>(500)</em>"
#: contrib/admin/templates/admin/500.html:9 #: contrib/admin/templates/admin/500.html:10
msgid "" msgid ""
"There's been an error. It's been reported to the site administrators via e-" "There's been an error. It's been reported to the site administrators via e-"
"mail and should be fixed shortly. Thanks for your patience." "mail and should be fixed shortly. Thanks for your patience."
@ -77,69 +82,69 @@ msgstr ""
"eMail weitergegeben und sollte bald behoben sein. Vielen Dank für Ihr " "eMail weitergegeben und sollte bald behoben sein. Vielen Dank für Ihr "
"Verständnis." "Verständnis."
#: contrib/admin/templates/admin/404.html:3 #: contrib/admin/templates/admin/404.html:4
#: contrib/admin/templates/admin/404.html:7 #: contrib/admin/templates/admin/404.html:8
msgid "Page not found" msgid "Page not found"
msgstr "Seite nicht gefunden" msgstr "Seite nicht gefunden"
#: contrib/admin/templates/admin/404.html:9 #: contrib/admin/templates/admin/404.html:10
msgid "We're sorry, but the requested page could not be found." msgid "We're sorry, but the requested page could not be found."
msgstr "" msgstr ""
"Es tut uns leid, aber die angeforderte Seite kann nicht gefunden werden." "Es tut uns leid, aber die angeforderte Seite kann nicht gefunden werden."
#: contrib/admin/templates/admin/index.html:26 #: contrib/admin/templates/admin/index.html:27
msgid "Add" msgid "Add"
msgstr "Zufügen" msgstr "Zufügen"
#: contrib/admin/templates/admin/index.html:32 #: contrib/admin/templates/admin/index.html:33
msgid "Change" msgid "Change"
msgstr "Ändern" msgstr "Ändern"
#: contrib/admin/templates/admin/index.html:42 #: contrib/admin/templates/admin/index.html:43
msgid "You don't have permission to edit anything." msgid "You don't have permission to edit anything."
msgstr "Sie haben keine Berechtigung irgendwas zu ändern." msgstr "Sie haben keine Berechtigung irgendwas zu ändern."
#: contrib/admin/templates/admin/index.html:50 #: contrib/admin/templates/admin/index.html:51
msgid "Recent Actions" msgid "Recent Actions"
msgstr "Kürzliche Aktionen" msgstr "Kürzliche Aktionen"
#: contrib/admin/templates/admin/index.html:51 #: contrib/admin/templates/admin/index.html:52
msgid "My Actions" msgid "My Actions"
msgstr "Meine Aktionen" msgstr "Meine Aktionen"
#: contrib/admin/templates/admin/index.html:55 #: contrib/admin/templates/admin/index.html:56
msgid "None available" msgid "None available"
msgstr "Keine vorhanden" msgstr "Keine vorhanden"
#: contrib/admin/templates/admin/login.html:14 #: contrib/admin/templates/admin/login.html:15
msgid "Username:" msgid "Username:"
msgstr "Benutzername:" msgstr "Benutzername:"
#: contrib/admin/templates/admin/login.html:17 #: contrib/admin/templates/admin/login.html:18
msgid "Password:" msgid "Password:"
msgstr "Passwort:" msgstr "Passwort:"
#: contrib/admin/templates/admin/login.html:19 #: contrib/admin/templates/admin/login.html:20
msgid "Have you <a href=\"/password_reset/\">forgotten your password</a>?" msgid "Have you <a href=\"/password_reset/\">forgotten your password</a>?"
msgstr "Haben Sie <a href=\"/password_reset/\">ihr Passwort vergessen</a>?" msgstr "Haben Sie <a href=\"/password_reset/\">ihr Passwort vergessen</a>?"
#: contrib/admin/templates/admin/login.html:23 #: contrib/admin/templates/admin/login.html:24
msgid "Log in" msgid "Log in"
msgstr "Anmelden" msgstr "Anmelden"
#: contrib/admin/templates/admin/base.html:22 #: contrib/admin/templates/admin/base.html:23
msgid "Welcome," msgid "Welcome,"
msgstr "Willkommen," msgstr "Willkommen,"
#: contrib/admin/templates/admin/base.html:22 #: contrib/admin/templates/admin/base.html:23
msgid "Change password" msgid "Change password"
msgstr "Passwort ändern" msgstr "Passwort ändern"
#: contrib/admin/templates/admin/base.html:22 #: contrib/admin/templates/admin/base.html:23
msgid "Log out" msgid "Log out"
msgstr "Abmelden" msgstr "Abmelden"
#: contrib/admin/templates/admin/delete_confirmation.html:6 #: contrib/admin/templates/admin/delete_confirmation.html:7
#, python-format #, python-format
msgid "" msgid ""
"Deleting the %(object_name)s '%(object)s' would result in deleting related " "Deleting the %(object_name)s '%(object)s' would result in deleting related "
@ -150,7 +155,7 @@ msgstr ""
"abhängigen Daten zur Folge, aber Sie haben nicht die nötigen Rechte um die " "abhängigen Daten zur Folge, aber Sie haben nicht die nötigen Rechte um die "
"folgenden abhängigen Daten zu löschen:" "folgenden abhängigen Daten zu löschen:"
#: contrib/admin/templates/admin/delete_confirmation.html:13 #: contrib/admin/templates/admin/delete_confirmation.html:14
#, python-format #, python-format
msgid "" msgid ""
"Are you sure you want to delete the %(object_name)s \"%(object)s\"? All of " "Are you sure you want to delete the %(object_name)s \"%(object)s\"? All of "
@ -159,34 +164,33 @@ msgstr ""
"Sind Sie sicher, das Sie %(object_name)s \"%(object)s\" löschen wollen? Es " "Sind Sie sicher, das Sie %(object_name)s \"%(object)s\" löschen wollen? Es "
"werden zusätzlich die folgenden abhängigen Daten mit gelöscht:" "werden zusätzlich die folgenden abhängigen Daten mit gelöscht:"
#: contrib/admin/templates/admin/delete_confirmation.html:17 #: contrib/admin/templates/admin/delete_confirmation.html:18
msgid "Yes, I'm sure" msgid "Yes, I'm sure"
msgstr "Ja, ich bin sicher" msgstr "Ja, ich bin sicher"
#: contrib/admin/templates/registration/password_change_done.html:3 #: contrib/admin/templates/registration/password_change_done.html:4
#: contrib/admin/templates/registration/password_change_form.html:3 #: contrib/admin/templates/registration/password_change_form.html:4
#: contrib/admin/templates/registration/password_change_form.html:5 #: contrib/admin/templates/registration/password_change_form.html:6
#: contrib/admin/templates/registration/password_change_form.html:9 #: contrib/admin/templates/registration/password_change_form.html:10
msgid "Password change" msgid "Password change"
msgstr "Kennwort ändern" msgstr "Kennwort ändern"
#: contrib/admin/templates/registration/password_change_done.html:5 #: contrib/admin/templates/registration/password_change_done.html:6
#: contrib/admin/templates/registration/password_change_done.html:9 #: contrib/admin/templates/registration/password_change_done.html:10
msgid "Password change successful" msgid "Password change successful"
msgstr "Erfolgreiche Kennwortänderung" msgstr "Erfolgreiche Kennwortänderung"
#: contrib/admin/templates/registration/password_change_done.html:11 #: contrib/admin/templates/registration/password_change_done.html:12
msgid "Your password was changed." msgid "Your password was changed."
msgstr "Ihr Kennwort wurde geändert." msgstr "Ihr Kennwort wurde geändert."
#: contrib/admin/templates/registration/password_reset_form.html:3 #: contrib/admin/templates/registration/password_reset_form.html:4
#: contrib/admin/templates/registration/password_reset_form.html:5 #: contrib/admin/templates/registration/password_reset_form.html:6
#: contrib/admin/templates/registration/password_reset_form.html:9 #: contrib/admin/templates/registration/password_reset_done.html:4
#: contrib/admin/templates/registration/password_reset_done.html:3
msgid "Password reset" msgid "Password reset"
msgstr "Kennwort zurücksetzen" msgstr "Kennwort zurücksetzen"
#: contrib/admin/templates/registration/password_reset_form.html:11 #: contrib/admin/templates/registration/password_reset_form.html:12
msgid "" msgid ""
"Forgotten your password? Enter your e-mail address below, and we'll reset " "Forgotten your password? Enter your e-mail address below, and we'll reset "
"your password and e-mail the new one to you." "your password and e-mail the new one to you."
@ -195,28 +199,28 @@ msgstr ""
"wir setzen das Kennwort auf einen neuen Wert und schicken den per eMail an " "wir setzen das Kennwort auf einen neuen Wert und schicken den per eMail an "
"Sie raus." "Sie raus."
#: contrib/admin/templates/registration/password_reset_form.html:15 #: contrib/admin/templates/registration/password_reset_form.html:16
msgid "E-mail address:" msgid "E-mail address:"
msgstr "eMail-Adresse:" msgstr "eMail-Adresse:"
#: contrib/admin/templates/registration/password_reset_form.html:15 #: contrib/admin/templates/registration/password_reset_form.html:16
msgid "Reset my password" msgid "Reset my password"
msgstr "Mein Kennwort zurücksetzen" msgstr "Mein Kennwort zurücksetzen"
#: contrib/admin/templates/registration/logged_out.html:7 #: contrib/admin/templates/registration/logged_out.html:8
msgid "Thanks for spending some quality time with the Web site today." msgid "Thanks for spending some quality time with the Web site today."
msgstr "Danke, dass Sie eine Weile bei uns waren." msgstr "Danke, dass Sie eine Weile bei uns waren."
#: contrib/admin/templates/registration/logged_out.html:9 #: contrib/admin/templates/registration/logged_out.html:10
msgid "Log in again" msgid "Log in again"
msgstr "Neu anmelden" msgstr "Neu anmelden"
#: contrib/admin/templates/registration/password_reset_done.html:5 #: contrib/admin/templates/registration/password_reset_done.html:6
#: contrib/admin/templates/registration/password_reset_done.html:9 #: contrib/admin/templates/registration/password_reset_done.html:10
msgid "Password reset successful" msgid "Password reset successful"
msgstr "Erfolgreich Kennwort zurückgesetzt" msgstr "Erfolgreich Kennwort zurückgesetzt"
#: contrib/admin/templates/registration/password_reset_done.html:11 #: contrib/admin/templates/registration/password_reset_done.html:12
msgid "" msgid ""
"We've e-mailed a new password to the e-mail address you submitted. You " "We've e-mailed a new password to the e-mail address you submitted. You "
"should be receiving it shortly." "should be receiving it shortly."
@ -224,7 +228,7 @@ msgstr ""
"Wir haben Ihnen ein neues Kennwort per eMail zugeschickt an die Adresse, die " "Wir haben Ihnen ein neues Kennwort per eMail zugeschickt an die Adresse, die "
"Sie uns gegeben haben. Es sollte in Kürze ankommen." "Sie uns gegeben haben. Es sollte in Kürze ankommen."
#: contrib/admin/templates/registration/password_change_form.html:11 #: contrib/admin/templates/registration/password_change_form.html:12
msgid "" msgid ""
"Please enter your old password, for security's sake, and then enter your new " "Please enter your old password, for security's sake, and then enter your new "
"password twice so we can verify you typed it in correctly." "password twice so we can verify you typed it in correctly."
@ -233,49 +237,49 @@ msgstr ""
"dann zweimal (um sicherzustellen, das Sie es korrekt eingegeben haben) das " "dann zweimal (um sicherzustellen, das Sie es korrekt eingegeben haben) das "
"neue Kennwort ein." "neue Kennwort ein."
#: contrib/admin/templates/registration/password_change_form.html:16 #: contrib/admin/templates/registration/password_change_form.html:17
msgid "Old password:" msgid "Old password:"
msgstr "altes Kennwort:" msgstr "altes Kennwort:"
#: contrib/admin/templates/registration/password_change_form.html:18 #: contrib/admin/templates/registration/password_change_form.html:19
msgid "New password:" msgid "New password:"
msgstr "neues Kennwort:" msgstr "neues Kennwort:"
#: contrib/admin/templates/registration/password_change_form.html:20 #: contrib/admin/templates/registration/password_change_form.html:21
msgid "Confirm password:" msgid "Confirm password:"
msgstr "Kennwortwiederholung:" msgstr "Kennwortwiederholung:"
#: contrib/admin/templates/registration/password_change_form.html:22 #: contrib/admin/templates/registration/password_change_form.html:23
msgid "Change my password" msgid "Change my password"
msgstr "Mein Kennwort ändern" msgstr "Mein Kennwort ändern"
#: contrib/admin/templates/registration/password_reset_email.html:1 #: contrib/admin/templates/registration/password_reset_email.html:2
msgid "You're receiving this e-mail because you requested a password reset" msgid "You're receiving this e-mail because you requested a password reset"
msgstr "Sie erhalten diese Mail, weil Sie ein neues Kennwort" msgstr "Sie erhalten diese Mail, weil Sie ein neues Kennwort"
#: contrib/admin/templates/registration/password_reset_email.html:2 #: contrib/admin/templates/registration/password_reset_email.html:3
#, python-format #, python-format
msgid "for your user account at %(site_name)s" msgid "for your user account at %(site_name)s"
msgstr "für ihren Benutzer bei %(site_name)s angefordert haben." msgstr "für ihren Benutzer bei %(site_name)s angefordert haben."
#: contrib/admin/templates/registration/password_reset_email.html:4 #: contrib/admin/templates/registration/password_reset_email.html:5
#, python-format #, python-format
msgid "Your new password is: %(new_password)s" msgid "Your new password is: %(new_password)s"
msgstr "Ihr neues Kennwort ist: %(new_password)s" msgstr "Ihr neues Kennwort ist: %(new_password)s"
#: contrib/admin/templates/registration/password_reset_email.html:6 #: contrib/admin/templates/registration/password_reset_email.html:7
msgid "Feel free to change this password by going to this page:" msgid "Feel free to change this password by going to this page:"
msgstr "Sie können das Kennwort auf folgender Seite ändern:" msgstr "Sie können das Kennwort auf folgender Seite ändern:"
#: contrib/admin/templates/registration/password_reset_email.html:10 #: contrib/admin/templates/registration/password_reset_email.html:11
msgid "Your username, in case you've forgotten:" msgid "Your username, in case you've forgotten:"
msgstr "Ihr Benutzername, falls Sie ihn vergessen haben:" msgstr "Ihr Benutzername, falls Sie ihn vergessen haben:"
#: contrib/admin/templates/registration/password_reset_email.html:12 #: contrib/admin/templates/registration/password_reset_email.html:13
msgid "Thanks for using our site!" msgid "Thanks for using our site!"
msgstr "Vielen Dank, das Sie unsere Seiten benutzen!" msgstr "Vielen Dank, das Sie unsere Seiten benutzen!"
#: contrib/admin/templates/registration/password_reset_email.html:14 #: contrib/admin/templates/registration/password_reset_email.html:15
#, python-format #, python-format
msgid "The %(site_name)s team" msgid "The %(site_name)s team"
msgstr "Das Team von %(site_name)s" msgstr "Das Team von %(site_name)s"
@ -653,44 +657,48 @@ msgid "Message"
msgstr "Mitteilung" msgstr "Mitteilung"
#: conf/global_settings.py:37 #: conf/global_settings.py:37
msgid "Czech"
msgstr "Tschechisch"
#: conf/global_settings.py:38
msgid "German" msgid "German"
msgstr "Deutsch" msgstr "Deutsch"
#: conf/global_settings.py:38 #: conf/global_settings.py:39
msgid "English" msgid "English"
msgstr "Englisch" msgstr "Englisch"
#: conf/global_settings.py:39 #: conf/global_settings.py:40
msgid "Spanish" msgid "Spanish"
msgstr "Spanisch" msgstr "Spanisch"
#: conf/global_settings.py:40 #: conf/global_settings.py:41
msgid "French" msgid "French"
msgstr "Französisch" msgstr "Französisch"
#: conf/global_settings.py:41 #: conf/global_settings.py:42
msgid "Galician" msgid "Galician"
msgstr "Galicisch" msgstr "Galicisch"
#: conf/global_settings.py:42 #: conf/global_settings.py:43
msgid "Italian" msgid "Italian"
msgstr "Italienisch" msgstr "Italienisch"
#: conf/global_settings.py:43 #: conf/global_settings.py:44
msgid "Brazilian" msgid "Brazilian"
msgstr "Brasilianisch" msgstr "Brasilianisch"
#: conf/global_settings.py:44 #: conf/global_settings.py:45
msgid "Russian" msgid "Russian"
msgstr "Russisch" msgstr "Russisch"
#: conf/global_settings.py:45 #: conf/global_settings.py:46
msgid "Serbic" msgid "Serbian"
msgstr "Serbisch" msgstr "Serbisch"
#: conf/global_settings.py:46 #: conf/global_settings.py:47
msgid "Czech" msgid "Traditional Chinese"
msgstr "Tschechisch" msgstr ""
#: core/validators.py:58 #: core/validators.py:58
msgid "This value must contain only letters, numbers and underscores." msgid "This value must contain only letters, numbers and underscores."

View File

@ -1,11 +1,12 @@
{% extends "admin/base_site" %} {% extends "admin/base_site" %}
{% load i18n %}
{% block title %}{{ _('Page not found') }}{% endblock %} {% block title %}{% trans 'Page not found' %}{% endblock %}
{% block content %} {% block content %}
<h2>{{ _('Page not found') }}</h2> <h2>{% trans 'Page not found' %}</h2>
<p>{{ _("We're sorry, but the requested page could not be found.") }}</p> <p>{% trans "We're sorry, but the requested page could not be found." %}</p>
{% endblock %} {% endblock %}

View File

@ -1,11 +1,12 @@
{% extends "admin/base_site" %} {% extends "admin/base_site" %}
{% load i18n %}
{% block breadcrumbs %}<div class="breadcrumbs"><a href="/">Home</a> &rsaquo; Server error</div>{% endblock %} {% block breadcrumbs %}<div class="breadcrumbs"><a href="/">{% trans "Home" %}</a> &rsaquo; {% trans "Server error" %}</div>{% endblock %}
{% block title %}{{ _('Server error (500)') }}{% endblock %} {% block title %}{% trans 'Server error (500)' %}{% endblock %}
{% block content %} {% block content %}
<h1>{{ _('Server Error <em>(500)</em>') }}</h1> <h1>{% trans 'Server Error <em>(500)</em>' %}</h1>
<p>{{ _("There's been an error. It's been reported to the site administrators via e-mail and should be fixed shortly. Thanks for your patience.") }}</p> <p>{% trans "There's been an error. It's been reported to the site administrators via e-mail and should be fixed shortly. Thanks for your patience." %}</p>
{% endblock %} {% endblock %}

View File

@ -6,6 +6,7 @@
{% block extrastyle %}{% endblock %} {% block extrastyle %}{% endblock %}
{% block extrahead %}{% endblock %} {% block extrahead %}{% endblock %}
</head> </head>
{% load i18n %}
<body class="{% if is_popup %}popup {% endif %}{% block bodyclass %}{% endblock %}"> <body class="{% if is_popup %}popup {% endif %}{% block bodyclass %}{% endblock %}">
@ -19,13 +20,13 @@
{% block branding %}{% endblock %} {% block branding %}{% endblock %}
</div> </div>
{% if not user.is_anonymous %} {% if not user.is_anonymous %}
<div id="user-tools">{{ _('Welcome,') }} <strong>{% if user.first_name %}{{ user.first_name }}{% else %}{{ user.username }}{% endif %}</strong>. <br />{% block userlinks %}<a href="/admin/password_change/">{{ _('Change password') }}</a> / <a href="/admin/logout/">{{ _('Log out') }}</a>{% endblock %}</div> <div id="user-tools">{% trans 'Welcome,' %} <strong>{% if user.first_name %}{{ user.first_name }}{% else %}{{ user.username }}{% endif %}</strong>. <br />{% block userlinks %}<a href="/admin/password_change/">{% trans 'Change password' %}</a> / <a href="/admin/logout/">{% trans 'Log out' %}</a>{% endblock %}</div>
{% endif %} {% endif %}
{% block nav-global %}{% endblock %} {% block nav-global %}{% endblock %}
<br class="clear" /> <br class="clear" />
</div> </div>
<!-- END Header --> <!-- END Header -->
{% block breadcrumbs %}<div class="breadcrumbs"><a href="/">{{ _('Home') }}</a>{% if title %} &rsaquo; {{ title }}{% endif %}</div>{% endblock %} {% block breadcrumbs %}<div class="breadcrumbs"><a href="/">{% trans 'Home' %}</a>{% if title %} &rsaquo; {{ title }}{% endif %}</div>{% endblock %}
{% endif %} {% endif %}
{% if messages %} {% if messages %}

View File

@ -1,9 +1,10 @@
{% extends "admin/base" %} {% extends "admin/base" %}
{% load i18n %}
{% block title %}{{ title }} | {{ _('Django site admin') }}{% endblock %} {% block title %}{{ title }} | {% trans 'Django site admin' %}{% endblock %}
{% block branding %} {% block branding %}
<h1 id="site-name">{{ _('Django administration') }}</h1> <h1 id="site-name">{% trans 'Django administration' %}</h1>
<h2 id="site-url"><a href="http://www.example.com/">example.com</a></h2> <h2 id="site-url"><a href="http://www.example.com/">example.com</a></h2>
{% endblock %} {% endblock %}

View File

@ -1,20 +1,21 @@
{% extends "admin/base_site" %} {% extends "admin/base_site" %}
{% load i18n %}
{% block content %} {% block content %}
{% if perms_lacking %} {% if perms_lacking %}
<p>{{ _("Deleting the %(object_name)s '%(object)s' would result in deleting related objects, but your account doesn't have permission to delete the following types of objects:") }}</p> <p>{% blocktrans %}Deleting the {{ object_name }} '{{ object }}' would result in deleting related objects, but your account doesn't have permission to delete the following types of objects:{% endblocktrans %}</p>
<ul> <ul>
{% for obj in perms_lacking %} {% for obj in perms_lacking %}
<li>{{ obj }}</li> <li>{{ obj }}</li>
{% endfor %} {% endfor %}
</ul> </ul>
{% else %} {% else %}
<p>{{ _('Are you sure you want to delete the %(object_name)s "%(object)s"? All of the following related items will be deleted:') }}</p> <p>{% blocktrans %}Are you sure you want to delete the {{ object_name }} "{{ object }}"? All of the following related items will be deleted:{% endblocktrans %}</p>
<ul>{{ deleted_objects|unordered_list }}</ul> <ul>{{ deleted_objects|unordered_list }}</ul>
<form action="" method="post"> <form action="" method="post">
<input type="hidden" name="post" value="yes" /> <input type="hidden" name="post" value="yes" />
<input type="submit" value="{{ _("Yes, I'm sure") }}" /> <input type="submit" value="{% trans "Yes, I'm sure" %}" />
</form> </form>
{% endif %} {% endif %}

View File

@ -1,4 +1,5 @@
{% extends "admin/base_site" %} {% extends "admin/base_site" %}
{% load i18n %}
{% block coltype %}colMS{% endblock %} {% block coltype %}colMS{% endblock %}
{% block bodyclass %}dashboard{% endblock %} {% block bodyclass %}dashboard{% endblock %}
@ -23,13 +24,13 @@
{% endif %} {% endif %}
{% if model.perms.add %} {% if model.perms.add %}
<td class="x50"><a href="{{ model.admin_url }}add/" class="addlink">{{ _('Add') }}</a></td> <td class="x50"><a href="{{ model.admin_url }}add/" class="addlink">{% trans 'Add' %}</a></td>
{% else %} {% else %}
<td class="x50">&nbsp;</td> <td class="x50">&nbsp;</td>
{% endif %} {% endif %}
{% if model.perms.change %} {% if model.perms.change %}
<td class="x75"><a href="{{ model.admin_url }}" class="changelink">{{ _('Change') }}</a></td> <td class="x75"><a href="{{ model.admin_url }}" class="changelink">{% trans 'Change' %}</a></td>
{% else %} {% else %}
<td class="x75">&nbsp;</td> <td class="x75">&nbsp;</td>
{% endif %} {% endif %}
@ -39,7 +40,7 @@
</div> </div>
{% endfor %} {% endfor %}
{% else %} {% else %}
<p>{{ _("You don't have permission to edit anything.") }}</p> <p>{% trans "You don't have permission to edit anything." %}</p>
{% endif %} {% endif %}
</div> </div>
{% endblock %} {% endblock %}
@ -47,12 +48,12 @@
{% block sidebar %} {% block sidebar %}
<div id="content-related"> <div id="content-related">
<div class="module" id="recent-actions-module"> <div class="module" id="recent-actions-module">
<h2>{{ _('Recent Actions') }}</h2> <h2>{% trans 'Recent Actions' %}</h2>
<h3>{{ _('My Actions') }}</h3> <h3>{% trans 'My Actions' %}</h3>
{% load log %} {% load log %}
{% get_admin_log 10 as admin_log for_user user %} {% get_admin_log 10 as admin_log for_user user %}
{% if not admin_log %} {% if not admin_log %}
<p>{{ _('None available') }}</p> <p>{% trans 'None available' %}</p>
{% else %} {% else %}
<ul class="actionlist"> <ul class="actionlist">
{% for entry in admin_log %} {% for entry in admin_log %}

View File

@ -1,4 +1,5 @@
{% extends "admin/base_site" %} {% extends "admin/base_site" %}
{% load i18n %}
{% block breadcrumbs %}{% endblock %} {% block breadcrumbs %}{% endblock %}
@ -11,16 +12,16 @@
<form action="{{ app_path }}" method="post"> <form action="{{ app_path }}" method="post">
<p class="aligned"> <p class="aligned">
<label for="id_username">{{ _('Username:') }}</label> <input type="text" name="username" id="id_username" /> <label for="id_username">{% trans 'Username:' %}</label> <input type="text" name="username" id="id_username" />
</p> </p>
<p class="aligned"> <p class="aligned">
<label for="id_password">{{ _('Password:') }}</label> <input type="password" name="password" id="id_password" /> <label for="id_password">{% trans 'Password:' %}</label> <input type="password" name="password" id="id_password" />
<input type="hidden" name="this_is_the_login_form" value="1" /> <input type="hidden" name="this_is_the_login_form" value="1" />
<input type="hidden" name="post_data" value="{{ post_data }}" />{% comment %} <span class="help">{{ _('Have you <a href="/password_reset/">forgotten your password</a>?') }}</span>{% endcomment %} <input type="hidden" name="post_data" value="{{ post_data }}" />{% comment %} <span class="help">{% trans 'Have you <a href="/password_reset/">forgotten your password</a>?' %}</span>{% endcomment %}
</p> </p>
<div class="aligned "> <div class="aligned ">
<label>&nbsp;</label><input type="submit" value="{{ _('Log in') }}" /> <label>&nbsp;</label><input type="submit" value="{% trans 'Log in' %}" />
</div> </div>
</form> </form>

View File

@ -1,7 +1,8 @@
{% extends "admin/base_site" %} {% extends "admin/base_site" %}
{% load i18n %}
{% block breadcrumbs %} {% block breadcrumbs %}
<div class="breadcrumbs"><a href="../../../../">{{ _('Home') }}</a> &rsaquo; <a href="../../">{{ module_name }}</a> &rsaquo; <a href="../">{{ object|truncatewords:"18" }}</a> &rsaquo; {{ _('History') }}</div> <div class="breadcrumbs"><a href="../../../../">{% trans 'Home' %}</a> &rsaquo; <a href="../../">{{ module_name }}</a> &rsaquo; <a href="../">{{ object|truncatewords:"18" }}</a> &rsaquo; {% trans 'History' %}</div>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
@ -14,9 +15,9 @@
<table id="change-history"> <table id="change-history">
<thead> <thead>
<tr> <tr>
<th>{{ _('Date/time') }}</th> <th>{% trans 'Date/time' %}</th>
<th>{{ _('User') }}</th> <th>{% trans 'User' %}</th>
<th>{{ _('Action') }}</th> <th>{% trans 'Action' %}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -32,7 +33,7 @@
{% else %} {% else %}
<p>{{ _("This object doesn't have a change history. It probably wasn't added via this admin site.") }}</p> <p>{% trans "This object doesn't have a change history. It probably wasn't added via this admin site." %}</p>
{% endif %} {% endif %}

View File

@ -1,11 +1,12 @@
{% extends "admin/base_site" %} {% extends "admin/base_site" %}
{% load i18n %}
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{{ _('Home') }}</a></div>{% endblock %} {% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a></div>{% endblock %}
{% block content %} {% block content %}
<p>{{ _("Thanks for spending some quality time with the Web site today.") }}</p> <p>{% trans "Thanks for spending some quality time with the Web site today." %}</p>
<p><a href="../">{{ _('Log in again') }}</a></p> <p><a href="../">{% trans 'Log in again' %}</a></p>
{% endblock %} {% endblock %}

View File

@ -1,13 +1,14 @@
{% extends "admin/base_site" %} {% extends "admin/base_site" %}
{% load i18n %}
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{{ _('Home') }}</a> &rsaquo; {{ _('Password change') }}</div>{% endblock %} {% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password change' %}</div>{% endblock %}
{% block title %}{{ _('Password change successful') }}{% endblock %} {% block title %}{% trans 'Password change successful' %}{% endblock %}
{% block content %} {% block content %}
<h1>{{ _('Password change successful') }}</h1> <h1>{% trans 'Password change successful' %}</h1>
<p>{{ _('Your password was changed.') }}</p> <p>{% trans 'Your password was changed.' %}</p>
{% endblock %} {% endblock %}

View File

@ -1,25 +1,26 @@
{% extends "admin/base_site" %} {% extends "admin/base_site" %}
{% load i18n %}
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{{ _('Home') }}</a> &rsaquo; {{ _('Password change') }}</div>{% endblock %} {% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password change' %}</div>{% endblock %}
{% block title %}{{ _('Password change') }}{% endblock %} {% block title %}{% trans 'Password change' %}{% endblock %}
{% block content %} {% block content %}
<h1>{{ _('Password change') }}</h1> <h1>{% trans 'Password change' %}</h1>
<p>{{ _("Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly.") }}</p> <p>{% trans "Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly." %}</p>
<form action="" method="post"> <form action="" method="post">
{% if form.old_password.errors %}{{ form.old_password.html_error_list }}{% endif %} {% if form.old_password.errors %}{{ form.old_password.html_error_list }}{% endif %}
<p class="aligned wide"><label for="id_old_password">{{ _('Old password:') }}</label>{{ form.old_password }}</p> <p class="aligned wide"><label for="id_old_password">{% trans 'Old password:' %}</label>{{ form.old_password }}</p>
{% if form.new_password1.errors %}{{ form.new_password1.html_error_list }}{% endif %} {% if form.new_password1.errors %}{{ form.new_password1.html_error_list }}{% endif %}
<p class="aligned wide"><label for="id_new_password1">{{ _('New password:') }}</label>{{ form.new_password1 }}</p> <p class="aligned wide"><label for="id_new_password1">{% trans 'New password:' %}</label>{{ form.new_password1 }}</p>
{% if form.new_password2.errors %}{{ form.new_password2.html_error_list }}{% endif %} {% if form.new_password2.errors %}{{ form.new_password2.html_error_list }}{% endif %}
<p class="aligned wide"><label for="id_new_password2">{{ _('Confirm password:') }}</label>{{ form.new_password2 }}</p> <p class="aligned wide"><label for="id_new_password2">{% trans 'Confirm password:' %}</label>{{ form.new_password2 }}</p>
<p><input type="submit" value="{{ _('Change my password') }}" /></p> <p><input type="submit" value="{% trans 'Change my password' %}" /></p>
</form> </form>
{% endblock %} {% endblock %}

View File

@ -1,13 +1,14 @@
{% extends "admin/base_site" %} {% extends "admin/base_site" %}
{% load i18n %}
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{{ _('Home') }}</a> &rsaquo; {{ _('Password reset') }}</div>{% endblock %} {% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset' %}</div>{% endblock %}
{% block title %}{{ _('Password reset successful') }}{% endblock %} {% block title %}{% trans 'Password reset successful' %}{% endblock %}
{% block content %} {% block content %}
<h1>{{ _('Password reset successful') }}</h1> <h1>{% trans 'Password reset successful' %}</h1>
<p>{{ _("We've e-mailed a new password to the e-mail address you submitted. You should be receiving it shortly.") }}</p> <p>{% trans "We've e-mailed a new password to the e-mail address you submitted. You should be receiving it shortly." %}</p>
{% endblock %} {% endblock %}

View File

@ -1,14 +1,15 @@
{{ _("You're receiving this e-mail because you requested a password reset") }} {% load i18n %}
{{ _("for your user account at %(site_name)s") }}. {% trans "You're receiving this e-mail because you requested a password reset" %}
{% trans "for your user account at %(site_name)s" %}.
{{ _("Your new password is: %(new_password)s") }} {% trans "Your new password is: %(new_password)s" %}
{{ _("Feel free to change this password by going to this page:") }} {% trans "Feel free to change this password by going to this page:" %}
http://{{ domain }}/password_change/ http://{{ domain }}/password_change/
{{ _("Your username, in case you've forgotten:") }} {{ user.username }} {% trans "Your username, in case you've forgotten:" %} {{ user.username }}
{{ _("Thanks for using our site!") }} {% trans "Thanks for using our site!" %}
{{ _("The %(site_name)s team") }} {% trans "The %(site_name)s team" %}

View File

@ -1,18 +1,19 @@
{% extends "admin/base_site" %} {% extends "admin/base_site" %}
{% load i18n %}
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{{ _('Home') }}</a> &rsaquo; {{ _('Password reset') }}</div>{% endblock %} {% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset' %}</div>{% endblock %}
{% block title %}{{ _("Password reset") }}{% endblock %} {% block title %}{% trans "Password reset" %}{% endblock %}
{% block content %} {% block content %}
<h1>{{ _("Password reset") }}</h1> <h1>{% trans "Password reset") }}</h1>
<p>{{ _("Forgotten your password? Enter your e-mail address below, and we'll reset your password and e-mail the new one to you.") }}</p> <p>{% trans "Forgotten your password? Enter your e-mail address below, and we'll reset your password and e-mail the new one to you." %}</p>
<form action="" method="post"> <form action="" method="post">
{% if form.email.errors %}{{ form.email.html_error_list }}{% endif %} {% if form.email.errors %}{{ form.email.html_error_list }}{% endif %}
<p><label for="id_email">{{ _('E-mail address:') }}</label> {{ form.email }} <input type="submit" value="{{ _('Reset my password') }}" /></p> <p><label for="id_email">{% trans 'E-mail address:' %}</label> {{ form.email }} <input type="submit" value="{% trans 'Reset my password' %}" /></p>
</form> </form>
{% endblock %} {% endblock %}

View File

@ -234,6 +234,97 @@ class Parser:
def delete_first_token(self): def delete_first_token(self):
del self.tokens[0] del self.tokens[0]
class TokenParser:
"""
You need to subclass this class and implement the
top method to parse your template line. When instantiating
the parser, you pass in the line from the django template
parser.
If your tag needs to know what tag name it was called with,
you find it in the tagname instance variable of the parser.
"""
def __init__(self, subject):
self.subject = subject
self.pointer = 0
self.backout = []
self.tagname = self.tag()
def top(self):
"""
You need to overload this method to do the actual parsing
and return the result.
"""
raise NotImplemented
def more(self):
"""
This returns True if there is more stuff in the tag.
"""
return self.pointer < len(self.subject)
def back(self):
"""
This method undos the last microparser. This can be
used for lookahead and backtracking.
"""
if not len(self.backout):
raise TemplateSyntaxError, "back called without some previous parsing"
self.pointer = self.backout.pop()
def tag(self):
"""
This microparser just returns the next tag from the line.
"""
subject = self.subject
i = self.pointer
if i >= len(subject):
raise TemplateSyntaxError, "expected another tag, found end of string: %s" % subject
p = i
while i < len(subject) and subject[i] not in (' ', '\t'):
i += 1
s = subject[p:i]
while i < len(subject) and subject[i] in (' ', '\t'):
i += 1
self.backout.append(self.pointer)
self.pointer = i
return s
def value(self):
"""
This microparser parses for a value - some string constant or
variable name.
"""
subject = self.subject
i = self.pointer
if i >= len(subject):
raise TemplateSyntaxError, "searching for value expected another value, found end of string: %s" % subject
if subject[i] in ('"', "'"):
p = i
i += 1
while i < len(subject) and subject[i] != subject[p]:
i += 1
if i >= len(subject):
raise TemplateSyntaxError, "searching for value, unexpected end of string in column %d: %s" % subject
i += 1
res = subject[p:i]
while i < len(subject) and subject[i] in (' ', '\t'):
i += 1
self.backout.append(self.pointer)
self.pointer = i
return res
else:
p = i
while i < len(subject) and subject[i] not in (' ', '\t'):
i += 1
s = subject[p:i]
while i < len(subject) and subject[i] in (' ', '\t'):
i += 1
self.backout.append(self.pointer)
self.pointer = i
return s
class FilterParser: class FilterParser:
"""Parse a variable token and its optional filters (all as a single string), """Parse a variable token and its optional filters (all as a single string),
and return a list of tuples of the filter name and arguments. and return a list of tuples of the filter name and arguments.
@ -257,13 +348,13 @@ class FilterParser:
self.current_filter_arg = None self.current_filter_arg = None
# First read the variable part - decide on wether we need # First read the variable part - decide on wether we need
# to parse a string or a variable by peeking into the stream # to parse a string or a variable by peeking into the stream
if self.peek_char() in ('_', '"', "'"): if self.peek_char() in ('"', "'"):
self.var = self.read_constant_string_token() self.var = self.read_constant_string_token()
else: else:
self.var = self.read_alphanumeric_token() self.var = self.read_alphanumeric_token()
if not self.var: if not self.var:
raise TemplateSyntaxError, "Could not read variable name: '%s'" % self.s raise TemplateSyntaxError, "Could not read variable name: '%s'" % self.s
if self.var.find(VARIABLE_ATTRIBUTE_SEPARATOR + '_') > -1 or (self.var[0] == '_' and not self.var.startswith('_(')): if self.var.find(VARIABLE_ATTRIBUTE_SEPARATOR + '_') > -1 or self.var[0] == '_':
raise TemplateSyntaxError, "Variables and attributes may not begin with underscores: '%s'" % self.var raise TemplateSyntaxError, "Variables and attributes may not begin with underscores: '%s'" % self.var
# Have we reached the end? # Have we reached the end?
if self.current is None: if self.current is None:
@ -288,19 +379,10 @@ class FilterParser:
def read_constant_string_token(self): def read_constant_string_token(self):
"""Read a constant string that must be delimited by either " """Read a constant string that must be delimited by either "
or ' characters. The string is returned with it's delimiters or ' characters. The string is returned with it's delimiters."""
and a possible i18n tag."""
val = '' val = ''
i18n = False
qchar = None qchar = None
self.next_char() self.next_char()
if self.current == '_':
self.next_char()
if self.current != '(':
raise TemplateSyntaxError, "Bad character (expecting '(') '%s'" % self.current
i18n = True
val = '_('
self.next_char()
if not self.current in ('"', "'"): if not self.current in ('"', "'"):
raise TemplateSyntaxError, "Bad character (expecting '\"' or ''') '%s'" % self.current raise TemplateSyntaxError, "Bad character (expecting '\"' or ''') '%s'" % self.current
qchar = self.current qchar = self.current
@ -311,11 +393,6 @@ class FilterParser:
break break
val += self.current val += self.current
val += self.current val += self.current
if i18n:
self.next_char()
if self.current != ')':
raise TemplateSyntaxError, "Bad character (expecting ')') '%s'" % self.current
val += self.current
self.next_char() self.next_char()
return val return val
@ -430,8 +507,6 @@ def resolve_variable(path, context):
""" """
if path[0] in ('"', "'") and path[0] == path[-1]: if path[0] in ('"', "'") and path[0] == path[-1]:
current = path[1:-1] current = path[1:-1]
elif path.startswith('_(') and path.endswith(')') and path[2] in ("'", '"') and path[-2] == path[2]:
current = _(path[3:-2]) % context
else: else:
current = context current = context
bits = path.split(VARIABLE_ATTRIBUTE_SEPARATOR) bits = path.split(VARIABLE_ATTRIBUTE_SEPARATOR)

210
django/templatetags/i18n.py Normal file
View File

@ -0,0 +1,210 @@
"Default tags used by the template system, available to all templates."
from django.core.template import Node, NodeList, Template, Context, resolve_variable, resolve_variable_with_filters, registered_filters
from django.core.template import TemplateSyntaxError, register_tag, TokenParser
from django.core.template import TOKEN_BLOCK, TOKEN_TEXT, TOKEN_VAR
from django.utils import translation
import sys
import re
class GetAvailableLanguagesNode(Node):
def __init__(self, variable):
self.variable = variable
def render(self, context):
from django.conf.settings import LANGUAGES
context[self.variable] = LANGUAGES
return ''
class GetCurrentLanguage(Node):
def __init__(self, variable):
self.variable = variable
def render(self, context):
context[self.variable] = translation.get_language()
return ''
class TranslateNode(Node):
def __init__(self, value, noop):
self.value = value
self.noop = noop
def render(self, context):
value = resolve_variable(self.value, context)
if self.noop:
return value
else:
return translation.gettext(value)
class BlockTranslateNode(Node):
def __init__(self, extra_context, singular, plural=None, countervar=None, counter=None):
self.extra_context = extra_context
self.singular = singular
self.plural = plural
self.countervar = countervar
self.counter = counter
def render_token_list(self, tokens):
result = []
for token in tokens:
if token.token_type == TOKEN_TEXT:
result.append(token.contents)
elif token.token_type == TOKEN_VAR:
result.append('%%(%s)s' % token.contents)
return ''.join(result)
def render(self, context):
context.push()
for var,val in self.extra_context.items():
context[var] = resolve_variable_with_filters(val, context)
singular = self.render_token_list(self.singular) % context
if self.plural and self.countervar and self.counter:
count = resolve_variable_with_filters(self.counter, context)
context[self.countervar] = count
plural = self.render_token_list(self.plural) % context
result = translation.ngettext(singular, plural, count) % context
else:
result = translation.gettext(singular) % context
context.pop()
return result
def do_get_available_languages(parser, token):
"""
This will store a list of available languages
in the context.
Usage is as follows::
{% get_available_languages as languages %}
{% for language in languages %}
...
{% endfor %}
This will just pull the LANGUAGES setting from
your setting file (or the default settings) and
put it into the named variable.
"""
args = token.contents.split()
if len(args) != 3 or args[1] != 'as':
raise TemplateSyntaxError, "'get_available_languages' requires 'as variable' (got %r)" % args
return GetAvailableLanguagesNode(args[2])
def do_get_current_language(parser, token):
"""
This will store the current language in
the context.
Usage is as follows::
{% get_current_language as language %}
This will fetch the currently active language and
put it's value into the ``language`` context
variable.
"""
args = token.contents.split()
if len(args) != 3 or args[1] != 'as':
raise TemplateSyntaxError, "'get_available_languages' requires 'as variable' (got %r)" % args
return GetAvailableLanguagesNode(args[2])
def do_translate(parser, token):
"""
This will mark a string for translation and will
translate the string for the current language.
Usage is like this::
{% trans "this is a test" %}
This will mark the string for translation so it will
be pulled out by mark-messages.py into the .po files
and will run the string through the translation engine.
There is a second form::
{% trans "this is a test" noop %}
This will only mark for translation, but will return
the string unchanged. Use it when you need to store
values into forms that should be translated later on.
You can use variables instead of constant strings
to translate stuff you marked somewhere else::
{% trans variable %}
This will just try to translate the contents of
the variable ``variable``. Make sure that the string
in there is something that is in the .po file.
"""
args = token.contents.split(None, 1)
p = args[1].rfind(' ')
noop = False
value = ''
if p >= 0 and args[1][p:].strip() == 'noop':
value = args[1][:p].strip()
else:
value = args[1]
return TranslateNode(value, noop)
def do_block_translate(parser, token):
"""
"""
class BlockTranslateParser(TokenParser):
def top(self):
countervar = None
counter = None
extra_context = {}
while self.more():
tag = self.tag()
if tag == 'with' or tag == 'and':
value = self.value()
if self.tag() != 'as':
raise TemplateSyntaxError, "variable bindings in 'blocktrans' must be 'with value as variable'"
extra_context[self.tag()] = value
elif tag == 'count':
counter = self.value()
if self.tag() != 'as':
raise TemplateSyntaxError, "counter specification in 'blocktrans' must be 'count value as variable'"
countervar = self.tag()
else:
raise TemplateSyntaxError, "unknown subtag %s for 'blocktrans' found" % tag
return (countervar, counter, extra_context)
(countervar, counter, extra_context) = BlockTranslateParser(token.contents).top()
singular = []
plural = []
while parser.tokens:
token = parser.next_token()
if token.token_type in (TOKEN_VAR, TOKEN_TEXT):
singular.append(token)
else:
break
if countervar and counter:
if token.contents.strip() != 'plural':
raise TemplateSyntaxError, "'blocktrans' doesn't allow other block tags inside it" % tag
while parser.tokens:
token = parser.next_token()
if token.token_type in (TOKEN_VAR, TOKEN_TEXT):
plural.append(token)
else:
break
if token.contents.strip() != 'endblocktrans':
raise TemplateSyntaxError, "'blocktrans' doesn't allow other block tags (seen %r) inside it" % token.contents
return BlockTranslateNode(extra_context, singular, plural, countervar, counter)
register_tag('get_available_languages', do_get_available_languages)
register_tag('get_curent_language', do_get_current_language)
register_tag('trans', do_translate)
register_tag('blocktrans', do_block_translate)

View File

@ -1,8 +1,10 @@
"translation helper functions" "translation helper functions"
import os import os
import re
import sys import sys
import gettext as gettext_module import gettext as gettext_module
from cStringIO import StringIO
from django.utils.functional import lazy from django.utils.functional import lazy
@ -349,3 +351,89 @@ def install():
""" """
__builtins__['_'] = gettext __builtins__['_'] = gettext
dot_re = re.compile(r'\S')
def blankout(src, char):
"""
This is used in the templateize function and changes every
non-whitespace character to the given char.
"""
return dot_re.sub(char, src)
inline_re = re.compile(r"""^\s*trans\s+((?:".*?")|(?:'.*?'))\s*""")
block_re = re.compile(r"""^\s*blocktrans(?:\s+|$)""")
endblock_re = re.compile(r"""^\s*endblocktrans$""")
plural_re = re.compile(r"""^\s*plural$""")
def templateize(src):
from django.core.template import tokenize, TOKEN_TEXT, TOKEN_VAR, TOKEN_BLOCK
"""
This function turns a django template into something that is
understood by xgettext. It does so by translating the django
translation tags into standard gettext function invocations.
"""
out = StringIO()
intrans = False
inplural = False
singular = []
plural = []
for t in tokenize(src):
if intrans:
if t.token_type == TOKEN_BLOCK:
endbmatch = endblock_re.match(t.contents)
pluralmatch = plural_re.match(t.contents)
if endbmatch:
if inplural:
out.write(' ngettext(%r,%r,count) ' % (''.join(singular), ''.join(plural)))
for part in singular:
out.write(blankout(part, 'S'))
for part in plural:
out.write(blankout(part, 'P'))
else:
out.write(' gettext(%r) ' % ''.join(singular))
for part in singular:
out.write(blankout(part, 'S'))
intrans = False
inplural = False
singular = []
plural = []
elif pluralmatch:
inplural = True
else:
raise SyntaxError, "translation blocks must not include other block tags: %s" % t.contents
elif t.token_type == TOKEN_VAR:
if inplural:
plural.append('%%(%s)s' % t.contents)
else:
singular.append('%%(%s)s' % t.contents)
elif t.token_type == TOKEN_TEXT:
if inplural:
plural.append(t.contents)
else:
singular.append(t.contents)
else:
if t.token_type == TOKEN_BLOCK:
imatch = inline_re.match(t.contents)
bmatch = block_re.match(t.contents)
if imatch:
g = imatch.group(1)
if g[0] == '"': g = g.strip('"')
elif g[0] == "'": g = g.strip("'")
out.write(' gettext(%r) ' % g)
elif bmatch:
intrans = True
inplural = False
singular = []
plural = []
else:
out.write(blankout(t.contents, 'B'))
elif t.token_type == TOKEN_VAR:
parts = t.contents.split('|')
for p in parts:
if p.find(':_(') >= 0:
out.write(' %s ' % p.split(':',1)[1])
else:
out.write(blankout(p, 'F'))
else:
out.write(blankout(t.contents, 'X'))
return out.getvalue()