Skip to content

Commit b0bed74

Browse files
authored
Merge pull request #1582 from AtlasOfLivingAustralia/feature/i18n
added async internationalisation ko binding
2 parents 196b4f4 + efd1723 commit b0bed74

File tree

5 files changed

+109
-2
lines changed

5 files changed

+109
-2
lines changed

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
biocollectVersion=6.7-SNAPSHOT
1+
biocollectVersion=6.8-i18n-SNAPSHOT
22
grailsVersion=5.1.9
33
grailsGradlePluginVersion=5.1.5
44
assetPipelineVersion=3.3.4

grails-app/assets/javascripts/i18n.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright (C) 2019 Atlas of Living Australia
3+
* All Rights Reserved.
4+
*
5+
* The contents of this file are subject to the Mozilla Public
6+
* License Version 1.1 (the "License"); you may not use this file
7+
* except in compliance with the License. You may obtain a copy of
8+
* the License at http://www.mozilla.org/MPL/
9+
*
10+
* Software distributed under the License is distributed on an "AS
11+
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
12+
* implied. See the License for the specific language governing
13+
* rights and limitations under the License.
14+
*
15+
* Created by Temi on 15/11/19.
16+
*/
17+
18+
(function() {
19+
var messages = {},
20+
deffer = $.Deferred();
21+
$.get({
22+
url: fcConfig.i18nURL,
23+
cache: true
24+
}).done(function (data) {
25+
messages = data;
26+
deffer.resolve();
27+
}).fail(function () {
28+
deffer.reject();
29+
});
30+
31+
$i18n = function(key, defaultValue) {
32+
if (messages[key] !== undefined) {
33+
return messages[key];
34+
} else {
35+
return defaultValue || key;
36+
}
37+
};
38+
39+
$i18nAsync = function(key, defaultValue, callback) {
40+
if (callback) {
41+
deffer.done(function () {
42+
callback($i18n(key, defaultValue));
43+
}).fail(function () {
44+
callback($i18n(key, defaultValue));
45+
})
46+
}
47+
}
48+
49+
})();

grails-app/assets/javascripts/knockout-custom-bindings.js

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1148,4 +1148,49 @@ ko.bindingHandlers.debug = {
11481148
console.log(element);
11491149
console.log(ko.toJS(valueAccessor()));
11501150
}
1151-
};
1151+
};
1152+
1153+
1154+
/**
1155+
* This binding requires i18n.js to be loaded. It also requires fcConfig.i18nURL to be set.
1156+
* Params can be a string or an object. If string, it is treated as key and translated to text. Object parameter has the
1157+
* following properties:
1158+
* @contentType can be 'text' or 'html' (default is 'text')
1159+
* @key is the key to be translated
1160+
* @defaultValue is the default value to be used if the key is not found
1161+
*
1162+
* Usage examples:
1163+
* <div data-bind="i18n: 'g.cancel'"></div>
1164+
* <div data-bind="i18n: {key: 'record.edit.verificationStatusTypes.help', contentType: 'html', defaultValue: '<b>simple help</b>'}"></div>
1165+
*
1166+
*/
1167+
ko.bindingHandlers.i18n = {
1168+
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
1169+
var value = valueAccessor();
1170+
value = ko.unwrap(value);
1171+
var contentType = value && value.contentType || 'text'
1172+
1173+
// $i18nAsync is required to be defined
1174+
if(typeof $i18nAsync === 'undefined')
1175+
return
1176+
1177+
if( typeof value === 'string') {
1178+
$i18nAsync(value, '',function(text) {
1179+
$(element).text(text);
1180+
});
1181+
}
1182+
else if (typeof value === 'object') {
1183+
$i18nAsync(value.key, value.defaultValue,function(text) {
1184+
switch (contentType) {
1185+
default:
1186+
case 'text':
1187+
$(element).text(text);
1188+
break;
1189+
case 'html':
1190+
$(element).html(text);
1191+
break;
1192+
}
1193+
});
1194+
}
1195+
}
1196+
}

grails-app/controllers/au/org/ala/biocollect/merit/HomeController.groovy

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class HomeController {
1414
def settingService
1515
def metadataService
1616
def userService
17+
CommonService commonService
1718

1819
@PreAuthorise(accessLevel = 'alaAdmin', redirectController = "admin")
1920
@SSO
@@ -61,6 +62,13 @@ class HomeController {
6162
def works() {
6263
}
6364

65+
def i18n() {
66+
if (request.isGet()) {
67+
Map props = commonService.i18n(request.locale)
68+
render props as JSON
69+
}
70+
}
71+
6472
/**
6573
* The purpose of this method is to enable the display of the spatial object corresponding to a selected
6674
* value from a geographic facet (e.g. to display the polygon representing NSW on the map if the user has

grails-app/services/au/org/ala/biocollect/merit/CommonService.groovy

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package au.org.ala.biocollect.merit
33
import grails.converters.JSON
44
import grails.web.mapping.LinkGenerator
55
import grails.web.servlet.mvc.GrailsParameterMap
6+
import org.springframework.context.MessageSource
67

78
import javax.servlet.http.HttpServletRequest
89
import javax.xml.bind.DatatypeConverter
@@ -13,6 +14,7 @@ class CommonService {
1314
UserService userService
1415

1516
LinkGenerator grailsLinkGenerator
17+
MessageSource messageSource
1618

1719
List ignores = ["action","controller"]
1820

@@ -92,4 +94,7 @@ class CommonService {
9294
queryParams
9395
}
9496

97+
def i18n(Locale locale) {
98+
messageSource.getMergedProperties(locale)?.properties
99+
}
95100
}

0 commit comments

Comments
 (0)