{"id":75949,"date":"2020-01-20T12:38:35","date_gmt":"2020-01-20T07:08:35","guid":{"rendered":"https:\/\/www.vskills.in\/certification\/tutorial\/?p=75949"},"modified":"2024-04-12T14:17:42","modified_gmt":"2024-04-12T08:47:42","slug":"translations-and-javascript","status":"publish","type":"page","link":"https:\/\/www.vskills.in\/certification\/tutorial\/translations-and-javascript\/","title":{"rendered":"Translations and JavaScript"},"content":{"rendered":"<p>Adding translations to JavaScript poses some problems:<\/p>\n<ul>\n<li>&nbsp;JavaScript code doesn\u2019t have access to a gettext implementation.<\/li>\n<li>JavaScript code doesn\u2019t have access to .po or .mo files; they need to be delivered by the server.<\/li>\n<li>The translation catalogs for JavaScript should be kept as small as possible.<br>\nDjango provides an integrated solution for these problems: It passes the translations into JavaScript, so you can call gettext, etc., from within JavaScript.<\/li>\n<\/ul>\n<h3>The Javascript_Catalog View<\/h3>\n<p>The main solution to these problems is the django.views.i18n.javascript_catalog() view, which sends out a JavaScript code library with functions that mimic the gettext interface, plus an array of translation strings.<\/p>\n<p>Those translation strings are taken from applications or Django core, according to what you specify in either the info_dict or the URL. Paths listed in LOCALE_PATHS are also included.<\/p>\n<p>You hook it up like this:<\/p>\n<p>from django.views.i18n import javascript_catalog<\/p>\n<p>js_info_dict = {<br>\n&#8216;packages&#8217;: (&#8216;your.app.package&#8217;,),<br>\n}<\/p>\n<p>urlpatterns = [<br>\nurl(r&#8217;^jsi18n\/$&#8217;, javascript_catalog, js_info_dict),<br>\n]\n<p>Each string in packages should be in Python dotted-package syntax (the same format as the strings in INSTALLED_APPS) and should refer to a package that contains a locale directory. If you specify multiple packages, all those catalogs are merged into one catalog. This is useful if you have JavaScript that uses strings from different applications.<\/p>\n<p>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.<\/p>\n<p>By default, the view uses the djangojs gettext domain. This can be changed by altering the domain argument. You can make the view dynamic by putting the packages into the URL pattern:<\/p>\n<p>urlpatterns = [<br>\nurl(r&#8217;^jsi18n\/(?P&lt;packages&gt;\\S+?)\/$&#8217;, javascript_catalog),<br>\n]\n<p>With this, you specify the packages as a list of package names delimited by \u2018+\u2019 signs in the URL. This is especially useful if your pages use code from different apps and this changes often and you don\u2019t want to pull in one big catalog file. As a security measure, these values can only be either django.conf or any package from the INSTALLED_APPS setting.<\/p>\n<p>The JavaScript translations found in the paths listed in the LOCALE_PATHS setting are also always included. To keep consistency with the translations lookup order algorithm used for Python and templates, the directories listed in LOCALE_PATHS have the highest precedence with the ones appearing first having higher precedence than the ones appearing later.<\/p>\n<h3>Using The Javascript Translation Catalog<\/h3>\n<p>To use the catalog, just pull in the dynamically generated script like this:<\/p>\n<p>&lt;script type=&#8221;text\/javascript&#8221; src=&#8221;{% url \u2018django.views.i18n.javascript_catalog\u2019 %}&#8221;&gt;&lt;\/script&gt;<\/p>\n<p>This uses reverse URL lookup to find the URL of the JavaScript catalog view. When the catalog is loaded, your JavaScript code can use the standard gettext interface to access it:<\/p>\n<p>document.write(gettext(&#8216;this is to be translated&#8217;));<br>\nThere is also an `ngettext` interface:<\/p>\n<p>var object_cnt = 1 \/\/ or 0, or 2, or 3, &#8230;<br>\ns = ngettext(&#8216;literal for the singular case&#8217;,<br>\n&#8216;literal for the plural case&#8217;, object_cnt);<\/p>\n<p>and even a string interpolation function:<\/p>\n<p>function interpolate(fmt, obj, named);<\/p>\n<p>The interpolation syntax is borrowed from Python, so the interpolate function supports both positional and named interpolation:<\/p>\n<ul>\n<li>Positional interpolation: obj contains a JavaScript array object whose elements values are then sequentially interpolated in their corresponding fmt placeholders in the same order they appear. For example:<\/li>\n<\/ul>\n<p>fmts = ngettext(&#8216;There is %s object. Remaining: %s&#8217;,<br>\n&#8216;There are %s objects. Remaining: %s&#8217;, 11);<br>\ns = interpolate(fmts, [11, 20]);<br>\n\/\/ s is &#8216;There are 11 objects. Remaining: 20&#8217;<\/p>\n<ul>\n<li>&nbsp;Named interpolation: This mode is selected by passing the optional boolean named parameter as true. obj contains a JavaScript object or associative array. For example:<\/li>\n<\/ul>\n<p>d = {<br>\ncount: 10,<br>\ntotal: 50<br>\n};<\/p>\n<p>fmts = ngettext(&#8216;Total: %(total)s, there is %(count)s object&#8217;,<br>\n&#8216;there are %(count)s of a total of %(total)s objects&#8217;, d.count);<br>\ns = interpolate(fmts, d, true);<\/p>\n<p>You shouldn\u2019t go over the top with string interpolation, though: this is still JavaScript, so the code has to make repeated regular-expression substitutions. This isn\u2019t as fast as string interpolation in Python, so keep it to those cases where you really need it (for example, in conjunction with ngettext to produce proper pluralization).<\/p>\n<h3>Performance<\/h3>\n<p>The javascript_catalog() view generates the catalog from .mo files on every request. Since its output is constant \u2013 at least for a given version of a site \u2013 it\u2019s a good candidate for caching.<\/p>\n<p>Server-side caching will reduce CPU load. It\u2019s easily implemented with the cache_page() decorator. To trigger cache invalidation when your translations change, provide a version-dependent key prefix, as shown in the example below, or map the view at a version-dependent URL.<\/p>\n<p>from django.views.decorators.cache import cache_page<br>\nfrom django.views.i18n import javascript_catalog<\/p>\n<p># The value returned by get_version() must change when translations change.<br>\n@cache_page(86400, key_prefix=&#8217;js18n-%s&#8217; % get_version())<br>\ndef cached_javascript_catalog(request, domain=&#8217;djangojs&#8217;, packages=None):<br>\nreturn javascript_catalog(request, domain, packages)<\/p>\n<p>Client-side caching will save bandwidth and make your site load faster. If you\u2019re using ETags (USE_ETAGS = True), you\u2019re already covered. Otherwise, you can apply conditional decorators. In the following example, the cache is invalidated whenever you restart your application server.<\/p>\n<p>from django.utils import timezone<br>\nfrom django.views.decorators.http import last_modified<br>\nfrom django.views.i18n import javascript_catalog<\/p>\n<p>last_modified_date = timezone.now()<\/p>\n<p>@last_modified(lambda req, **kw: last_modified_date)<br>\ndef cached_javascript_catalog(request, domain=&#8217;djangojs&#8217;, packages=None):<br>\nreturn javascript_catalog(request, domain, packages)<\/p>\n<p>You can even pre-generate the JavaScript catalog as part of your deployment procedure and serve it as a static file.<\/p>\n\n\n<p><a href=\"https:\/\/www.vskills.in\/certification\/tutorial\/certified-django-developer\/\" target=\"_blank\" rel=\"noreferrer noopener\">Back to Tutorial<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Adding translations to JavaScript poses some problems: &nbsp;JavaScript code doesn\u2019t have access to a gettext implementation. JavaScript code doesn\u2019t have access to .po or .mo files; they need to be delivered by the server. The translation catalogs for JavaScript should be kept as small as possible. Django provides an integrated solution for these problems: It&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"categories":[8655],"tags":[8870],"class_list":["post-75949","page","type-page","status-publish","hentry","category-django-web-development","tag-translations-and-javascript"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Translations and JavaScript - Tutorial<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.vskills.in\/certification\/tutorial\/translations-and-javascript\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Translations and JavaScript - Tutorial\" \/>\n<meta property=\"og:description\" content=\"Adding translations to JavaScript poses some problems: &nbsp;JavaScript code doesn\u2019t have access to a gettext implementation. JavaScript code doesn\u2019t have access to .po or .mo files; they need to be delivered by the server. The translation catalogs for JavaScript should be kept as small as possible. Django provides an integrated solution for these problems: It...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.vskills.in\/certification\/tutorial\/translations-and-javascript\/\" \/>\n<meta property=\"og:site_name\" content=\"Tutorial\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/vskills.in\/\" \/>\n<meta property=\"article:modified_time\" content=\"2024-04-12T08:47:42+00:00\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.vskills.in\/certification\/tutorial\/translations-and-javascript\/\",\"url\":\"https:\/\/www.vskills.in\/certification\/tutorial\/translations-and-javascript\/\",\"name\":\"Translations and JavaScript - Tutorial\",\"isPartOf\":{\"@id\":\"https:\/\/www.vskills.in\/certification\/tutorial\/#website\"},\"datePublished\":\"2020-01-20T07:08:35+00:00\",\"dateModified\":\"2024-04-12T08:47:42+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.vskills.in\/certification\/tutorial\/translations-and-javascript\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.vskills.in\/certification\/tutorial\/translations-and-javascript\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.vskills.in\/certification\/tutorial\/translations-and-javascript\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.vskills.in\/certification\/tutorial\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Translations and JavaScript\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.vskills.in\/certification\/tutorial\/#website\",\"url\":\"https:\/\/www.vskills.in\/certification\/tutorial\/\",\"name\":\"Tutorial\",\"description\":\"Vskills - A initiative in elearning and certification\",\"publisher\":{\"@id\":\"https:\/\/www.vskills.in\/certification\/tutorial\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.vskills.in\/certification\/tutorial\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.vskills.in\/certification\/tutorial\/#organization\",\"name\":\"Vskills\",\"url\":\"https:\/\/www.vskills.in\/certification\/tutorial\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.vskills.in\/certification\/tutorial\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.vskills.in\/certification\/tutorial\/wp-content\/uploads\/2017\/07\/vskills-min-logo.jpg\",\"contentUrl\":\"https:\/\/www.vskills.in\/certification\/tutorial\/wp-content\/uploads\/2017\/07\/vskills-min-logo.jpg\",\"width\":73,\"height\":55,\"caption\":\"Vskills\"},\"image\":{\"@id\":\"https:\/\/www.vskills.in\/certification\/tutorial\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/vskills.in\/\",\"https:\/\/x.com\/vskills_in\",\"https:\/\/www.linkedin.com\/company-beta\/1371554\/\",\"https:\/\/www.youtube.com\/channel\/UCMWnscxPwRF_PqXo9B7q_Tw\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Translations and JavaScript - Tutorial","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.vskills.in\/certification\/tutorial\/translations-and-javascript\/","og_locale":"en_US","og_type":"article","og_title":"Translations and JavaScript - Tutorial","og_description":"Adding translations to JavaScript poses some problems: &nbsp;JavaScript code doesn\u2019t have access to a gettext implementation. JavaScript code doesn\u2019t have access to .po or .mo files; they need to be delivered by the server. The translation catalogs for JavaScript should be kept as small as possible. Django provides an integrated solution for these problems: It...","og_url":"https:\/\/www.vskills.in\/certification\/tutorial\/translations-and-javascript\/","og_site_name":"Tutorial","article_publisher":"https:\/\/www.facebook.com\/vskills.in\/","article_modified_time":"2024-04-12T08:47:42+00:00","twitter_misc":{"Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.vskills.in\/certification\/tutorial\/translations-and-javascript\/","url":"https:\/\/www.vskills.in\/certification\/tutorial\/translations-and-javascript\/","name":"Translations and JavaScript - Tutorial","isPartOf":{"@id":"https:\/\/www.vskills.in\/certification\/tutorial\/#website"},"datePublished":"2020-01-20T07:08:35+00:00","dateModified":"2024-04-12T08:47:42+00:00","breadcrumb":{"@id":"https:\/\/www.vskills.in\/certification\/tutorial\/translations-and-javascript\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.vskills.in\/certification\/tutorial\/translations-and-javascript\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.vskills.in\/certification\/tutorial\/translations-and-javascript\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.vskills.in\/certification\/tutorial\/"},{"@type":"ListItem","position":2,"name":"Translations and JavaScript"}]},{"@type":"WebSite","@id":"https:\/\/www.vskills.in\/certification\/tutorial\/#website","url":"https:\/\/www.vskills.in\/certification\/tutorial\/","name":"Tutorial","description":"Vskills - A initiative in elearning and certification","publisher":{"@id":"https:\/\/www.vskills.in\/certification\/tutorial\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.vskills.in\/certification\/tutorial\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.vskills.in\/certification\/tutorial\/#organization","name":"Vskills","url":"https:\/\/www.vskills.in\/certification\/tutorial\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.vskills.in\/certification\/tutorial\/#\/schema\/logo\/image\/","url":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-content\/uploads\/2017\/07\/vskills-min-logo.jpg","contentUrl":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-content\/uploads\/2017\/07\/vskills-min-logo.jpg","width":73,"height":55,"caption":"Vskills"},"image":{"@id":"https:\/\/www.vskills.in\/certification\/tutorial\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/vskills.in\/","https:\/\/x.com\/vskills_in","https:\/\/www.linkedin.com\/company-beta\/1371554\/","https:\/\/www.youtube.com\/channel\/UCMWnscxPwRF_PqXo9B7q_Tw"]}]}},"_links":{"self":[{"href":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-json\/wp\/v2\/pages\/75949","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-json\/wp\/v2\/comments?post=75949"}],"version-history":[{"count":4,"href":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-json\/wp\/v2\/pages\/75949\/revisions"}],"predecessor-version":[{"id":83453,"href":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-json\/wp\/v2\/pages\/75949\/revisions\/83453"}],"wp:attachment":[{"href":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-json\/wp\/v2\/media?parent=75949"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-json\/wp\/v2\/categories?post=75949"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.vskills.in\/certification\/tutorial\/wp-json\/wp\/v2\/tags?post=75949"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}