diff --git a/.env b/.env
new file mode 100644
index 0000000000000000000000000000000000000000..a492d13c734644423e5ae3b6c30f3616cc94e1c4
--- /dev/null
+++ b/.env
@@ -0,0 +1,2 @@
+VUE_APP_I18N_LOCALE=nb
+VUE_APP_I18N_FALLBACK_LOCALE=en
diff --git a/README.md b/README.md
index 2e933796d7b5c44266fedd784aabd2be067a0b80..36d8d54b36034c19fb1bddde036fd8664af47ed5 100644
--- a/README.md
+++ b/README.md
@@ -67,3 +67,38 @@ The router components (the "pages" in the Single Page Application that you manag
### Checking out new code
Remember to always run `npm install` after checking out new code from the repository. That way, new dependencies will be installed.
+
+### Translation
+[This tutorial](https://www.codeandweb.com/babeledit/tutorials/how-to-translate-your-vue-app-with-vue-i18n) has been used to enable translation.
+
+I couldn't get the per-component translation thing working (where you embed it in `<i18n>` tags),
+so all translations go into the `/locales/[languagecode].json` files.
+
+
+There's a simple translation example in /components/ObservationList.js:
+
+``` html
+<template>
+ <div class="hello">
+ <h1>{{ $t('startpage') }}</h1>
+ <router-link to="/observation" custom v-slot="{navigate}">
+ <button type="button" class="btn btn-primary" @click="navigate">+</button>
+ </router-link>
+
+ </div>
+</template>
+```
+
+(TODO: Update this documentation when code in ObservationList changes)
+
+Change the startup language in the app here in `/i18n.js`:
+
+``` javascript
+export default new VueI18n({
+ locale: process.env.VUE_APP_I18N_LOCALE || 'nb', // Here you can customize
+ fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
+ messages: loadLocaleMessages()
+})
+```
+
+
diff --git a/package-lock.json b/package-lock.json
index 551dde8d3c03275502197fa56f7324ef095fd566..63819ad40734122dee8461297f13dc1293d86e8f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4,6 +4,43 @@
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+ "@intlify/vue-i18n-loader": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@intlify/vue-i18n-loader/-/vue-i18n-loader-1.0.0.tgz",
+ "integrity": "sha512-y7LlpKEQ01u7Yq14l4VNlbFYEHMmSEH1QXXASOMWspj9ZcIdCebhhvHCHqk5Oy5Epw3PtoxyRJNpb6Wle5udgA==",
+ "dev": true,
+ "requires": {
+ "js-yaml": "^3.13.1",
+ "json5": "^2.1.1"
+ },
+ "dependencies": {
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "json5": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
+ "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.5"
+ }
+ }
+ }
+ },
"@netflix/nerror": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@netflix/nerror/-/nerror-1.1.3.tgz",
@@ -1815,6 +1852,17 @@
"integrity": "sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg==",
"dev": true
},
+ "cli-table3": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz",
+ "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==",
+ "dev": true,
+ "requires": {
+ "colors": "^1.1.2",
+ "object-assign": "^4.1.0",
+ "string-width": "^2.1.1"
+ }
+ },
"cliui": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
@@ -3466,6 +3514,12 @@
"regexp.prototype.flags": "^1.2.0"
}
},
+ "deepmerge": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
+ "dev": true
+ },
"define-properties": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
@@ -3713,6 +3767,24 @@
"domelementtype": "1"
}
},
+ "dot-object": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/dot-object/-/dot-object-1.9.0.tgz",
+ "integrity": "sha512-7MPN6y7XhAO4vM4eguj5+5HNKLjJYfkVG1ZR1Aput4Q4TR6SYeSjhpVQ77IzJHoSHffKbDxBC+48aCiiRurDPw==",
+ "dev": true,
+ "requires": {
+ "commander": "^2.20.0",
+ "glob": "^7.1.4"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ }
+ }
+ },
"dot-prop": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
@@ -3722,6 +3794,12 @@
"is-obj": "^2.0.0"
}
},
+ "dotenv": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
+ "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
+ "dev": true
+ },
"duplexer": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
@@ -3798,6 +3876,12 @@
}
}
},
+ "emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+ "dev": true
+ },
"emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
@@ -4021,6 +4105,12 @@
"estraverse": "^4.1.1"
}
},
+ "esm": {
+ "version": "3.2.25",
+ "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
+ "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
+ "dev": true
+ },
"esprima": {
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
@@ -4482,6 +4572,12 @@
"locate-path": "^2.0.0"
}
},
+ "flat": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+ "dev": true
+ },
"flatten": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz",
@@ -5501,6 +5597,12 @@
"integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
"dev": true
},
+ "is-valid-glob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz",
+ "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=",
+ "dev": true
+ },
"is-windows": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
@@ -11249,6 +11351,48 @@
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.12.tgz",
"integrity": "sha512-uhmLFETqPPNyuLLbsKz6ioJ4q7AZHzD8ZVFNATNyICSZouqP2Sz0rotWQC8UNBF6VGSCs5abnKJoStA6JbCbfg=="
},
+ "vue-cli-plugin-i18n": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/vue-cli-plugin-i18n/-/vue-cli-plugin-i18n-1.0.1.tgz",
+ "integrity": "sha512-sLo6YzudaWgn5dOMvrKixE5bb/onYGxcxm+0YexqoOx0QtR+7hZ/P5WPFBMM9v/2i1ec2YYe2PvKTBel7KE+tA==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.0",
+ "deepmerge": "^4.2.0",
+ "dotenv": "^8.2.0",
+ "flat": "^5.0.0",
+ "rimraf": "^3.0.0",
+ "vue": "^2.6.11",
+ "vue-i18n": "^8.17.0",
+ "vue-i18n-extract": "1.0.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ }
+ }
+ },
"vue-hot-reload-api": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",
@@ -11260,6 +11404,159 @@
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.22.4.tgz",
"integrity": "sha512-XLI5s0AdqMP2Lf4I4CmdmOq8kjb5DDFGR77wAuxCfpEuYSfhTRyyx6MetgZMiL6Lxa0DasjBOiOcciU3NkL3/Q=="
},
+ "vue-i18n-extract": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/vue-i18n-extract/-/vue-i18n-extract-1.0.2.tgz",
+ "integrity": "sha512-+zwDKvle4KcfloXZnj5hF01ViKDiFr5RMx5507D7oyDXpSleRpekF5YHgZa/+Ra6Go68//z0Nya58J9tKFsCjw==",
+ "dev": true,
+ "requires": {
+ "cli-table3": "^0.5.1",
+ "dot-object": "^1.7.1",
+ "esm": "^3.2.13",
+ "glob": "^7.1.3",
+ "is-valid-glob": "^1.0.0",
+ "yargs": "^13.2.2"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true
+ },
+ "cliui": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+ "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+ "dev": true,
+ "requires": {
+ "string-width": "^3.1.0",
+ "strip-ansi": "^5.2.0",
+ "wrap-ansi": "^5.1.0"
+ }
+ },
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ },
+ "require-main-filename": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+ "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.0",
+ "string-width": "^3.0.0",
+ "strip-ansi": "^5.0.0"
+ }
+ },
+ "yargs": {
+ "version": "13.3.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
+ "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^5.0.0",
+ "find-up": "^3.0.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^3.0.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^13.1.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "13.1.2",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
+ "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ }
+ }
+ }
+ },
"vue-loader": {
"version": "13.7.3",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-13.7.3.tgz",
diff --git a/package.json b/package.json
index e123358afbb2114c03b199abc52881accf515b02..690d8018254efdb38e772bf8b0538cd9bb3b7ea5 100644
--- a/package.json
+++ b/package.json
@@ -1,13 +1,14 @@
{
"name": "vipsobservationapp",
"version": "1.0.0",
+ "private": true,
"description": "The Field Pest Observation App for VIPS users",
"author": "Tor-Einar Skog <tor-einar.skog@nibio.no>",
- "private": true,
"scripts": {
+ "build": "node build/build.js",
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
- "start": "npm run dev",
- "build": "node build/build.js"
+ "i18n:report": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/locales/**/*.json'",
+ "start": "npm run dev"
},
"dependencies": {
"vue": "^2.5.2",
@@ -15,6 +16,7 @@
"vue-router": "^3.0.1"
},
"devDependencies": {
+ "@intlify/vue-i18n-loader": "^1.0.0",
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
@@ -48,6 +50,7 @@
"shelljs": "^0.7.6",
"uglifyjs-webpack-plugin": "^1.1.1",
"url-loader": "^0.5.8",
+ "vue-cli-plugin-i18n": "~1.0.1",
"vue-loader": "^13.3.0",
"vue-style-loader": "^3.0.1",
"vue-template-compiler": "^2.5.2",
@@ -56,10 +59,6 @@
"webpack-dev-server": "^2.9.1",
"webpack-merge": "^4.1.0"
},
- "engines": {
- "node": ">= 6.0.0",
- "npm": ">= 3.0.0"
- },
"browserslist": [
"> 1%",
"last 2 versions",
@@ -79,5 +78,9 @@
"ANDROID_SUPPORT_V4_VERSION": "27.+"
}
}
+ },
+ "engines": {
+ "node": ">= 6.0.0",
+ "npm": ">= 3.0.0"
}
}
diff --git a/src/components/ObservationList.vue b/src/components/ObservationList.vue
index a467c7c93e2e7b17dfe9b012bb1b9019945d5676..07bba5055b2b8a8e730bdff04c5746cc22225198 100644
--- a/src/components/ObservationList.vue
+++ b/src/components/ObservationList.vue
@@ -1,6 +1,6 @@
<template>
<div class="hello">
- <h1>{{ msg }}</h1>
+ <h1>{{ $t('startpage') }}</h1>
<router-link to="/observation" custom v-slot="{navigate}">
<button type="button" class="btn btn-primary" @click="navigate">+</button>
</router-link>
@@ -13,7 +13,7 @@ export default {
name: 'ObservationList',
data () {
return {
- msg: 'Startsiden'
+ /*msg: 'Startsiden'*/
}
}
}
@@ -35,4 +35,4 @@ li {
a {
color: #42b983;
}
-</style>
+</style>
\ No newline at end of file
diff --git a/src/i18n.js b/src/i18n.js
new file mode 100644
index 0000000000000000000000000000000000000000..313e372dbf8cff6703c81fdac01010eedfa0d104
--- /dev/null
+++ b/src/i18n.js
@@ -0,0 +1,23 @@
+import Vue from 'vue'
+import VueI18n from 'vue-i18n'
+
+Vue.use(VueI18n)
+
+function loadLocaleMessages () {
+ const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i)
+ const messages = {}
+ locales.keys().forEach(key => {
+ const matched = key.match(/([A-Za-z0-9-_]+)\./i)
+ if (matched && matched.length > 1) {
+ const locale = matched[1]
+ messages[locale] = locales(key)
+ }
+ })
+ return messages
+}
+
+export default new VueI18n({
+ locale: process.env.VUE_APP_I18N_LOCALE || 'nb', // Here you can customize
+ fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
+ messages: loadLocaleMessages()
+})
diff --git a/src/locales/en.json b/src/locales/en.json
new file mode 100644
index 0000000000000000000000000000000000000000..9e9f5c7c68d9a75c9df763a4b341a2e4d8efd72d
--- /dev/null
+++ b/src/locales/en.json
@@ -0,0 +1,3 @@
+{
+ "startpage": "Start page"
+}
\ No newline at end of file
diff --git a/src/locales/nb.json b/src/locales/nb.json
new file mode 100644
index 0000000000000000000000000000000000000000..d2862dd814b1e9a1341c0c686bb9dabd403a86ed
--- /dev/null
+++ b/src/locales/nb.json
@@ -0,0 +1,3 @@
+{
+ "startpage": "Startsiden"
+}
\ No newline at end of file
diff --git a/src/main.js b/src/main.js
index 0823a9a194d122e5950afd85002c1df63a91ccf4..eeb5de6b307f983d1b602f276416dc19fcd62451 100644
--- a/src/main.js
+++ b/src/main.js
@@ -3,24 +3,31 @@
import Vue from 'vue'
import App from './App'
import router from './router'
+import i18n from './i18n'
Vue.config.productionTip = false
/* eslint-disable no-new */
const init = () => {
new Vue({
- el: '#app',
- router,
- components: { App },
- template: '<App/>',
- data: {
+ el: '#app',
+ router,
+ components: { App },
+ template: '<App/>',
+
+ data: {
},
- methods: {
+
+ methods: {
},
- created() {
- console.info("Vue is ready")
+
+ i18n,
+
+ created() {
+ console.info("Vue is ready");
+ console.info("User's preferred language is " + navigator.language);
}
- });
+ });
};
/**
@@ -29,7 +36,8 @@ const init = () => {
*/
new Vue({
el: '#vipsobsappmenu',
- router
+ router,
+ i18n,
});
// Wait for the deviceready event to start the render
diff --git a/vue.config.js b/vue.config.js
new file mode 100644
index 0000000000000000000000000000000000000000..93ef04aa3aa9473fb173de2074a102745b209b51
--- /dev/null
+++ b/vue.config.js
@@ -0,0 +1,10 @@
+module.exports = {
+ pluginOptions: {
+ i18n: {
+ locale: 'nb',
+ fallbackLocale: 'en',
+ localeDir: 'locales',
+ enableInSFC: false
+ }
+ }
+}