Skip to content

Commit

Permalink
Allow translating from javascript files (pypi#15612)
Browse files Browse the repository at this point in the history
Co-authored-by: Dustin Ingram <di@users.noreply.github.com>
Co-authored-by: Mike Fiedler <miketheman@gmail.com>
  • Loading branch information
3 people authored Jan 16, 2025
1 parent f46c35f commit ba6d7bd
Show file tree
Hide file tree
Showing 23 changed files with 1,015 additions and 73 deletions.
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ FROM static-deps AS static
# small amount of copying when only `webpack.config.js` is modified.
COPY warehouse/static/ /opt/warehouse/src/warehouse/static/
COPY warehouse/admin/static/ /opt/warehouse/src/warehouse/admin/static/
COPY warehouse/locale/ /opt/warehouse/src/warehouse/locale/
COPY webpack.config.js /opt/warehouse/src/
COPY webpack.plugin.localize.js /opt/warehouse/src/

RUN NODE_ENV=production npm run build

Expand Down
3 changes: 3 additions & 0 deletions babel.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@
encoding = utf-8
extensions=warehouse.utils.html:ClientSideIncludeExtension,warehouse.i18n.extensions.TrimmedTranslatableTagsExtension
silent=False
[javascript: **.js]
encoding=utf-8
silent=False
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ services:
volumes:
- ./warehouse:/opt/warehouse/src/warehouse:z
- ./webpack.config.js:/opt/warehouse/src/webpack.config.js:z
- ./webpack.plugin.localize.js:/opt/warehouse/src/webpack.plugin.localize.js:z
- ./babel.config.js:/opt/warehouse/src/babel.config.js:z
- ./.stylelintrc.json:/opt/warehouse/src/.stylelintrc.json:z
- ./tests/frontend:/opt/warehouse/src/tests/frontend:z
Expand Down
22 changes: 22 additions & 0 deletions docs/dev/development/frontend.rst
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,25 @@ One of these blocks provides code syntax highlighting, which can be tested with
reference project provided at `<http://localhost/project/pypi-code-highlighting-demo/>`_
when using development database. Source reStructuredText file is available
`here <https://github.com/evemorgen/pypi-code-highlighting-demo>`_.


Javascript localization support
-------------------------------

Strings in JS can be translated, see the see the :doc:`../translations` docs.

As part of the webpack build,
the translation data for each locale in ``KNOWN_LOCALES``
is placed in |warehouse/static/js/warehouse/utils/messages-access.js|_.

A separate js bundle is generated for each locale,
named like this: ``warehouse.[locale].[contenthash].js``.

The JS bundle to include is selected in |warehouse/templates/base.html|_
using the current :code:`request.localizer.locale_name`.

.. |warehouse/static/js/warehouse/utils/messages-access.js| replace:: ``warehouse/static/js/warehouse/utils/messages-access.js``
.. _warehouse/static/js/warehouse/utils/messages-access.js: https://github.com/pypi/warehouse/blob/main/warehouse/static/js/warehouse/utils/messages-access.js

.. |warehouse/templates/base.html| replace:: ``warehouse/templates/base.html``
.. _warehouse/templates/base.html: https://github.com/pypi/warehouse/blob/main/warehouse/templates/base.html
29 changes: 27 additions & 2 deletions docs/dev/translations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ To add a new known locale:
1. Check for `outstanding Weblate pull requests
<https://github.com/pypi/warehouse/pulls/weblate>`_ and merge them if so.
2. In a new branch for |pypi/warehouse|_, add the new language identifier to
``KNOWN_LOCALES`` in |warehouse/i18n/__init__.py|_.
``KNOWN_LOCALES`` in |warehouse/i18n/__init__.py|_ and |webpack.plugin.localize.js|_.
The value is the locale code, and corresponds to a directory in
``warehouse/locale``.
3. Commit these changes and make a new pull request to |pypi/warehouse|_.
Expand All @@ -45,6 +45,8 @@ To add a new known locale:
.. _pypi/warehouse: https://github.com/pypi/warehouse
.. |warehouse/i18n/__init__.py| replace:: ``warehouse/i18n/__init__.py``
.. _warehouse/i18n/__init__.py: https://github.com/pypi/warehouse/blob/main/warehouse/i18n/__init__.py
.. |webpack.plugin.localize.js| replace:: ``webpack.plugin.localize.js``
.. _webpack.plugin.localize.js: https://github.com/pypi/warehouse/blob/main/webpack.plugin.localize.js
.. |pypi/infra| replace:: ``pypi/infra``
.. _pypi/infra: https://github.com/pypi/infra

Expand All @@ -62,11 +64,23 @@ In Python, given a request context, call :code:`request._(message)` to mark
from warehouse.i18n import localize as _
message = _("Your message here.")
In javascript, use :code:`gettext("singular", ...placeholder_values)` and
:code:`ngettext("singular", "plural", count, ...placeholder_values)`.
The function names are important because they need to be recognised by pybabel.

.. code-block:: javascript
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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To pass values you don't want to be translated into
In html, to pass values you don't want to be translated into
translated strings, define them inside the :code:`{% trans %}` tag.
For example, to pass a non-translatable link
:code:`request.route_path('classifiers')` into a string, instead of
Expand All @@ -86,6 +100,15 @@ Instead, define it inside the :code:`{% trans %}` tag:
Filter by <a href="{{ href }}">classifier</a>
{% endtrans %}

In javascript, use :code:`%1`, :code:`%2`, etc as
placeholders and provide the placeholder values:

.. code-block:: javascript
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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand All @@ -105,6 +128,8 @@ variants of a string, for example:

This is not yet directly possible in Python for Warehouse.

In javascript, use :code:`ngettext()` as described above.

Marking views as translatable
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
130 changes: 130 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"scripts": {
"build": "webpack",
"watch": "webpack --watch",
"lint": "eslint 'warehouse/static/js/**' 'warehouse/admin/static/js/**' 'tests/frontend/**' --ignore-pattern 'warehouse/static/js/vendor/**'",
"lint:fix": "eslint 'warehouse/static/js/**' 'warehouse/admin/static/js/**' 'tests/frontend/**' --ignore-pattern 'warehouse/static/js/vendor/**' --fix",
"lint": "eslint 'warehouse/static/js/**' 'warehouse/admin/static/js/**' 'tests/frontend/**' 'webpack.*.js' --ignore-pattern 'warehouse/static/js/vendor/**'",
"lint:fix": "eslint 'warehouse/static/js/**' 'warehouse/admin/static/js/**' 'tests/frontend/**' 'webpack.*.js' --ignore-pattern 'warehouse/static/js/vendor/**' --fix",
"stylelint": "stylelint '**/*.scss' --cache",
"stylelint:fix": "stylelint '**/*.scss' --cache --fix",
"test": "NODE_OPTIONS='$NODE_OPTIONS --experimental-vm-modules' jest --coverage"
Expand Down Expand Up @@ -45,6 +45,7 @@
"css-loader": "^7.1.2",
"css-minimizer-webpack-plugin": "^7.0.0",
"eslint": "^8.36.0",
"gettext-parser": "^7.0.1",
"glob": "^10.2.2",
"image-minimizer-webpack-plugin": "^4.0.2",
"jest": "^29.5.0",
Expand Down
Loading

0 comments on commit ba6d7bd

Please sign in to comment.