From 9a0f19c84128c62893c2f3a9fd125cf6605f14d7 Mon Sep 17 00:00:00 2001 From: Omar Al-Ithawi Date: Sat, 23 Mar 2024 07:52:34 +0300 Subject: [PATCH 1/2] feat: fix missing `gettext` functions if translations aren't pulled in devstack --- cms/templates/base.html | 7 +- common/static/js/src/gettext_fallback.js | 132 +++++++++++++++++++++++ lms/templates/main.html | 7 +- 3 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 common/static/js/src/gettext_fallback.js diff --git a/cms/templates/base.html b/cms/templates/base.html index 6907161fff54..c306814ecddd 100644 --- a/cms/templates/base.html +++ b/cms/templates/base.html @@ -60,7 +60,12 @@ % endif - + % if LANGUAGE_CODE != 'en': + + % elif settings.DEBUG or LANGUAGE_CODE == 'en': + ## Provides a fallback for gettext functions for English and in debug mode + + % endif <%block name="header_meta"> diff --git a/common/static/js/src/gettext_fallback.js b/common/static/js/src/gettext_fallback.js new file mode 100644 index 000000000000..63a72d7536c3 --- /dev/null +++ b/common/static/js/src/gettext_fallback.js @@ -0,0 +1,132 @@ +'use strict'; + +/** + * This is a fallback file for the Django JavaScript internationalization library if the language gettext catalog + * is not available. + */ + +(function(globals) { + const django = globals.django || (globals.django = {}); + + /* gettext library */ + if (!django.jsi18n_initialized) { + django.catalog = django.catalog || {}; + + django.pluralidx = function(n) { + const v = (n != 1); + if (typeof v === 'boolean') { + return v ? 1 : 0; + } else { + return v; + } + }; + + django.gettext = function(msgid) { + const value = django.catalog[msgid]; + if (typeof value === 'undefined') { + return msgid; + } else { + return (typeof value === 'string') ? value : value[0]; + } + }; + + django.ngettext = function(singular, plural, count) { + const value = django.catalog[singular]; + if (typeof value === 'undefined') { + return (count == 1) ? singular : plural; + } else { + return value.constructor === Array ? value[django.pluralidx(count)] : value; + } + }; + + django.gettext_noop = function(msgid) { + return msgid; + }; + + django.pgettext = function(context, msgid) { + let value = django.gettext(context + '\x04' + msgid); + if (value.includes('\x04')) { + value = msgid; + } + return value; + }; + + django.npgettext = function(context, singular, plural, count) { + let value = django.ngettext(context + '\x04' + singular, context + '\x04' + plural, count); + if (value.includes('\x04')) { + value = django.ngettext(singular, plural, count); + } + return value; + }; + + django.interpolate = function(fmt, obj, named) { + if (named) { + return fmt.replace(/%\(\w+\)s/g, function(match) { + return String(obj[match.slice(2, -2)]) + }); + } else { + return fmt.replace(/%s/g, function(match) { + return String(obj.shift()) + }); + } + }; + + /* formatting library */ + django.formats = { + DATETIME_FORMAT: 'N j, Y, P', + DATETIME_INPUT_FORMATS: [ + '%Y-%m-%d %H:%M:%S', + '%Y-%m-%d %H:%M:%S.%f', + '%Y-%m-%d %H:%M', + '%m/%d/%Y %H:%M:%S', + '%m/%d/%Y %H:%M:%S.%f', + '%m/%d/%Y %H:%M', + '%m/%d/%y %H:%M:%S', + '%m/%d/%y %H:%M:%S.%f', + '%m/%d/%y %H:%M', + '%Y-%m-%d' + ], + DATE_FORMAT: 'N j, Y', + DATE_INPUT_FORMATS: [ + '%Y-%m-%d', + '%m/%d/%Y', + '%m/%d/%y' + ], + DECIMAL_SEPARATOR: '.', + FIRST_DAY_OF_WEEK: 0, + MONTH_DAY_FORMAT: 'F j', + NUMBER_GROUPING: 3, + SHORT_DATETIME_FORMAT: 'm/d/Y P', + SHORT_DATE_FORMAT: 'm/d/Y', + THOUSAND_SEPARATOR: ',', + TIME_FORMAT: 'P', + TIME_INPUT_FORMATS: [ + '%H:%M:%S', + '%H:%M:%S.%f', + '%H:%M' + ], + YEAR_MONTH_FORMAT: 'F Y' + }; + + django.get_format = function(format_type) { + const value = django.formats[format_type]; + if (typeof value === 'undefined') { + return format_type; + } else { + return value; + } + }; + + /* add to global namespace */ + globals.pluralidx = django.pluralidx; + globals.gettext = django.gettext; + globals.ngettext = django.ngettext; + globals.gettext_noop = django.gettext_noop; + globals.pgettext = django.pgettext; + globals.npgettext = django.npgettext; + globals.interpolate = django.interpolate; + globals.get_format = django.get_format; + + django.jsi18n_initialized = true; + } +}(this)); diff --git a/lms/templates/main.html b/lms/templates/main.html index 963e82fb535d..9bf5992173b5 100644 --- a/lms/templates/main.html +++ b/lms/templates/main.html @@ -79,7 +79,12 @@ } % endif - + % if LANGUAGE_CODE != 'en': + + % elif settings.DEBUG or LANGUAGE_CODE == 'en': + ## Provides a fallback for gettext functions for English and in debug mode + + % endif <% favicon_url = branding_api.get_favicon_url() %> From 746702e45e698124b690406f349e39d99b9640f3 Mon Sep 17 00:00:00 2001 From: Omar Al-Ithawi Date: Tue, 26 Mar 2024 22:54:51 +0300 Subject: [PATCH 2/2] fix: fixup previous commit --- cms/templates/base.html | 7 +++---- lms/templates/main.html | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/cms/templates/base.html b/cms/templates/base.html index c306814ecddd..68df2d1a0e13 100644 --- a/cms/templates/base.html +++ b/cms/templates/base.html @@ -60,10 +60,9 @@ % endif - % if LANGUAGE_CODE != 'en': - - % elif settings.DEBUG or LANGUAGE_CODE == 'en': - ## Provides a fallback for gettext functions for English and in debug mode + + % if settings.DEBUG: + ## Provides a fallback for gettext functions in development environment % endif diff --git a/lms/templates/main.html b/lms/templates/main.html index 9bf5992173b5..1a11900dae58 100644 --- a/lms/templates/main.html +++ b/lms/templates/main.html @@ -79,10 +79,9 @@ } % endif - % if LANGUAGE_CODE != 'en': - - % elif settings.DEBUG or LANGUAGE_CODE == 'en': - ## Provides a fallback for gettext functions for English and in debug mode + + % if settings.DEBUG: + ## Provides a fallback for gettext functions in development environment % endif