Mercurial > gemma
annotate client/docs/developer.md @ 1443:6b100f639178
removed blue borders from fairwayprofile and infobar
author | Markus Kottlaender <markus@intevation.de> |
---|---|
date | Fri, 30 Nov 2018 13:20:26 +0100 |
parents | ec0a0542c221 |
children | 70573eea890e |
rev | line source |
---|---|
482
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
1 # General considerations |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
2 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
3 ## We chose [vuejs](https://vuejs.org/) |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
4 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
5 Vue is a modern framework for webdevelopment. |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
6 It offers a very homogenous ecosystem (vuejs, vuecli, vue-router vuex) combined with up to date fontend rendering techniques like virtual DOM. |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
7 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
8 ## We chose [vue cli](https://cli.vuejs.org/) |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
9 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
10 Vue cli allows a good jumpstart for a vuejs project. |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
11 There is no manual boilerplate to write. Everything is in place and already wired. The skeleton is easy extendable and in contrast to |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
12 other frameworks (i.e. create-react-app) there is no "eject" for further customization necessary. |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
13 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
14 Configuration: |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
15 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
16 - Babel |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
17 - Router |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
18 - Vuex |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
19 - CSSPreprocessor |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
20 - Linter+Unit |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
21 - Testing+E2E |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
22 - Testing |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
23 - No Typescript (No advantages) |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
24 - No PWA (IE11 compatibility makes more modern approaches unavailable) |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
25 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
26 - SASS as CSS Preprocessor (widely used, allows programmatic CSS, familarity) |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
27 - Eslint + Prettier (Rationale below) |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
28 - Lint on Save |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
29 - Jest as Unittesting framework (zeroconf, ease of use) [productpage](https://jestjs.io/ |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
30 - Nightwatch (Seleniumbased, familarity with selenium, Chromedriver ootB) |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
31 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
32 Everything in dedicated config files |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
33 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
34 ## We chose [vuex](https://vuex.vuejs.org/guide/) |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
35 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
36 Vuex is the store component of vuejs. For medium to complex applications it is reasonable to centralize state globally, to make every possible interaction with state transparent. Interactions with state become traceable in contrast to chains built with components and properties. |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
37 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
38 Perhaps it is resonable to configure [strict mode](https://vuex.vuejs.org/api/#strict) in the future (for development). State changes should only be allowed through `actions` and `mutations`. |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
39 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
40 Besides traceability vuex allows to dumb down components. |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
41 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
42 ## We chose [prettier](https://prettier.io/) in combination with [eslint](https://eslint.org/) |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
43 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
44 To enforce tight styling guidelines (e.g. avoidance of problems with [semicolons](https://eslint.org/docs/rules/no-unexpected-multiline)) and strict formatting rules, prettier was chosen. Prettier as a plugin is widey supported: |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
45 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
46 - [vim](https://github.com/prettier/vim-prettier) |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
47 - [emacs](https://github.com/prettier/prettier-emacs) |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
48 - [VSCode](https://github.com/prettier/prettier-vscode) |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
49 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
50 On top, there is [pretty quick](https://www.npmjs.com/package/pretty-quick) a tool, which allows autmatically solving linting issues for you. |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
51 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
52 Overall prettier makes styling issues a non-issue: You get achieve styled code as a result. Code which is automatically formatted is easier to read for humans (it is in every project the same guideline) and easier to read for machines (which offer help like `pretty-quick`). |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
53 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
54 Similar philosophy as behind [gofmt](https://golang.org/cmd/gofmt/) |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
55 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
56 ## We chose [env](https://github.com/motdotla/dotenv) as configurtion file format |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
57 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
58 It is good practice to store configuration in the environment (see [12 factor app](https://12factor.net/config)). |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
59 From this idea evolved the practice to use `.env` files for configuring the environment. |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
60 `.env` is a standard widely supported, e.g. |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
61 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
62 - [go](https://github.com/joho/godotenv) |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
63 - [Node](https://www.npmjs.com/package/dotenv) |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
64 - [Webpack](https://www.npmjs.com/package/dotenv-webpack) |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
65 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
66 Last but not least: `.env` is the format, which is used by [vue-cli](https://cli.vuejs.org/guide/mode-and-env.html) |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
67 |
168
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
68 # Translation |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
69 |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
70 We want to internationalize our application for the following |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
71 languages: |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
72 |
482
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
73 - EN |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
74 - DE |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
75 - SK |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
76 - HU |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
77 - HR |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
78 - RS |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
79 - BiH |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
80 - BG |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
81 - RO |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
82 - UA |
168
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
83 |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
84 ## Our preferred translation cycle is as follows: |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
85 |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
86 Application -> .po files -> Weblate -> .po files -> Application |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
87 |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
88 There are several possibilities to achieve this goal. |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
89 |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
90 ## We chose [vue-gettext](https://github.com/Polyconseil/vue-gettext) |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
91 |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
92 Rationale: |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
93 * No other framework supports our preferred translation cycle fully |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
94 * Relies in parts on well known utilities (xgettext) |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
95 * Allows phrases as parameters instead of Variables |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
96 $gettext("Dear Sir") opposed to $("greeting") |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
97 |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
98 Downsides: |
482
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
99 |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
100 - At present (July 2018) there are some annoying issues, which demand quirky solutions: |
168
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
101 |
482
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
102 - [xgettext fails with some .vue files](https://github.com/Polyconseil/vue-gettext/issues/28) which forces us to use `(`, `)` around templates |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
103 - [translations in attributes](https://github.com/Polyconseil/vue-gettext/issues/9) which leaves us with either interpolating in templates with `<translate></translate>` or use computed properties in Vue components (cf. Login component). |
1428
ec0a0542c221
client: add hints to docs for translation
Bernhard Reiter <bernhard@intevation.de>
parents:
1402
diff
changeset
|
104 - [inconsistent white space handling](https://github.com/Polyconseil/vue-gettext/issues/80) if you need a white space preserved before the translated tag, use `<span v-translate class="fix-trans-space">to be translated</a>` (see `src/assets/application.sass`). |
168
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
105 |
482
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
106 - Is dependend on external (=non JS) tools (`xgettext`) which are not able to consume `.vue`-files directly, which in turn leads to unexpected behaviour. |
3e5ed9f40095
docs: Rationale for clientside framework decisions
Thomas Junk <thomas.junk@intevation.de>
parents:
168
diff
changeset
|
107 - |
168
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
108 |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
109 ## Commands |
1402
acb71a982837
client: improve translation process docs
Fadi Abbud <fadi.abbud@intevation.de>
parents:
482
diff
changeset
|
110 You need the following applications to run the process: |
acb71a982837
client: improve translation process docs
Fadi Abbud <fadi.abbud@intevation.de>
parents:
482
diff
changeset
|
111 * `gettext` (e.g. from Debian gettext 0.19.8.1-9) |
acb71a982837
client: improve translation process docs
Fadi Abbud <fadi.abbud@intevation.de>
parents:
482
diff
changeset
|
112 * `vue-gettext` and `easygettext` (e.g. via yarn or npm) |
168
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
113 |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
114 In order to extract the messages from the templates call `make makemessages`. |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
115 After that you have the `.po`-file which could be translated. |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
116 After translation, you have to call `make translations` to generate the `translations.json` |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
117 which is consumed by `vue-gettext`. |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
118 |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
119 The workflow is as follows: |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
120 |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
121 `component.vue ---> /tmp/template.pot ---> app/locale/fr_FR/LC_MESSAGES/app.po ---> app/translations.json` |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
122 |
e4e4a0e6338e
docs: Added a developer documentation
Thomas Junk <thomas.junk@intevation.de>
parents:
diff
changeset
|
123 (taken from the documentation of `vue-gettext`) |