mirror of
https://github.com/django/django.git
synced 2025-07-24 05:36:15 +00:00
Fixed #19567 -- Added JavaScriptCatalog and JSONCatalog class-based views
Thanks Cristiano Coelho and Tim Graham for the reviews.
This commit is contained in:
parent
79a091820f
commit
de40cfbe74
11 changed files with 591 additions and 40 deletions
|
@ -959,15 +959,76 @@ Django provides an integrated solution for these problems: It passes the
|
|||
translations into JavaScript, so you can call ``gettext``, etc., from within
|
||||
JavaScript.
|
||||
|
||||
The main solution to these problems is the following ``JavaScriptCatalog`` view,
|
||||
which generates a JavaScript code library with functions that mimic the
|
||||
``gettext`` interface, plus an array of translation strings.
|
||||
|
||||
.. _javascript_catalog-view:
|
||||
|
||||
The ``JavaScriptCatalog`` view
|
||||
------------------------------
|
||||
|
||||
.. module:: django.views.i18n
|
||||
|
||||
.. versionadded:: 1.10
|
||||
|
||||
.. class:: JavaScriptCatalog
|
||||
|
||||
A view that produces a JavaScript code library with functions that mimic
|
||||
the ``gettext`` interface, plus an array of translation strings.
|
||||
|
||||
**Attributes**
|
||||
|
||||
.. attribute:: domain
|
||||
|
||||
Translation domain containing strings to add in the view output.
|
||||
Defaults to ``'djangojs'``.
|
||||
|
||||
.. attribute:: packages
|
||||
|
||||
A list of :attr:`application names <django.apps.AppConfig.name>` among
|
||||
installed applications. Those apps should contain a ``locale``
|
||||
directory. All those catalogs plus all catalogs found in
|
||||
:setting:`LOCALE_PATHS` (which are always included) are merged into one
|
||||
catalog. Defaults to ``None``, which means that all available
|
||||
translations from all :setting:`INSTALLED_APPS` are provided in the
|
||||
JavaScript output.
|
||||
|
||||
**Example with default values**::
|
||||
|
||||
from django.views.i18n import JavaScriptCatalog
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^jsi18n/$', JavaScriptCatalog.as_view(), name='javascript-catalog'),
|
||||
]
|
||||
|
||||
**Example with custom packages**::
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^jsi18n/myapp/$',
|
||||
JavaScriptCatalog.as_view(packages=['your.app.label']),
|
||||
name='javascript-catalog'),
|
||||
]
|
||||
|
||||
The precedence of translations is such that the packages appearing later in the
|
||||
``packages`` argument have higher precedence than the ones appearing at the
|
||||
beginning. This is important in the case of clashing translations for the same
|
||||
literal.
|
||||
|
||||
If you use more than one ``JavaScriptCatalog`` view on a site and some of them
|
||||
define the same strings, the strings in the catalog that was loaded last take
|
||||
precedence.
|
||||
|
||||
The ``javascript_catalog`` view
|
||||
-------------------------------
|
||||
|
||||
.. module:: django.views.i18n
|
||||
|
||||
.. function:: javascript_catalog(request, domain='djangojs', packages=None)
|
||||
|
||||
.. deprecated:: 1.10
|
||||
|
||||
``javascript_catalog()`` is deprecated in favor of
|
||||
:class:`JavaScriptCatalog` and will be removed in Django 2.0.
|
||||
|
||||
The main solution to these problems is the
|
||||
:meth:`django.views.i18n.javascript_catalog` view, which sends out a JavaScript
|
||||
code library with functions that mimic the ``gettext`` interface, plus an array
|
||||
|
@ -1209,6 +1270,37 @@ will render a conditional expression. This will evaluate to either a ``true``
|
|||
|
||||
.. highlight:: python
|
||||
|
||||
The ``JSONCatalog`` view
|
||||
------------------------
|
||||
|
||||
.. versionadded:: 1.10
|
||||
|
||||
.. class:: JSONCatalog
|
||||
|
||||
In order to use another client-side library to handle translations, you may
|
||||
want to take advantage of the ``JSONCatalog`` view. It's similar to
|
||||
:class:`~django.views.i18n.JavaScriptCatalog` but returns a JSON response.
|
||||
|
||||
See the documentation for :class:`~django.views.i18n.JavaScriptCatalog`
|
||||
to learn about possible values and use of the ``domain`` and ``packages``
|
||||
attributes.
|
||||
|
||||
The response format is as follows:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
{
|
||||
"catalog": {
|
||||
# Translations catalog
|
||||
},
|
||||
"formats": {
|
||||
# Language formats for date, time, etc.
|
||||
},
|
||||
"plural": "..." # Expression for plural forms, or null.
|
||||
}
|
||||
|
||||
.. JSON doesn't allow comments so highlighting as JSON won't work here.
|
||||
|
||||
The ``json_catalog`` view
|
||||
-------------------------
|
||||
|
||||
|
@ -1216,6 +1308,11 @@ The ``json_catalog`` view
|
|||
|
||||
.. function:: json_catalog(request, domain='djangojs', packages=None)
|
||||
|
||||
.. deprecated:: 1.10
|
||||
|
||||
``json_catalog()`` is deprecated in favor of :class:`JSONCatalog` and will
|
||||
be removed in Django 2.0.
|
||||
|
||||
In order to use another client-side library to handle translations, you may
|
||||
want to take advantage of the ``json_catalog()`` view. It's similar to
|
||||
:meth:`~django.views.i18n.javascript_catalog` but returns a JSON response.
|
||||
|
@ -1260,9 +1357,9 @@ The response format is as follows:
|
|||
Note on performance
|
||||
-------------------
|
||||
|
||||
The :func:`~django.views.i18n.javascript_catalog` view generates the catalog
|
||||
from ``.mo`` files on every request. Since its output is constant — at least
|
||||
for a given version of a site — it's a good candidate for caching.
|
||||
The various JavaScript/JSON i18n views generate the catalog from ``.mo`` files
|
||||
on every request. Since its output is constant, at least for a given version
|
||||
of a site, it's a good candidate for caching.
|
||||
|
||||
Server-side caching will reduce CPU load. It's easily implemented with the
|
||||
:func:`~django.views.decorators.cache.cache_page` decorator. To trigger cache
|
||||
|
@ -1271,12 +1368,14 @@ prefix, as shown in the example below, or map the view at a version-dependent
|
|||
URL::
|
||||
|
||||
from django.views.decorators.cache import cache_page
|
||||
from django.views.i18n import javascript_catalog
|
||||
from django.views.i18n import JavaScriptCatalog
|
||||
|
||||
# The value returned by get_version() must change when translations change.
|
||||
@cache_page(86400, key_prefix='js18n-%s' % get_version())
|
||||
def cached_javascript_catalog(request, domain='djangojs', packages=None):
|
||||
return javascript_catalog(request, domain, packages)
|
||||
urlpatterns = [
|
||||
url(r'^jsi18n/$',
|
||||
cache_page(86400, key_prefix='js18n-%s' % get_version())(JavaScriptCatalog.as_view()),
|
||||
name='javascript-catalog'),
|
||||
]
|
||||
|
||||
Client-side caching will save bandwidth and make your site load faster. If
|
||||
you're using ETags (:setting:`USE_ETAGS = True <USE_ETAGS>`), you're already
|
||||
|
@ -1286,13 +1385,15 @@ whenever you restart your application server::
|
|||
|
||||
from django.utils import timezone
|
||||
from django.views.decorators.http import last_modified
|
||||
from django.views.i18n import javascript_catalog
|
||||
from django.views.i18n import JavaScriptCatalog
|
||||
|
||||
last_modified_date = timezone.now()
|
||||
|
||||
@last_modified(lambda req, **kw: last_modified_date)
|
||||
def cached_javascript_catalog(request, domain='djangojs', packages=None):
|
||||
return javascript_catalog(request, domain, packages)
|
||||
urlpatterns = [
|
||||
url(r'^jsi18n/$',
|
||||
last_modified(lambda req, **kw: last_modified_date)(JavaScriptCatalog.as_view()),
|
||||
name='javascript-catalog'),
|
||||
]
|
||||
|
||||
You can even pre-generate the JavaScript catalog as part of your deployment
|
||||
procedure and serve it as a static file. This radical technique is implemented
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue