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

unicode: Started making the necessary documentation changes required for

unicodification.


git-svn-id: http://code.djangoproject.com/svn/django/branches/unicode@5280 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2007-05-17 20:27:12 +00:00
parent 6042458926
commit e10da26109
3 changed files with 68 additions and 48 deletions

View File

@ -368,6 +368,7 @@ Model style
* All database fields * All database fields
* ``class Meta`` * ``class Meta``
* ``class Admin`` * ``class Admin``
* ``def __unicode__()``
* ``def __str__()`` * ``def __str__()``
* ``def save()`` * ``def save()``
* ``def get_absolute_url()`` * ``def get_absolute_url()``

View File

@ -68,23 +68,43 @@ In Python code
Standard translation Standard translation
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
Specify a translation string by using the function ``_()``. (Yes, the name of Specify a translation string by using the function ``ugettext()``. Since you
the function is the "underscore" character.) This function is available may well be typing this a lot, it's often worthwhile importing it as a shorter
globally in any Python module; you don't have to import it. alias and ``_`` is a very common choice (i.e. the function is called as
``_()``).
.. note::
Python's standard library ``gettext`` module installs ``_()`` into the
global namespace, as an alias for ``gettext()``. In Django, we have chosen
not to follow this practice, for a couple of reasons:
1. For international character set (unicode) support, you really wanting
to be using ``ugettext()``, rather than ``gettext()``. Sometimes, you
should be using ``ugettext_lazy()`` more often. By not installing
``_`` directly, the developer is required to think about which is the
most appropriate function to use.
2. Python's interactive shell uses ``_`` to represent "the previous
result". This is also used in doctest tests and having ``_()`` causes
interference. Explicitly importing ``ugettext()`` as ``_()`` avoids
this problem.
In this example, the text ``"Welcome to my site."`` is marked as a translation In this example, the text ``"Welcome to my site."`` is marked as a translation
string:: string::
from django.utils.translation import ugettext as _
def my_view(request): def my_view(request):
output = _("Welcome to my site.") output = _("Welcome to my site.")
return HttpResponse(output) return HttpResponse(output)
The function ``django.utils.translation.gettext()`` is identical to ``_()``. Obviously you could code this without using the alias. This example is
This example is identical to the previous one:: identical to the previous one::
from django.utils.translation import ugettext
from django.utils.translation import gettext
def my_view(request): def my_view(request):
output = gettext("Welcome to my site.") output = ugettext("Welcome to my site.")
return HttpResponse(output) return HttpResponse(output)
Translation works on computed values. This example is identical to the previous Translation works on computed values. This example is identical to the previous
@ -107,7 +127,7 @@ examples, is that Django's translation-string-detecting utility,
``make-messages.py``, won't be able to find these strings. More on ``make-messages.py``, won't be able to find these strings. More on
``make-messages`` later.) ``make-messages`` later.)
The strings you pass to ``_()`` or ``gettext()`` can take placeholders, The strings you pass to ``_()`` or ``ugettext()`` can take placeholders,
specified with Python's standard named-string interpolation syntax. Example:: specified with Python's standard named-string interpolation syntax. Example::
def my_view(request, n): def my_view(request, n):
@ -120,14 +140,14 @@ while a Spanish translation may be ``"Me llamo Adrian."`` -- with the
placeholder (the name) placed after the translated text instead of before it. placeholder (the name) placed after the translated text instead of before it.
For this reason, you should use named-string interpolation (e.g., ``%(name)s``) For this reason, you should use named-string interpolation (e.g., ``%(name)s``)
instead of positional interpolation (e.g., ``%s`` or ``%d``). If you used instead of positional interpolation (e.g., ``%s`` or ``%d``) whenever you
positional interpolation, translations wouldn't be able to reorder placeholder have more than a single parameter. If you used positional interpolation,
text. translations wouldn't be able to reorder placeholder text.
Marking strings as no-op Marking strings as no-op
~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~
Use the function ``django.utils.translation.gettext_noop()`` to mark a string Use the function ``django.utils.translation.ugettext_noop()`` to mark a string
as a translation string without translating it. The string is later translated as a translation string without translating it. The string is later translated
from a variable. from a variable.
@ -139,25 +159,25 @@ as when the string is presented to the user.
Lazy translation Lazy translation
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
Use the function ``django.utils.translation.gettext_lazy()`` to translate Use the function ``django.utils.translation.ugettext_lazy()`` to translate
strings lazily -- when the value is accessed rather than when the strings lazily -- when the value is accessed rather than when the
``gettext_lazy()`` function is called. ``ugettext_lazy()`` function is called.
For example, to translate a model's ``help_text``, do the following:: For example, to translate a model's ``help_text``, do the following::
from django.utils.translation import gettext_lazy from django.utils.translation import ugettext_lazy
class MyThing(models.Model): class MyThing(models.Model):
name = models.CharField(help_text=gettext_lazy('This is the help text')) name = models.CharField(help_text=ugettext_lazy('This is the help text'))
In this example, ``gettext_lazy()`` stores a lazy reference to the string -- In this example, ``ugettext_lazy()`` stores a lazy reference to the string --
not the actual translation. The translation itself will be done when the string not the actual translation. The translation itself will be done when the string
is used in a string context, such as template rendering on the Django admin site. is used in a string context, such as template rendering on the Django admin site.
If you don't like the verbose name ``gettext_lazy``, you can just alias it as If you don't like the verbose name ``ugettext_lazy``, you can just alias it as
``_`` (underscore), like so:: ``_`` (underscore), like so::
from django.utils.translation import gettext_lazy as _ from django.utils.translation import ugettext_lazy as _
class MyThing(models.Model): class MyThing(models.Model):
name = models.CharField(help_text=_('This is the help text')) name = models.CharField(help_text=_('This is the help text'))
@ -167,7 +187,7 @@ translations for the field names and table names, too. This means writing
explicit ``verbose_name`` and ``verbose_name_plural`` options in the ``Meta`` explicit ``verbose_name`` and ``verbose_name_plural`` options in the ``Meta``
class, though:: class, though::
from django.utils.translation import gettext_lazy as _ from django.utils.translation import ugettext_lazy as _
class MyThing(models.Model): class MyThing(models.Model):
name = models.CharField(_('name'), help_text=_('This is the help text')) name = models.CharField(_('name'), help_text=_('This is the help text'))
@ -180,24 +200,24 @@ class, though::
Pluralization Pluralization
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
Use the function ``django.utils.translation.ngettext()`` to specify pluralized Use the function ``django.utils.translation.ungettext()`` to specify pluralized
messages. Example:: messages. Example::
from django.utils.translation import ngettext from django.utils.translation import ungettext
def hello_world(request, count): def hello_world(request, count):
page = ngettext('there is %(count)d object', 'there are %(count)d objects', count) % { page = ungettext('there is %(count)d object', 'there are %(count)d objects', count) % {
'count': count, 'count': count,
} }
return HttpResponse(page) return HttpResponse(page)
``ngettext`` takes three arguments: the singular translation string, the plural ``ungettext`` takes three arguments: the singular translation string, the plural
translation string and the number of objects (which is passed to the translation string and the number of objects (which is passed to the
translation languages as the ``count`` variable). translation languages as the ``count`` variable).
In template code In template code
---------------- ----------------
Using translations in `Django templates`_ uses two template tags and a slightly Translations in `Django templates`_ uses two template tags and a slightly
different syntax than in Python code. To give your template access to these different syntax than in Python code. To give your template access to these
tags, put ``{% load i18n %}`` toward the top of your template. tags, put ``{% load i18n %}`` toward the top of your template.
@ -243,7 +263,7 @@ To pluralize, specify both the singular and plural forms with the
{% endblocktrans %} {% endblocktrans %}
Internally, all block and inline translations use the appropriate Internally, all block and inline translations use the appropriate
``gettext`` / ``ngettext`` call. ``ugettext`` / ``ungettext`` call.
Each ``RequestContext`` has access to two translation-specific variables: Each ``RequestContext`` has access to two translation-specific variables:
@ -487,26 +507,26 @@ Notes:
* If you define a custom ``LANGUAGES`` setting, as explained in the * If you define a custom ``LANGUAGES`` setting, as explained in the
previous bullet, it's OK to mark the languages as translation strings previous bullet, it's OK to mark the languages as translation strings
-- but use a "dummy" ``gettext()`` function, not the one in -- but use a "dummy" ``ugettext()`` function, not the one in
``django.utils.translation``. You should *never* import ``django.utils.translation``. You should *never* import
``django.utils.translation`` from within your settings file, because that ``django.utils.translation`` from within your settings file, because that
module in itself depends on the settings, and that would cause a circular module in itself depends on the settings, and that would cause a circular
import. import.
The solution is to use a "dummy" ``gettext()`` function. Here's a sample The solution is to use a "dummy" ``ugettext()`` function. Here's a sample
settings file:: settings file::
gettext = lambda s: s ugettext = lambda s: s
LANGUAGES = ( LANGUAGES = (
('de', gettext('German')), ('de', ugettext('German')),
('en', gettext('English')), ('en', ugettext('English')),
) )
With this arrangement, ``make-messages.py`` will still find and mark With this arrangement, ``make-messages.py`` will still find and mark
these strings for translation, but the translation won't happen at these strings for translation, but the translation won't happen at
runtime -- so you'll have to remember to wrap the languages in the *real* runtime -- so you'll have to remember to wrap the languages in the *real*
``gettext()`` in any code that uses ``LANGUAGES`` at runtime. ``ugettext()`` in any code that uses ``LANGUAGES`` at runtime.
* The ``LocaleMiddleware`` can only select languages for which there is a * The ``LocaleMiddleware`` can only select languages for which there is a
Django-provided base translation. If you want to provide translations Django-provided base translation. If you want to provide translations
@ -712,23 +732,23 @@ interface to access it::
document.write(gettext('this is to be translated')); document.write(gettext('this is to be translated'));
There even is a ``ngettext`` interface and a string interpolation function:: There even is a ``ungettext`` interface and a string interpolation function::
d = { d = {
count: 10 count: 10
}; };
s = interpolate(ngettext('this is %(count)s object', 'this are %(count)s objects', d.count), d); s = interpolate(ungettext('this is %(count)s object', 'this are %(count)s objects', d.count), d);
The ``interpolate`` function supports both positional interpolation and named The ``interpolate`` function supports both positional interpolation and named
interpolation. So the above could have been written as:: interpolation. So the above could have been written as::
s = interpolate(ngettext('this is %s object', 'this are %s objects', 11), [11]); s = interpolate(ungettext('this is %s object', 'this are %s objects', 11), [11]);
The interpolation syntax is borrowed from Python. You shouldn't go over the top The interpolation syntax is borrowed from Python. You shouldn't go over the top
with string interpolation, though: this is still JavaScript, so the code will with string interpolation, though: this is still JavaScript, so the code will
have to do repeated regular-expression substitutions. This isn't as fast as have to do repeated regular-expression substitutions. This isn't as fast as
string interpolation in Python, so keep it to those cases where you really string interpolation in Python, so keep it to those cases where you really
need it (for example, in conjunction with ``ngettext`` to produce proper need it (for example, in conjunction with ``ungettext`` to produce proper
pluralizations). pluralizations).
Creating JavaScript translation catalogs Creating JavaScript translation catalogs
@ -750,16 +770,13 @@ Specialities of Django translation
If you know ``gettext``, you might note these specialities in the way Django If you know ``gettext``, you might note these specialities in the way Django
does translation: does translation:
* The string domain is ``django`` or ``djangojs``. The string domain is used to * The string domain is ``django`` or ``djangojs``. The string domain is
differentiate between different programs that store their data in a used to differentiate between different programs that store their data
common message-file library (usually ``/usr/share/locale/``). The ``django`` in a common message-file library (usually ``/usr/share/locale/``). The
domain is used for python and template translation strings and is loaded into ``django`` domain is used for python and template translation strings
the global translation catalogs. The ``djangojs`` domain is only used for and is loaded into the global translation catalogs. The ``djangojs``
JavaScript translation catalogs to make sure that those are as small as domain is only used for JavaScript translation catalogs to make sure
possible. that those are as small as possible.
* Django only uses ``gettext`` and ``gettext_noop``. That's because Django
always uses ``DEFAULT_CHARSET`` strings internally. There isn't much use
in using ``ugettext``, because you'll always need to produce utf-8
anyway.
* Django doesn't use ``xgettext`` alone. It uses Python wrappers around * Django doesn't use ``xgettext`` alone. It uses Python wrappers around
``xgettext`` and ``msgfmt``. That's mostly for convenience. ``xgettext`` and ``msgfmt``. That's mostly for convenience.

View File

@ -1764,7 +1764,9 @@ But this template code is good::
characters (required by the URI spec, `RFC 2396`_) that has been characters (required by the URI spec, `RFC 2396`_) that has been
URL-encoded, if necessary. Code and templates using ``get_absolute_url()`` URL-encoded, if necessary. Code and templates using ``get_absolute_url()``
should be able to use the result directly without needing to do any should be able to use the result directly without needing to do any
further processing. further processing. You may wish to use the
``django.utils.encoding.iri_to_uri()`` function to help with this if you
are using unicode strings a lot.
.. _RFC 2396: http://www.ietf.org/rfc/rfc2396.txt .. _RFC 2396: http://www.ietf.org/rfc/rfc2396.txt