Skip to content

Commit

Permalink
Merge pull request #493 from dzhuang/fix_js_l10n
Browse files Browse the repository at this point in the history
Optimized i18n js of DataTable and FullCalendar. Close #491
  • Loading branch information
dzhuang authored Mar 13, 2018
2 parents 8064481 + 49dd451 commit 7048045
Show file tree
Hide file tree
Showing 12 changed files with 93 additions and 44 deletions.
4 changes: 3 additions & 1 deletion course/templates/course/calendar.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
<script src='{% static "fullcalendar/dist/fullcalendar.js" %}'></script>
{# load calendar with local language #}
{% get_current_language as LANGUAGE_CODE %}
<script src='{% static "fullcalendar/dist/lang/" %}{{ LANGUAGE_CODE }}.js'></script>
{% if LANGUAGE_CODE != "en" %}
<script src='{% static "fullcalendar/dist/lang/" %}{{ LANGUAGE_CODE |js_lang_fallback:"fullcalendar" }}.js'></script>
{% endif %}
{% endblock %}

{% block content %}
Expand Down
2 changes: 1 addition & 1 deletion course/templates/course/gradebook-by-opp.html
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ <h3 class="start-well-title">{% trans "Modify many sessions at once" %}</h3>
"paging": false,
"ordering": true,
"columnDefs": [{ type: 'name', targets: 1 }],
"language": {url: '{% static "datatables.net-plugins/i18n/" %}{{LANG}}.lang'},
"language": {url: '{% static "datatables-i18n/i18n/" %}{{LANG}}.json'},
} );
new $.fn.dataTable.FixedColumns(tbl);
</script>
Expand Down
2 changes: 1 addition & 1 deletion course/templates/course/gradebook-opp-list.html
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ <h1>{% trans "List of Grading Opportunities" %}</h1>
"scrollCollapse": true,
"paging": false,
"ordering": true,
"language": {url: '{% static "datatables.net-plugins/i18n/" %}{{LANG}}.lang'},
"language": {url: '{% static "datatables-i18n/i18n/" %}{{LANG}}.json'},
} );
</script>

Expand Down
2 changes: 1 addition & 1 deletion course/templates/course/gradebook-participant.html
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ <h1>{% trans "Grades" %}</h1>
"scrollCollapse": true,
"paging": false,
"columnDefs": [{ type: 'name', targets: 1 }],
"language": {url: '{% static "datatables.net-plugins/i18n/" %}{{LANG}}.lang'},
"language": {url: '{% static "datatables-i18n/i18n/" %}{{LANG}}.json'},
} );
</script>

Expand Down
2 changes: 1 addition & 1 deletion course/templates/course/gradebook.html
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ <h1>{% trans "Grade book" %}</h1>
"paging": true,
"ordering": true,
"columnDefs": [{ type: 'name', targets: 1 }],
"language": {url: '{% static "datatables.net-plugins/i18n/" %}{{LANG}}.lang'},
"language": {url: '{% static "datatables-i18n/i18n/" %}{{LANG}}.json'},
} );
new $.fn.dataTable.FixedColumns(tbl);
</script>
Expand Down
2 changes: 1 addition & 1 deletion course/templates/course/participation-table.html
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,6 @@
"paging": false,
"ordering": true,
"columnDefs": [{ type: 'name', targets: 1 }],
"language": {url: '{% static "datatables.net-plugins/i18n/" %}{{LANG}}.lang'},
"language": {url: '{% static "datatables-i18n/i18n/" %}{{LANG}}.json'},
} );
</script>
34 changes: 27 additions & 7 deletions course/templatetags/coursetags.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,20 @@

from django.template import Library, Node, TemplateSyntaxError
from django.utils import translation
from relate.utils import to_datatables_lang_name

register = Library()

# {{{ get language_code in JS traditional naming format

# {{{ get language_code in JS traditional naming format

class GetCurrentLanguageJsFmtNode(Node):
def __init__(self, variable):
self.variable = variable

def render(self, context):
datatables_lang_name = to_datatables_lang_name(translation.get_language())
context[self.variable] = datatables_lang_name
lang_name = (
translation.to_locale(translation.get_language()).replace("_", "-"))
context[self.variable] = lang_name
return ''


Expand All @@ -46,9 +46,10 @@ def do_get_current_js_lang_name(parser, token):
"""
This will store the current language in the context, in js lang format.
This is different with built-in do_get_current_language, which returns
languange name like "en-us", "zh-cn", with the country code using lower
case. This method return lang name "en-US", "zh-CN", as most js packages
with i18n are providing translations using that naming format.
languange name like "en-us", "zh-hans". This method return lang name
"en-US", "zh-Hans", with the country code capitallized if country code
has 2 characters, and capitalize first if country code has more than 2
characters.
Usage::
Expand All @@ -65,6 +66,25 @@ def do_get_current_js_lang_name(parser, token):
"'as variable' (got %r)" % args)
return GetCurrentLanguageJsFmtNode(args[2])


@register.filter(name='js_lang_fallback')
def js_lang_fallback(lang_name, js_name=None):
"""
Return the fallback lang name for js files.
:param a :class:`str:`
:param js_name: a :class:`str:`, optional.
:return: a :class:`str:`
"""

# The mapping is crap, we use a special case table to fix it.
if js_name == "fullcalendar":
known_fallback_mapping = {
"zh-hans": "zh-cn",
"zh-hant": "zh-tw"}
return known_fallback_mapping.get(lang_name.lower(), lang_name).lower()

return lang_name

# }}}


Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"datatables.net-bs": "^1.10.16",
"datatables.net-fixedcolumns": "^3.2.4",
"datatables.net-fixedcolumns-bs": "^3.2.4",
"datatables.net-plugins": "^1.10.15",
"datatables-i18n": "git+https://github.com/dzhuang/datatables-i18n.git",
"font-awesome": "^4.7.0",
"fullcalendar": "^2.9.1",
"jquery": "^3.3.1",
Expand Down
24 changes: 0 additions & 24 deletions relate/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import django.forms as forms
from django.utils.translation import ugettext_lazy as _
import dulwich.repo
import pycountry

from typing import Union

Expand Down Expand Up @@ -369,29 +368,6 @@ def dumpstacks(signal, frame):
# }}}


# {{{ convert django language name to js styled language name

def to_datatables_lang_name(dj_lang_name):
"""
Turns a Django language name (en-us) into the correspnding DataTables.net
i18n lang name.
"""
# The mapping is crap, we use a special case table to fix it.
mapping = {"zh-hans": "Chinese",
"zh-hant": "Chinese-traditional"}

if dj_lang_name in mapping:
return mapping[dj_lang_name]
else:
primary = dj_lang_name.split('-')[0]
try:
return pycountry.languages.get(alpha_2=primary).name
except LookupError:
return "English"

# }}}


#{{{ Allow multiple email connections
# https://gist.github.com/niran/840999

Expand Down
3 changes: 0 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@ unicodecsv
# To support network matching for facility recognition
ipaddress

# For datatables i18n
pycountry

# {{{ For interoperation with SAML2/Shibboleth

pysaml2
Expand Down
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
"nbconvert>=5.2.1",
"pymbolic",
"sympy",
"pycountry",
],
package_data={
"relate": [
Expand Down
59 changes: 57 additions & 2 deletions tests/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,13 +277,25 @@ def test_get_current_js_lang_name_tag(self):
template = self.engines["django"].from_string(
"{% get_current_js_lang_name as LANG %}{{LANG}}")
text = template.render()
self.assertEqual(text, "English")
self.assertEqual(text, "en-US")

with override_settings(LANGUAGE_CODE="de"):
template = self.engines["django"].from_string(
"{% get_current_js_lang_name as LANG %}{{LANG}}")
text = template.render()
self.assertEqual(text, "German")
self.assertEqual(text, "de")

with override_settings(LANGUAGE_CODE="zh-hans"):
template = self.engines["django"].from_string(
"{% get_current_js_lang_name as LANG %}{{LANG}}")
text = template.render()
self.assertEqual(text, "zh-Hans")

with override_settings(LANGUAGE_CODE="zh-hant"):
template = self.engines["django"].from_string(
"{% get_current_js_lang_name as LANG %}{{LANG}}")
text = template.render()
self.assertEqual(text, "zh-Hant")

def test_get_current_js_lang_name_tag_failed(self):
from django.template import TemplateSyntaxError
Expand All @@ -307,6 +319,49 @@ def test_get_current_js_lang_name_tag_failed(self):
self.engines["django"].from_string(
"{% get_current_js_lang_name AS LANG %}{{LANG}}")

def test_js_lang_fallback(self):
with override_settings(LANGUAGE_CODE="en-us"):
template = self.engines["django"].from_string(
"{% get_current_js_lang_name as LANG %}"
"{{LANG|js_lang_fallback}}")
text = template.render()
self.assertEqual(text, "en-US")

with override_settings(LANGUAGE_CODE="en-us"):
template = self.engines["django"].from_string(
"{% get_current_js_lang_name as LANG %}"
"{{LANG|js_lang_fallback:'fullcalendar'}}")
text = template.render()
self.assertEqual(text, "en-us")

with override_settings(LANGUAGE_CODE="zh-cn"):
template = self.engines["django"].from_string(
"{% get_current_js_lang_name as LANG %}"
"{{LANG|js_lang_fallback:'fullcalendar'}}")
text = template.render()
self.assertEqual(text, "zh-cn")

with override_settings(LANGUAGE_CODE="zh-cn"):
template = self.engines["django"].from_string(
"{% get_current_js_lang_name as LANG %}"
"{{LANG|js_lang_fallback}}")
text = template.render()
self.assertEqual(text, "zh-CN")

with override_settings(LANGUAGE_CODE="zh-hans"):
template = self.engines["django"].from_string(
"{% get_current_js_lang_name as LANG %}"
"{{LANG|js_lang_fallback}}")
text = template.render()
self.assertEqual(text, "zh-Hans")

with override_settings(LANGUAGE_CODE="zh-hans"):
template = self.engines["django"].from_string(
"{% get_current_js_lang_name as LANG %}"
"{{LANG|js_lang_fallback:'fullcalendar'}}")
text = template.render()
self.assertEqual(text, "zh-cn")


class HasPermissionTemplateFilterTest(SingleCourseTestMixin, TestCase):
def setUp(self):
Expand Down

0 comments on commit 7048045

Please sign in to comment.