Translations¶
We use Weblate to manage PyPI translations across several languages. Visit the Warehouse project on Weblate to contribute.
If you are experiencing issues as a translator, please let us know by opening a translation issue on the Warehouse issue tracker.
Adding a newly completed translation¶
Weblate will automatically add commits to a pull request as translations are updated.
When a translation reaches 100%, it should be added as a known locale and have it's MO file (Machine Object file) compiled.
To add a new known locale:
- Check for outstanding Weblate pull requests and merge them if so.
- In a new branch for
pypi/warehouse, add the new language identifier toKNOWN_LOCALESinwarehouse/i18n/__init__.pyandwebpack.plugin.localize.js. The value is the locale code, and corresponds to a directory inwarehouse/locale. - Commit these changes and make a new pull request to
pypi/warehouse. -
In a new branch for
pypi/infra, add the new identifier to theaccept.language_lookupcall in PyPI's VCL configuration. The value is the IANA language subtag string for the locale.Note
This value may differ from the identifier used for
KNOWN_LOCALES, e.g.pt-BRvspt_BR. -
Commit these change and make a new pull request to
pypi/infrareferencing your pull request topypi/warehouse.
Marking new strings for translation¶
In an HTML template, use the {% trans %} and {% endtrans %}
tags to mark a string for translation.
In Python, given a request context, call request._(message) to mark
message for translation. Without a request context, you can do the following:
In javascript, use gettext("singular", ...placeholder_values) and
ngettext("singular", "plural", count, ...placeholder_values).
The function names are important because they need to be recognised by pybabel.
import { gettext, ngettext } from "../utils/messages-access";
gettext("Get some fruit");
// -> (en) "Get some fruit"
ngettext("Yesterday", "In the past", numDays);
// -> (en) numDays is 1: "Yesterday"; numDays is 3: "In the past"
Passing non-translatable values to translated strings¶
In html, to pass values you don't want to be translated into
translated strings, define them inside the {% trans %} tag.
For example, to pass a non-translatable link
request.route_path('classifiers') into a string, instead of
placing it directly in the string like so:
Instead, define it inside the {% trans %} tag:
{% trans href=request.route_path('classifiers') %}
Filter by <a href="{{ href }}">classifier</a>
{% endtrans %}
In javascript, use %1, %2, etc as
placeholders and provide the placeholder values:
import { ngettext } from "../utils/messages-access";
ngettext("Yesterday", "About %1 days ago", numDays, numDays);
// -> (en) numDays is 1: "Yesterday"; numDays is 3: "About 3 days ago"
Marking new strings for pluralization¶
To pluralize a translated string in an HTML template,
use the {% pluralize %} tag to separate the singular and plural
variants of a string, for example:
{% trans n_hours=n_hours %}
This link will expire in {{ n_hours }} hour.
{% pluralize %}
This link will expire in {{ n_hours }} hours.
{% endtrans %}
This is not yet directly possible in Python for Warehouse.
In javascript, use ngettext() as described above.
Marking views as translatable¶
If a view's renderer uses translations, you should mark the view as
translatable by setting the has_translations option in
the view's configuration:
@viewconfig(
route_name="sample.route",
renderer="translatable_sample.html",
has_translations=True,
)
class SampleViews:
You may have to rebuild the translation files.