diff options
| author | Georg Bauer <gb@hugo.westfalen.de> | 2005-11-03 11:25:18 +0000 |
|---|---|---|
| committer | Georg Bauer <gb@hugo.westfalen.de> | 2005-11-03 11:25:18 +0000 |
| commit | b60d7ff98582798723fe64da12089d93e92bab85 (patch) | |
| tree | 1ca1cb2a5b7fd7ac51d6199543b1e41ab06f8e16 | |
| parent | df1e0ef61bbf95a86ea1a1dfedccd7b5517cf6f7 (diff) | |
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
20 files changed, 558 insertions, 184 deletions
diff --git a/django/bin/make-messages.py b/django/bin/make-messages.py index d8c5299e62..c78faac694 100755 --- a/django/bin/make-messages.py +++ b/django/bin/make-messages.py @@ -5,6 +5,8 @@ import os import sys import getopt +from django.utils.translation import templateize + localedir = None if os.path.isdir(os.path.join('conf', 'locale')): @@ -44,29 +46,6 @@ if lang is not None: elif all: 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: print "processing language", lang diff --git a/django/conf/locale/de/LC_MESSAGES/django.mo b/django/conf/locale/de/LC_MESSAGES/django.mo Binary files differindex d9f0aea348..c8b9157d0c 100644 --- a/django/conf/locale/de/LC_MESSAGES/django.mo +++ b/django/conf/locale/de/LC_MESSAGES/django.mo diff --git a/django/conf/locale/de/LC_MESSAGES/django.po b/django/conf/locale/de/LC_MESSAGES/django.po index 19b8b726fb..e2481e89ce 100644 --- a/django/conf/locale/de/LC_MESSAGES/django.po +++ b/django/conf/locale/de/LC_MESSAGES/django.po @@ -7,44 +7,45 @@ msgid "" msgstr "" "Project-Id-Version: Django 1.0\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" "Last-Translator: Georg Bauer <gb@bofh.ms>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-1\n" "Content-Transfer-Encoding: 8bit\n" -#: contrib/admin/templates/admin/object_history.html:4 -#: contrib/admin/templates/admin/base.html:28 -#: contrib/admin/templates/registration/password_change_done.html:3 -#: contrib/admin/templates/registration/password_reset_form.html:3 -#: contrib/admin/templates/registration/logged_out.html:3 -#: contrib/admin/templates/registration/password_reset_done.html:3 -#: contrib/admin/templates/registration/password_change_form.html:3 +#: contrib/admin/templates/admin/object_history.html:5 +#: contrib/admin/templates/admin/500.html:4 +#: contrib/admin/templates/admin/base.html:29 +#: contrib/admin/templates/registration/password_change_done.html:4 +#: contrib/admin/templates/registration/password_reset_form.html:4 +#: contrib/admin/templates/registration/logged_out.html:4 +#: contrib/admin/templates/registration/password_reset_done.html:4 +#: contrib/admin/templates/registration/password_change_form.html:4 msgid "Home" msgstr "Start" -#: contrib/admin/templates/admin/object_history.html:4 +#: contrib/admin/templates/admin/object_history.html:5 msgid "History" msgstr "Geschichte" -#: contrib/admin/templates/admin/object_history.html:17 +#: contrib/admin/templates/admin/object_history.html:18 msgid "Date/time" 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" msgstr "Benutzer" -#: contrib/admin/templates/admin/object_history.html:19 +#: contrib/admin/templates/admin/object_history.html:20 msgid "Action" msgstr "Aktion" -#: contrib/admin/templates/admin/object_history.html:25 +#: contrib/admin/templates/admin/object_history.html:26 msgid "DATE_WITH_TIME_FULL" msgstr "j. N Y, H:i" -#: contrib/admin/templates/admin/object_history.html:35 +#: contrib/admin/templates/admin/object_history.html:36 msgid "" "This object doesn't have a change history. It probably wasn't added via this " "admin site." @@ -52,23 +53,27 @@ msgstr "" "Dieses Objekt hat keine Änderungsgeschichte. Es wurde möglicherweise nicht " "über diese Verwaltungsseiten angelegt." -#: contrib/admin/templates/admin/base_site.html:3 +#: contrib/admin/templates/admin/base_site.html:4 msgid "Django site admin" msgstr "Django Systemverwaltung" -#: contrib/admin/templates/admin/base_site.html:6 +#: contrib/admin/templates/admin/base_site.html:7 msgid "Django administration" 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)" msgstr "Serverfehler (500)" -#: contrib/admin/templates/admin/500.html:8 +#: contrib/admin/templates/admin/500.html:9 msgid "Server Error <em>(500)</em>" msgstr "Serverfehler <em>(500)</em>" -#: contrib/admin/templates/admin/500.html:9 +#: contrib/admin/templates/admin/500.html:10 msgid "" "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." @@ -77,72 +82,72 @@ msgstr "" "eMail weitergegeben und sollte bald behoben sein. Vielen Dank für Ihr " "Verständnis." -#: contrib/admin/templates/admin/404.html:3 -#: contrib/admin/templates/admin/404.html:7 +#: contrib/admin/templates/admin/404.html:4 +#: contrib/admin/templates/admin/404.html:8 msgid "Page not found" 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." msgstr "" "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" msgstr "Zufügen" -#: contrib/admin/templates/admin/index.html:32 +#: contrib/admin/templates/admin/index.html:33 msgid "Change" 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." 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" msgstr "Kürzliche Aktionen" -#: contrib/admin/templates/admin/index.html:51 +#: contrib/admin/templates/admin/index.html:52 msgid "My Actions" msgstr "Meine Aktionen" -#: contrib/admin/templates/admin/index.html:55 +#: contrib/admin/templates/admin/index.html:56 msgid "None available" msgstr "Keine vorhanden" -#: contrib/admin/templates/admin/login.html:14 +#: contrib/admin/templates/admin/login.html:15 msgid "Username:" msgstr "Benutzername:" -#: contrib/admin/templates/admin/login.html:17 +#: contrib/admin/templates/admin/login.html:18 msgid "Password:" 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>?" 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" msgstr "Anmelden" -#: contrib/admin/templates/admin/base.html:22 +#: contrib/admin/templates/admin/base.html:23 msgid "Welcome," msgstr "Willkommen," -#: contrib/admin/templates/admin/base.html:22 +#: contrib/admin/templates/admin/base.html:23 msgid "Change password" msgstr "Passwort ändern" -#: contrib/admin/templates/admin/base.html:22 +#: contrib/admin/templates/admin/base.html:23 msgid "Log out" msgstr "Abmelden" -#: contrib/admin/templates/admin/delete_confirmation.html:6 +#: contrib/admin/templates/admin/delete_confirmation.html:7 #, python-format 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 " "objects, but your account doesn't have permission to delete the following " "types of objects:" msgstr "" @@ -150,7 +155,7 @@ msgstr "" "abhängigen Daten zur Folge, aber Sie haben nicht die nötigen Rechte um die " "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 msgid "" "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 " "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" msgstr "Ja, ich bin sicher" -#: contrib/admin/templates/registration/password_change_done.html:3 -#: contrib/admin/templates/registration/password_change_form.html:3 -#: contrib/admin/templates/registration/password_change_form.html:5 -#: contrib/admin/templates/registration/password_change_form.html:9 +#: contrib/admin/templates/registration/password_change_done.html:4 +#: contrib/admin/templates/registration/password_change_form.html:4 +#: contrib/admin/templates/registration/password_change_form.html:6 +#: contrib/admin/templates/registration/password_change_form.html:10 msgid "Password change" msgstr "Kennwort ändern" -#: contrib/admin/templates/registration/password_change_done.html:5 -#: contrib/admin/templates/registration/password_change_done.html:9 +#: contrib/admin/templates/registration/password_change_done.html:6 +#: contrib/admin/templates/registration/password_change_done.html:10 msgid "Password change successful" 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." msgstr "Ihr Kennwort wurde geändert." -#: contrib/admin/templates/registration/password_reset_form.html:3 -#: contrib/admin/templates/registration/password_reset_form.html:5 -#: contrib/admin/templates/registration/password_reset_form.html:9 -#: contrib/admin/templates/registration/password_reset_done.html:3 +#: contrib/admin/templates/registration/password_reset_form.html:4 +#: contrib/admin/templates/registration/password_reset_form.html:6 +#: contrib/admin/templates/registration/password_reset_done.html:4 msgid "Password reset" msgstr "Kennwort zurücksetzen" -#: contrib/admin/templates/registration/password_reset_form.html:11 +#: contrib/admin/templates/registration/password_reset_form.html:12 msgid "" "Forgotten your password? Enter your e-mail address below, and we'll reset " "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 " "Sie raus." -#: contrib/admin/templates/registration/password_reset_form.html:15 +#: contrib/admin/templates/registration/password_reset_form.html:16 msgid "E-mail address:" 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" 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." 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" msgstr "Neu anmelden" -#: contrib/admin/templates/registration/password_reset_done.html:5 -#: contrib/admin/templates/registration/password_reset_done.html:9 +#: contrib/admin/templates/registration/password_reset_done.html:6 +#: contrib/admin/templates/registration/password_reset_done.html:10 msgid "Password reset successful" msgstr "Erfolgreich Kennwort zurückgesetzt" -#: contrib/admin/templates/registration/password_reset_done.html:11 +#: contrib/admin/templates/registration/password_reset_done.html:12 msgid "" "We've e-mailed a new password to the e-mail address you submitted. You " "should be receiving it shortly." @@ -224,7 +228,7 @@ msgstr "" "Wir haben Ihnen ein neues Kennwort per eMail zugeschickt an die Adresse, die " "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 "" "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." @@ -233,49 +237,49 @@ msgstr "" "dann zweimal (um sicherzustellen, das Sie es korrekt eingegeben haben) das " "neue Kennwort ein." -#: contrib/admin/templates/registration/password_change_form.html:16 +#: contrib/admin/templates/registration/password_change_form.html:17 msgid "Old password:" msgstr "altes Kennwort:" -#: contrib/admin/templates/registration/password_change_form.html:18 +#: contrib/admin/templates/registration/password_change_form.html:19 msgid "New password:" msgstr "neues Kennwort:" -#: contrib/admin/templates/registration/password_change_form.html:20 +#: contrib/admin/templates/registration/password_change_form.html:21 msgid "Confirm password:" msgstr "Kennwortwiederholung:" -#: contrib/admin/templates/registration/password_change_form.html:22 +#: contrib/admin/templates/registration/password_change_form.html:23 msgid "Change my password" 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" 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 msgid "for your user account at %(site_name)s" 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 msgid "Your new password is: %(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:" 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:" 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!" 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 msgid "The %(site_name)s team" msgstr "Das Team von %(site_name)s" @@ -653,44 +657,48 @@ msgid "Message" msgstr "Mitteilung" #: conf/global_settings.py:37 +msgid "Czech" +msgstr "Tschechisch" + +#: conf/global_settings.py:38 msgid "German" msgstr "Deutsch" -#: conf/global_settings.py:38 +#: conf/global_settings.py:39 msgid "English" msgstr "Englisch" -#: conf/global_settings.py:39 +#: conf/global_settings.py:40 msgid "Spanish" msgstr "Spanisch" -#: conf/global_settings.py:40 +#: conf/global_settings.py:41 msgid "French" msgstr "Französisch" -#: conf/global_settings.py:41 +#: conf/global_settings.py:42 msgid "Galician" msgstr "Galicisch" -#: conf/global_settings.py:42 +#: conf/global_settings.py:43 msgid "Italian" msgstr "Italienisch" -#: conf/global_settings.py:43 +#: conf/global_settings.py:44 msgid "Brazilian" msgstr "Brasilianisch" -#: conf/global_settings.py:44 +#: conf/global_settings.py:45 msgid "Russian" msgstr "Russisch" -#: conf/global_settings.py:45 -msgid "Serbic" +#: conf/global_settings.py:46 +msgid "Serbian" msgstr "Serbisch" -#: conf/global_settings.py:46 -msgid "Czech" -msgstr "Tschechisch" +#: conf/global_settings.py:47 +msgid "Traditional Chinese" +msgstr "" #: core/validators.py:58 msgid "This value must contain only letters, numbers and underscores." diff --git a/django/contrib/admin/templates/admin/404.html b/django/contrib/admin/templates/admin/404.html index 031d9d9877..d791f565ba 100644 --- a/django/contrib/admin/templates/admin/404.html +++ b/django/contrib/admin/templates/admin/404.html @@ -1,11 +1,12 @@ {% extends "admin/base_site" %} +{% load i18n %} -{% block title %}{{ _('Page not found') }}{% endblock %} +{% block title %}{% trans 'Page not found' %}{% endblock %} {% 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 %} diff --git a/django/contrib/admin/templates/admin/500.html b/django/contrib/admin/templates/admin/500.html index 75856d407e..9d3e3de32c 100644 --- a/django/contrib/admin/templates/admin/500.html +++ b/django/contrib/admin/templates/admin/500.html @@ -1,11 +1,12 @@ {% extends "admin/base_site" %} +{% load i18n %} -{% block breadcrumbs %}<div class="breadcrumbs"><a href="/">Home</a> › Server error</div>{% endblock %} +{% block breadcrumbs %}<div class="breadcrumbs"><a href="/">{% trans "Home" %}</a> › {% trans "Server error" %}</div>{% endblock %} -{% block title %}{{ _('Server error (500)') }}{% endblock %} +{% block title %}{% trans 'Server error (500)' %}{% endblock %} {% block content %} -<h1>{{ _('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> +<h1>{% trans 'Server Error <em>(500)</em>' %}</h1> +<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 %} diff --git a/django/contrib/admin/templates/admin/base.html b/django/contrib/admin/templates/admin/base.html index a007a9c788..0c0ae4aabd 100644 --- a/django/contrib/admin/templates/admin/base.html +++ b/django/contrib/admin/templates/admin/base.html @@ -6,6 +6,7 @@ {% block extrastyle %}{% endblock %} {% block extrahead %}{% endblock %} </head> +{% load i18n %} <body class="{% if is_popup %}popup {% endif %}{% block bodyclass %}{% endblock %}"> @@ -19,13 +20,13 @@ {% block branding %}{% endblock %} </div> {% 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 %} {% block nav-global %}{% endblock %} <br class="clear" /> </div> <!-- END Header --> - {% block breadcrumbs %}<div class="breadcrumbs"><a href="/">{{ _('Home') }}</a>{% if title %} › {{ title }}{% endif %}</div>{% endblock %} + {% block breadcrumbs %}<div class="breadcrumbs"><a href="/">{% trans 'Home' %}</a>{% if title %} › {{ title }}{% endif %}</div>{% endblock %} {% endif %} {% if messages %} diff --git a/django/contrib/admin/templates/admin/base_site.html b/django/contrib/admin/templates/admin/base_site.html index 6494951be3..cb2ea43254 100644 --- a/django/contrib/admin/templates/admin/base_site.html +++ b/django/contrib/admin/templates/admin/base_site.html @@ -1,9 +1,10 @@ {% extends "admin/base" %} +{% load i18n %} -{% block title %}{{ title }} | {{ _('Django site admin') }}{% endblock %} +{% block title %}{{ title }} | {% trans 'Django site admin' %}{% endblock %} {% 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> {% endblock %} diff --git a/django/contrib/admin/templates/admin/delete_confirmation.html b/django/contrib/admin/templates/admin/delete_confirmation.html index 4881e0825e..0bff003980 100644 --- a/django/contrib/admin/templates/admin/delete_confirmation.html +++ b/django/contrib/admin/templates/admin/delete_confirmation.html @@ -1,20 +1,21 @@ {% extends "admin/base_site" %} +{% load i18n %} {% block content %} {% 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> {% for obj in perms_lacking %} <li>{{ obj }}</li> {% endfor %} </ul> {% 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> <form action="" method="post"> <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> {% endif %} diff --git a/django/contrib/admin/templates/admin/index.html b/django/contrib/admin/templates/admin/index.html index 0620caa7bc..9822ed92c2 100644 --- a/django/contrib/admin/templates/admin/index.html +++ b/django/contrib/admin/templates/admin/index.html @@ -1,4 +1,5 @@ {% extends "admin/base_site" %} +{% load i18n %} {% block coltype %}colMS{% endblock %} {% block bodyclass %}dashboard{% endblock %} @@ -23,13 +24,13 @@ {% endif %} {% 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 %} <td class="x50"> </td> {% endif %} {% 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 %} <td class="x75"> </td> {% endif %} @@ -39,7 +40,7 @@ </div> {% endfor %} {% else %} - <p>{{ _("You don't have permission to edit anything.") }}</p> + <p>{% trans "You don't have permission to edit anything." %}</p> {% endif %} </div> {% endblock %} @@ -47,12 +48,12 @@ {% block sidebar %} <div id="content-related"> <div class="module" id="recent-actions-module"> - <h2>{{ _('Recent Actions') }}</h2> - <h3>{{ _('My Actions') }}</h3> + <h2>{% trans 'Recent Actions' %}</h2> + <h3>{% trans 'My Actions' %}</h3> {% load log %} {% get_admin_log 10 as admin_log for_user user %} {% if not admin_log %} - <p>{{ _('None available') }}</p> + <p>{% trans 'None available' %}</p> {% else %} <ul class="actionlist"> {% for entry in admin_log %} diff --git a/django/contrib/admin/templates/admin/login.html b/django/contrib/admin/templates/admin/login.html index 72891e797d..ea823e1020 100644 --- a/django/contrib/admin/templates/admin/login.html +++ b/django/contrib/admin/templates/admin/login.html @@ -1,4 +1,5 @@ {% extends "admin/base_site" %} +{% load i18n %} {% block breadcrumbs %}{% endblock %} @@ -11,16 +12,16 @@ <form action="{{ app_path }}" method="post"> <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 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="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> <div class="aligned "> -<label> </label><input type="submit" value="{{ _('Log in') }}" /> +<label> </label><input type="submit" value="{% trans 'Log in' %}" /> </div> </form> diff --git a/django/contrib/admin/templates/admin/object_history.html b/django/contrib/admin/templates/admin/object_history.html index 5c1114307a..847cfdf2af 100644 --- a/django/contrib/admin/templates/admin/object_history.html +++ b/django/contrib/admin/templates/admin/object_history.html @@ -1,7 +1,8 @@ {% extends "admin/base_site" %} +{% load i18n %} {% block breadcrumbs %} -<div class="breadcrumbs"><a href="../../../../">{{ _('Home') }}</a> › <a href="../../">{{ module_name }}</a> › <a href="../">{{ object|truncatewords:"18" }}</a> › {{ _('History') }}</div> +<div class="breadcrumbs"><a href="../../../../">{% trans 'Home' %}</a> › <a href="../../">{{ module_name }}</a> › <a href="../">{{ object|truncatewords:"18" }}</a> › {% trans 'History' %}</div> {% endblock %} {% block content %} @@ -14,9 +15,9 @@ <table id="change-history"> <thead> <tr> - <th>{{ _('Date/time') }}</th> - <th>{{ _('User') }}</th> - <th>{{ _('Action') }}</th> + <th>{% trans 'Date/time' %}</th> + <th>{% trans 'User' %}</th> + <th>{% trans 'Action' %}</th> </tr> </thead> <tbody> @@ -32,7 +33,7 @@ {% 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 %} diff --git a/django/contrib/admin/templates/registration/logged_out.html b/django/contrib/admin/templates/registration/logged_out.html index 253845c31a..756f82aadc 100644 --- a/django/contrib/admin/templates/registration/logged_out.html +++ b/django/contrib/admin/templates/registration/logged_out.html @@ -1,11 +1,12 @@ {% 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 %} -<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 %} diff --git a/django/contrib/admin/templates/registration/password_change_done.html b/django/contrib/admin/templates/registration/password_change_done.html index 5c1acd32f9..f163e55a68 100644 --- a/django/contrib/admin/templates/registration/password_change_done.html +++ b/django/contrib/admin/templates/registration/password_change_done.html @@ -1,13 +1,14 @@ {% extends "admin/base_site" %} +{% load i18n %} -{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{{ _('Home') }}</a> › {{ _('Password change') }}</div>{% endblock %} +{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> › {% trans 'Password change' %}</div>{% endblock %} -{% block title %}{{ _('Password change successful') }}{% endblock %} +{% block title %}{% trans 'Password change successful' %}{% endblock %} {% 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 %} diff --git a/django/contrib/admin/templates/registration/password_change_form.html b/django/contrib/admin/templates/registration/password_change_form.html index acb2bef2ab..32e5569458 100644 --- a/django/contrib/admin/templates/registration/password_change_form.html +++ b/django/contrib/admin/templates/registration/password_change_form.html @@ -1,25 +1,26 @@ {% extends "admin/base_site" %} +{% load i18n %} -{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{{ _('Home') }}</a> › {{ _('Password change') }}</div>{% endblock %} +{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> › {% trans 'Password change' %}</div>{% endblock %} -{% block title %}{{ _('Password change') }}{% endblock %} +{% block title %}{% trans 'Password change' %}{% endblock %} {% 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"> {% 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 %} -<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 %} -<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> {% endblock %} diff --git a/django/contrib/admin/templates/registration/password_reset_done.html b/django/contrib/admin/templates/registration/password_reset_done.html index 29f0b84452..dff293c931 100644 --- a/django/contrib/admin/templates/registration/password_reset_done.html +++ b/django/contrib/admin/templates/registration/password_reset_done.html @@ -1,13 +1,14 @@ {% extends "admin/base_site" %} +{% load i18n %} -{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{{ _('Home') }}</a> › {{ _('Password reset') }}</div>{% endblock %} +{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> › {% trans 'Password reset' %}</div>{% endblock %} -{% block title %}{{ _('Password reset successful') }}{% endblock %} +{% block title %}{% trans 'Password reset successful' %}{% endblock %} {% 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 %} diff --git a/django/contrib/admin/templates/registration/password_reset_email.html b/django/contrib/admin/templates/registration/password_reset_email.html index 08ca2c142d..b9a0257392 100644 --- a/django/contrib/admin/templates/registration/password_reset_email.html +++ b/django/contrib/admin/templates/registration/password_reset_email.html @@ -1,14 +1,15 @@ -{{ _("You're receiving this e-mail because you requested a password reset") }} -{{ _("for your user account at %(site_name)s") }}. +{% load i18n %} +{% 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/ -{{ _("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" %} diff --git a/django/contrib/admin/templates/registration/password_reset_form.html b/django/contrib/admin/templates/registration/password_reset_form.html index 5e2e24e51c..8db1ede42f 100644 --- a/django/contrib/admin/templates/registration/password_reset_form.html +++ b/django/contrib/admin/templates/registration/password_reset_form.html @@ -1,18 +1,19 @@ {% extends "admin/base_site" %} +{% load i18n %} -{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{{ _('Home') }}</a> › {{ _('Password reset') }}</div>{% endblock %} +{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> › {% trans 'Password reset' %}</div>{% endblock %} -{% block title %}{{ _("Password reset") }}{% endblock %} +{% block title %}{% trans "Password reset" %}{% endblock %} {% 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"> {% 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> {% endblock %} diff --git a/django/core/template/__init__.py b/django/core/template/__init__.py index 9a63098005..0011cb2c9a 100644 --- a/django/core/template/__init__.py +++ b/django/core/template/__init__.py @@ -234,6 +234,97 @@ class Parser: def delete_first_token(self): 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: """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. @@ -257,13 +348,13 @@ class FilterParser: self.current_filter_arg = None # First read the variable part - decide on wether we need # 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() else: self.var = self.read_alphanumeric_token() if not self.var: 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 # Have we reached the end? if self.current is None: @@ -288,19 +379,10 @@ class FilterParser: def read_constant_string_token(self): """Read a constant string that must be delimited by either " - or ' characters. The string is returned with it's delimiters - and a possible i18n tag.""" + or ' characters. The string is returned with it's delimiters.""" val = '' - i18n = False qchar = None 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 ('"', "'"): raise TemplateSyntaxError, "Bad character (expecting '\"' or ''') '%s'" % self.current qchar = self.current @@ -311,11 +393,6 @@ class FilterParser: break 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() return val @@ -430,8 +507,6 @@ def resolve_variable(path, context): """ if path[0] in ('"', "'") and path[0] == path[-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: current = context bits = path.split(VARIABLE_ATTRIBUTE_SEPARATOR) diff --git a/django/templatetags/i18n.py b/django/templatetags/i18n.py new file mode 100644 index 0000000000..37f7175593 --- /dev/null +++ b/django/templatetags/i18n.py @@ -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) + diff --git a/django/utils/translation.py b/django/utils/translation.py index e4de5a8c64..a8b9192bc6 100644 --- a/django/utils/translation.py +++ b/django/utils/translation.py @@ -1,8 +1,10 @@ "translation helper functions" import os +import re import sys import gettext as gettext_module +from cStringIO import StringIO from django.utils.functional import lazy @@ -349,3 +351,89 @@ def install(): """ __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() + |
