Skip to content

Commit

Permalink
Merge pull request #70 from Zeit-Labs/shadinaif/FC-0012-OEP-58.05
Browse files Browse the repository at this point in the history
feat: Add gettext for JS translation

Refs: FC-0012 OEP-58
  • Loading branch information
brian-smith-tcril authored Oct 18, 2023
2 parents ed52df4 + dc013ff commit d32e7e4
Show file tree
Hide file tree
Showing 17 changed files with 346 additions and 104 deletions.
19 changes: 6 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
WORKING_DIR := recommender
EXTRACT_DIR := $(WORKING_DIR)/conf/locale/en/LC_MESSAGES
EXTRACTED_DJANGO_PARTIAL := $(EXTRACT_DIR)/django-partial.po
EXTRACTED_DJANGOJS_PARTIAL := $(EXTRACT_DIR)/djangojs-partial.po
EXTRACTED_DJANGO := $(EXTRACT_DIR)/django.po
JS_TARGET := $(WORKING_DIR)/public/js/translations

COMMON_CONSTRAINTS_TXT=requirements/common_constraints.txt
.PHONY: $(COMMON_CONSTRAINTS_TXT)
Expand All @@ -22,12 +19,8 @@ upgrade: $(COMMON_CONSTRAINTS_TXT) ## update the requirements/*.txt files with
pip-compile --upgrade -o requirements/ci.txt requirements/ci.in

extract_translations: ## extract strings to be translated, outputting .po files
cd $(WORKING_DIR) && i18n_tool extract
mv $(EXTRACTED_DJANGO_PARTIAL) $(EXTRACTED_DJANGO)
# Safely concatenate djangojs if it exists
if test -f $(EXTRACTED_DJANGOJS_PARTIAL); then \
msgcat $(EXTRACTED_DJANGO) $(EXTRACTED_DJANGOJS_PARTIAL) -o $(EXTRACTED_DJANGO) && \
rm $(EXTRACTED_DJANGOJS_PARTIAL); \
fi
sed -i'' -e 's/nplurals=INTEGER/nplurals=2/' $(EXTRACTED_DJANGO)
sed -i'' -e 's/plural=EXPRESSION/plural=\(n != 1\)/' $(EXTRACTED_DJANGO)
cd $(WORKING_DIR) && i18n_tool extract --no-segment --merge-po-files

compile_translations: ## compile translation files, outputting .mo files for each supported language
cd $(WORKING_DIR) && i18n_tool generate -v
python manage.py compilejsi18n --namespace RecommenderXBlockI18N --output $(JS_TARGET)
12 changes: 12 additions & 0 deletions manage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env python
import os
import sys
from django.core.management import execute_from_command_line

if __name__ == "__main__":
os.environ.setdefault(
"DJANGO_SETTINGS_MODULE",
"translation_settings"
)

execute_from_command_line(sys.argv)
4 changes: 3 additions & 1 deletion recommender/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
This XBlock will show a set of recommended resources which may be helpful to
students solving a given problem.
"""
from .recommender import RecommenderXBlock
# We avoid importing RecommenderXBlock here, because it's importing Filesystem from xblock.reference.plugins
# which is not loaded when running `manage.py` commands (which is used by `make compile_translations`)
# from .recommender import RecommenderXBlock

__version__ = '2.1.0'
3 changes: 3 additions & 0 deletions recommender/conf/locale/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@

locales:
- en # English - Source Language

ignore_dirs:
- public
54 changes: 0 additions & 54 deletions recommender/conf/locale/en/LC_MESSAGES/django.po

This file was deleted.

1 change: 0 additions & 1 deletion recommender/conf/locale/en/LC_MESSAGES/text.po

This file was deleted.

54 changes: 54 additions & 0 deletions recommender/conf/locale/en/LC_MESSAGES/text.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2016-05-27 11:04+0500\n"
"PO-Revision-Date: 2016-05-27 11:04+0500\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#: recommender.py
msgid "The resource you are attempting to provide already exists"
msgstr ""

#: recommender.py
msgid ""
"The resource you are attempting to provide has been disallowed by the staff. "
"Reason: "
msgstr ""

#: recommender.py
msgid "The selected resource does not exist"
msgstr ""

#: recommender.py
msgid "Size of uploaded file exceeds threshold"
msgstr ""

#: recommender.py
msgid "The configuration of pyfs is not properly set"
msgstr ""

#: recommender.py:729
msgid "Endorse resource without permission"
msgstr ""

#: recommender.py
msgid "You don't have the permission to remove this resource"
msgstr ""

#: recommender.py
msgid "Only staff can import resources"
msgstr ""

#: recommender.py
msgid "Please submit the JSON file obtained with the download resources button"
msgstr ""

#: recommender.py
msgid "Tried to access flagged resources without staff permission"
msgstr ""
22 changes: 22 additions & 0 deletions recommender/recommender.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import bleach
from webob.response import Response
from django.utils import translation

from xblock.core import XBlock
from xblock.exceptions import JsonHandlerError
Expand Down Expand Up @@ -944,6 +945,21 @@ def _construct_view_resource(self, resource):

return result

@staticmethod
def _get_statici18n_js_url(): # pragma: no cover
"""
Returns the Javascript translation file for the currently selected language, if any found by `pkg_resources`
"""
lang_code = translation.get_language()
if not lang_code:
return None
text_js = 'public/js/translations/{lang_code}/text.js'
country_code = lang_code.split('-')[0]
for code in (translation.to_locale(lang_code), lang_code, country_code):
if pkg_resources.resource_exists(resource_loader.module_name, text_js.format(lang_code=code)):
return text_js.format(lang_code=code)
return None

def student_view(self, _context=None): # pylint: disable=unused-argument
"""
The primary view of the RecommenderXBlock, shown to students
Expand Down Expand Up @@ -990,6 +1006,9 @@ def student_view(self, _context=None): # pylint: disable=unused-argument
frag.add_css(self.resource_string("static/css/recommender.css"))
frag.add_css(self.resource_string("static/css/introjs.css"))
frag.add_javascript(self.resource_string("static/js/src/jquery.tooltipster.min.js"))
statici18n_js_url = self._get_statici18n_js_url()
if statici18n_js_url:
frag.add_javascript(self.resource_string(statici18n_js_url))
frag.add_javascript(self.resource_string("static/js/src/cats.js"))
frag.add_javascript(self.resource_string("static/js/src/recommender.js"))
frag.initialize_js('RecommenderXBlock', self.get_client_configuration())
Expand All @@ -1007,6 +1026,9 @@ def studio_view(self, _context=None): # pylint: disable=unused-argument
))
frag.add_css(load("static/css/recommenderstudio.css"))
frag.add_javascript_url("//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js")
statici18n_js_url = self._get_statici18n_js_url()
if statici18n_js_url:
frag.add_javascript(self.resource_string(statici18n_js_url))
frag.add_javascript(load("static/js/src/recommenderstudio.js"))
frag.initialize_js('RecommenderXBlock')
return frag
Expand Down
24 changes: 20 additions & 4 deletions recommender/static/js/src/cats.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,26 @@
//
// Note: The global `window.*` variables should be converted into local ones to avoid over-using global variables. This is a 2014-era legacy XBlock coding standard that should be refactored -- @OmarIthawi at Apr 4, 2023
//
var gettext = window.gettext || (function (string) {
// Shim Django's `gettext` if unavailable.
return string;
});
var gettext;
if ('RecommenderXBlockI18N' in window) {
// Use Recommender's local translations
gettext = function(string) {
var translated = window.RecommenderXBlockI18N.gettext(string);
// if Recommender's translation is the same as the input, check if global has a different value
// This is useful for overriding the XBlock's string by themes (only for English)
if (string === translated && 'gettext' in window) {
translated = window.gettext(string);
}
return translated;
};
} else if ('gettext' in window) {
// Use edxapp's global translations
gettext = window.gettext;
}
if (typeof gettext == "undefined") {
// No translations -- used by test environment
gettext = function(string) { return string; };
}

var span = function(text) {
// Surround text with a span.
Expand Down
1 change: 1 addition & 0 deletions requirements/base.in
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ mako
simplejson
webob
web_fragments
edx-i18n-tools
28 changes: 25 additions & 3 deletions requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,43 @@
#
appdirs==1.4.4
# via fs
bleach==6.0.0
asgiref==3.7.2
# via django
bleach==6.1.0
# via -r requirements/base.in
django==3.2.22
# via
# -c requirements/common_constraints.txt
# edx-i18n-tools
edx-i18n-tools==1.3.0
# via -r requirements/base.in
fs==2.4.16
# via -r requirements/base.in
lxml==4.9.3
# via edx-i18n-tools
mako==1.2.4
# via -r requirements/base.in
markupsafe==2.1.3
# via mako
simplejson==3.19.1
path==16.7.1
# via edx-i18n-tools
polib==1.2.0
# via edx-i18n-tools
pytz==2023.3.post1
# via django
pyyaml==6.0.1
# via edx-i18n-tools
simplejson==3.19.2
# via -r requirements/base.in
six==1.16.0
# via
# bleach
# fs
web-fragments==2.0.0
sqlparse==0.4.4
# via django
typing-extensions==4.8.0
# via asgiref
web-fragments==2.1.0
# via -r requirements/base.in
webencodings==0.5.1
# via bleach
Expand Down
47 changes: 43 additions & 4 deletions requirements/ci.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,65 @@ appdirs==1.4.4
# via
# -r requirements/test.txt
# fs
bleach==6.0.0
asgiref==3.7.2
# via
# -r requirements/test.txt
# django
bleach==6.1.0
# via -r requirements/test.txt
django==3.2.22
# via
# -c requirements/common_constraints.txt
# -r requirements/test.txt
# edx-i18n-tools
edx-i18n-tools==1.3.0
# via -r requirements/test.txt
fs==2.4.16
# via -r requirements/test.txt
lxml==4.9.3
# via
# -r requirements/test.txt
# edx-i18n-tools
mako==1.2.4
# via -r requirements/test.txt
markupsafe==2.1.3
# via
# -r requirements/test.txt
# mako
pycodestyle==2.10.0
path==16.7.1
# via
# -r requirements/test.txt
# edx-i18n-tools
polib==1.2.0
# via
# -r requirements/test.txt
# edx-i18n-tools
pycodestyle==2.11.0
# via -r requirements/test.txt
simplejson==3.19.1
pytz==2023.3.post1
# via
# -r requirements/test.txt
# django
pyyaml==6.0.1
# via
# -r requirements/test.txt
# edx-i18n-tools
simplejson==3.19.2
# via -r requirements/test.txt
six==1.16.0
# via
# -r requirements/test.txt
# bleach
# fs
web-fragments==2.0.0
sqlparse==0.4.4
# via
# -r requirements/test.txt
# django
typing-extensions==4.8.0
# via
# -r requirements/test.txt
# asgiref
web-fragments==2.1.0
# via -r requirements/test.txt
webencodings==0.5.1
# via
Expand Down
5 changes: 0 additions & 5 deletions requirements/common_constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,3 @@ django-simple-history==3.0.0
# tox>4.0.0 isn't yet compatible with many tox plugins, causing CI failures in almost all repos.
# Details can be found in this discussion: https://github.com/tox-dev/tox/discussions/1810
tox<4.0.0

# edx-sphinx-theme is not compatible with latest Sphinx==6.0.0 version
# Pinning Sphinx version unless the compatibility issue gets resolved
# For details, see issue https://github.com/openedx/edx-sphinx-theme/issues/197
sphinx<6.0.0
Loading

0 comments on commit d32e7e4

Please sign in to comment.