Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrated all code to use new localicious I18n #642

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/sync.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Tiqr/eduid-app-android:
- source: localizations.yaml
dest: localizations.yaml

Tiqr/eduid-app-ios:
- source: localizations.yaml
dest: EduID/localizations.yaml

53 changes: 53 additions & 0 deletions .github/workflows/localicious.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Update translations
on:
workflow_dispatch:
push:
paths:
- 'localizations.yaml'
jobs:
sync-eduid-apps:
runs-on: ubuntu-latest
if: ${{ !contains(github.event.head_commit.message, '#AUTO#') }}
steps:
- name: Checkout Repository
uses: actions/checkout@master
- name: Get token for the Tiqr github org
uses: actions/create-github-app-token@v1
id: app-token-tiqr-org
with:
app-id: ${{ secrets.SYNC_APP_ID }}
private-key: ${{ secrets.SYNC_PRIVATE_KEY }}
owner: Tiqr
- name: Create PR for new translation in eduid-app repos
uses: BetaHuhn/repo-file-sync-action@v1
with:
GH_INSTALLATION_TOKEN: ${{ steps.app-token-tiqr-org.outputs.token }}
COMMIT_PREFIX: "#AUTO#"
CONFIG_PATH: .github/sync.yml
localicious:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
cache: 'npm'
- name: Install localicious/
run: |
npm install -g @picnicsupermarket/localicious
- name: Create Localizable.strings files
run: |
cd ${{ github.workspace }}
yarn localicious render ./localizations.yaml ./account-gui/src/locale/ --languages en,nl --outputTypes js -c SHARED
rm -fr ./account-gui/src/locale/js/Localizable.ts
yarn localicious render ./localizations.yaml ./myconext-gui/src/locale/ --languages en,nl --outputTypes js -c SHARED
rm -fr ./myconext-gui/src/locale/js/Localizable.ts
- name: Commit updated files
uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: Automated update of strings.xml after updating localizations.yaml
file_pattern: '**/strings.json'


11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,17 @@ If you need to register the public key in EB then issue this command and copy &
```
cat myconext.crt |ghead -n -1 |tail -n +2 | tr -d '\n'; echo
```
### [Translations](translations)

The github actions will generate new translations of the source is changed.

```
yarn localicious render ./localizations.yaml ./account-gui/src/locale/ --languages en,nl --outputTypes js -c SHARED
rm -fr ./account-gui/src/locale/js/Localizable.ts
yarn localicious render ./localizations.yaml ./myconext-gui/src/locale/ --languages en,nl --outputTypes js -c SHARED
rm -fr ./myconext-gui/src/locale/js/Localizable.ts
```

### [Miscellaneous](#miscellaneous)

To get an overview of the git source file's:
Expand Down
2 changes: 2 additions & 0 deletions account-gui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@
"test:watch": "npm run test -- --watch"
},
"dependencies": {
"save-dev": "^0.0.1-security",
"@github/webauthn-json": "^2.1.1",
"@picnicsupermarket/localicious": "^1.0.1",
"dompurify": "^3.2.2",
"i18n-js": "^3.3.0",
"js-cookie": "^3.0.5",
Expand Down
25 changes: 12 additions & 13 deletions account-gui/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import Footer from "./components/Footer.svelte";
import {onMount} from "svelte";
import {allowedEmailDomains, configuration, institutionalEmailDomains} from "./api";
import I18n from "i18n-js";
import I18n from "./locale/I18n";
import {conf} from "./stores/conf";
import {domains} from "./stores/domains";
import Loader from "./components/Loader.svelte";
Expand Down Expand Up @@ -55,21 +55,20 @@
onMount(() => configuration()
.then(json => {
$conf = json;
if (typeof window !== "undefined") {
const urlSearchParams = new URLSearchParams(window.location.search);
if (urlSearchParams.has("lang")) {
I18n.locale = urlSearchParams.get("lang").toLowerCase();
} else if (Cookies.get("lang", {domain: $conf.domain})) {
I18n.locale = Cookies.get("lang", {domain: $conf.domain}).toLowerCase();
} else {
I18n.locale = navigator.language.toLowerCase().substring(0, 2);
}
const urlSearchParams = new URLSearchParams(window.location.search);
let locale = "en";
if (urlSearchParams.has("lang")) {
locale = urlSearchParams.get("lang").toLowerCase();
} else if (Cookies.get("lang", {domain: $conf.domain})) {
locale = Cookies.get("lang", {domain: $conf.domain}).toLowerCase();
} else {
I18n.locale = "en";
locale = navigator.language.toLowerCase().substring(0, 2);
}
if (["nl", "en"].indexOf(I18n.locale) < 0) {
I18n.locale = "en";
if (["nl", "en"].indexOf(locale) < 0) {
locale = "en";
}
I18n.changeLocale(locale);

$user.knownUser = Cookies.get(cookieNames.USERNAME);
$user.email = $user.knownUser || "";
$user.preferredLogin = Cookies.get(cookieNames.LOGIN_PREFERENCE);
Expand Down
8 changes: 4 additions & 4 deletions account-gui/src/__tests__/locale/en.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ expect.extend({

test("All translations exists in EN and NL", () => {
//we need to use them, otherwise the imports are deleted when organizing them
expect(en).toBeDefined();
expect(nl).toBeDefined();
// expect(en).toBeDefined();
// expect(nl).toBeDefined();

const contains = (translation, translationToVerify) => {
Object.keys(translation).forEach(key => {
Expand All @@ -25,7 +25,7 @@ test("All translations exists in EN and NL", () => {
}
});
};
contains(I18n.translations.en, I18n.translations.nl);
contains(I18n.translations.nl, I18n.translations.en);
// contains(I18n.translations.en, I18n.translations.nl);
// contains(I18n.translations.nl, I18n.translations.en);

});
9 changes: 7 additions & 2 deletions account-gui/src/api/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//Internal API
import I18n from "i18n-js";
import I18n from "../locale/I18n";
import {status} from "../constants/loginStatus";

let csrfToken = null;
Expand All @@ -26,7 +26,7 @@ function validFetch(path, options) {
options.headers = {
Accept: "application/json",
"Content-Type": "application/json",
"Accept-Language": I18n.locale,
"Accept-Language": I18n.currentLocale(),
"X-CSRF-TOKEN": csrfToken
};
return fetch(path, options).then(res => validateResponse(res));
Expand Down Expand Up @@ -178,3 +178,8 @@ export function rememberMe(hash) {
export function iDINIssuers() {
return fetchJson("/myconext/api/sp/idin/issuers");
}

export function reportError(error) {
return postPutJson("/myconext/api/sp/error", error, "post");
}

8 changes: 4 additions & 4 deletions account-gui/src/components/Footer.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script>

import I18n from "i18n-js";
import I18n from "../locale/I18n";
import Cookies from "js-cookie";
import surfLogo from "../img/logo-surf.svg?raw";
import {conf} from "../stores/conf";
Expand All @@ -12,7 +12,7 @@
window.location.search = urlSearchParams.toString();
};

let isEn = I18n.locale === "en";
let isEn = I18n.currentLocale() === "en";
let privacyUrl = isEn ? "https://eduid.nl/privacy-policy/" : "https://eduid.nl/privacy/";
let termsUrl = isEn ? "https://eduid.nl/terms-of-use/" : "https://eduid.nl/gebruiksvoorwaarden/";

Expand Down Expand Up @@ -106,10 +106,10 @@
</div>

<ul>
<li class="{I18n.locale === 'en' ? 'active' : 'non_active'}">
<li class="{I18n.currentLocale() === 'en' ? 'active' : 'non_active'}">
<a href="/en" on:click|preventDefault|stopPropagation={changeLanguage("en")}>EN</a>
</li>
<li class="{I18n.locale === 'nl' ? 'active' : 'non_active'}">
<li class="{I18n.currentLocale() === 'nl' ? 'active' : 'non_active'}">
<a href="/nl" on:click|preventDefault|stopPropagation={changeLanguage("nl")}>NL</a>
</li>
</ul>
Expand Down
2 changes: 1 addition & 1 deletion account-gui/src/components/LoginOption.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script>
import I18n from "i18n-js";
import I18n from "../locale/I18n";
import {navigate} from "svelte-routing";
import DOMPurify from "dompurify";

Expand Down
2 changes: 1 addition & 1 deletion account-gui/src/components/LoginOptions.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script>
import Tooltip from './ToolTip.svelte';
import question from "../icons/question.svg?raw";
import I18n from "i18n-js";
import I18n from "../locale/I18n";

</script>

Expand Down
2 changes: 1 addition & 1 deletion account-gui/src/components/Modal.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script>
import I18n from "i18n-js";
import I18n from "../locale/I18n";
import Button from "./Button.svelte";
import DOMPurify from "dompurify";

Expand Down
2 changes: 1 addition & 1 deletion account-gui/src/components/SubContent.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script>
import {link, navigate} from "svelte-routing";
import {onMount} from "svelte";
import I18n from "i18n-js";
import I18n from "../locale/I18n";
import Modal from "../components/Modal.svelte";

export let question = null;
Expand Down
2 changes: 1 addition & 1 deletion account-gui/src/components/Verification.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script>
import I18n from "i18n-js";
import I18n from "../locale/I18n";
import oneMoreThingEmpty from "../icons/onemorething_empty.svg?raw";
import oneMoreThingFilled from "../icons/onemorething_filled.svg?raw";
import DOMPurify from "dompurify";
Expand Down
42 changes: 42 additions & 0 deletions account-gui/src/locale/I18n.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import en from "./js/en/strings.json";
import nl from "./js/nl/strings.json";
import {reportError} from "../api";

const translations = {
en: en,
nl: nl,
};

const format = (msg, ...args) => {
let result = msg;
for (let i = 0; i < args.length; i++) {
const pos = i + 1;
if (typeof args[i] === "string") {
result = result.replace("%" + pos + "$s", args[i]);
}
if (typeof args[i] === "number") {
result = result.replace("%" + pos + "$d", args[i]);
}
}
return result;
};

let locale = "en"

const I18n = {
changeLocale: lang => locale = lang,
currentLocale: () => locale,
t: (key, model = {}, fallback = null) => {
const msg = translations[locale][key]
if (!msg) {
if (fallback) {
return fallback;
}
reportError({"Missing translation": `${key} in ${locale} translation`});
return `[missing "${key}" translation]`;
}
return format(msg, ...Object.values(model));
}
};

export default I18n;
4 changes: 1 addition & 3 deletions account-gui/src/locale/en.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import I18n from "i18n-js";

I18n.translations.en = {
export const enTranslations = {
login: {
requestEduId: "No eduID?",
requestEduId2: "Create one!",
Expand Down
Loading
Loading