@museumwnf/viewer-i18n 3.1.0 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md CHANGED
@@ -1,44 +1,44 @@
1
- This package is Content of the MWNF Website in the sense of the legal notice below, which governs it.
2
-
3
- Source: https://www.museumwnf.org/about/legal-notice
4
- Retrieved: 2026-09-08
5
-
6
- ---
7
-
8
- # Important Legal Notice
9
-
10
- ## DEFINITIONS
11
-
12
- - **'Museum'**: Refers to Museum Ohne Grenzen e.V. (trading as **'Museum With No Frontiers'**, hereinafter **'MWNF'**), an international non-profit association incorporated under Austrian law, and the Consortium.
13
- - **'Consortium'**: The group of museums, public/private entities, and individuals coordinated by Museum Ohne Grenzen for the development of the [Website](https://museumwnf.org/).
14
- - **'Website'**: [museumwnf.org](https://museumwnf.org/) and all associated subdomains and services.
15
- - **'Content'**: All images, texts, data, software, audio-visual files, and metadata displayed on the Website.
16
- - **'Orphan Work'**: A work protected by copyright for which the rightsholder cannot be identified or located despite a [reasonably diligent search](https://www.euipo.europa.eu/en/observatory/awareness/ip-in-culture/orphan-works-db).
17
-
18
- ## DISCLAIMER
19
-
20
- The Website is maintained by MWNF. The European Union funded the initial development of this Website during the realisation of the Discover Islamic Art project. Since EU funding concluded in 2007, the Website has been maintained and further developed solely by MWNF. Content is provided "as is" and constitutes a work in progress. While MWNF makes every effort to ensure accuracy, the Museum is not liable for damages arising from the use of, or reliance on, the Content.
21
-
22
- ## TERMS AND CONDITIONS FOR USE
23
-
24
- 1. **Copyright Protection**: The Content is protected by copyright. MWNF retains all rights unless proprietary rights are held by third parties.
25
- 2. **Permitted Use**: Non-commercial, personal, educational, or scientific use is permitted strictly within the limits of the Austrian Copyright Act (Urheberrechtsgesetz - Urhg) and international treaties.
26
- 3. **Citations and Attribution**: All citations must include either the URL www.museumwnf.org or the specific 'source-URL' published on the relevant page.
27
- 4. **Mandatory Reporting**: Users are required to provide MWNF with a full digital or physical copy of any publication that makes use of Website Content
28
- 5. **Unauthorised Use**: Any reproduction, downloading, printing, or communication to the public of Content from the Website (including text, images, and documentation) for commercial purposes—including commercial publication or personal financial gain—is strictly prohibited without prior written permission from MWNF. Unauthorised use includes, but is not limited to, the redistribution of Content, removing author or source credits, or failing to acknowledge www.museumwnf.org as the source. Furthermore, works identified as belonging to third-party artists or their heirs cannot be copied or downloaded without separate permission from the respective rights holder.
29
- 6. **Enquiries**: Please submit requests or notifications to: [management@museumwnf.net](mailto:management@museumwnf.net).
30
- 7. **Artificial Intelligence & Data Mining (AI Opt-Out)**:
31
- - **Express Prohibition**: Pursuant to Article 4(3) of Directive (EU) 2019/790 and the corresponding implementation in Austrian law, the Museum expressly reserves all rights regarding Text and Data Mining (TDM) and automated data scraping.
32
- - **AI Training**: The use of any Content for the training, development, or operation of Artificial Intelligence models, machine learning systems, or Large Language Models (LLMs) is strictly prohibited.
33
- - **Automated Access**: Unauthorised web scraping, crawling, or automated extraction of data for commercial AI purposes constitutes a breach of these terms.
34
- 8. **Orphan Works**:
35
- - MWNF displays certain works identified as Orphan Works for cultural and educational purposes, following a diligent search for rightsholders.
36
- - If you are the rightsholder of a work displayed on this site and wish to assert your rights, please contact MWNF Management.
37
-
38
- ## PRIVACY POLICY
39
-
40
- Personal data processing is governed by the EU General Data Protection Regulation (GDPR). MWNF undertakes not to sell or rent personal data provided via the Website or newsletter to any third party.
41
-
42
- ## MISCELLANEOUS
43
-
44
- This Legal Notice is governed by the laws of Austria. Any disputes shall be submitted to the exclusive jurisdiction of the courts of Vienna.
1
+ This package is Content of the MWNF Website in the sense of the legal notice below, which governs it.
2
+
3
+ Source: https://www.museumwnf.org/about/legal-notice
4
+ Retrieved: 2026-09-08
5
+
6
+ ---
7
+
8
+ # Important Legal Notice
9
+
10
+ ## DEFINITIONS
11
+
12
+ - **'Museum'**: Refers to Museum Ohne Grenzen e.V. (trading as **'Museum With No Frontiers'**, hereinafter **'MWNF'**), an international non-profit association incorporated under Austrian law, and the Consortium.
13
+ - **'Consortium'**: The group of museums, public/private entities, and individuals coordinated by Museum Ohne Grenzen for the development of the [Website](https://museumwnf.org/).
14
+ - **'Website'**: [museumwnf.org](https://museumwnf.org/) and all associated subdomains and services.
15
+ - **'Content'**: All images, texts, data, software, audio-visual files, and metadata displayed on the Website.
16
+ - **'Orphan Work'**: A work protected by copyright for which the rightsholder cannot be identified or located despite a [reasonably diligent search](https://www.euipo.europa.eu/en/observatory/awareness/ip-in-culture/orphan-works-db).
17
+
18
+ ## DISCLAIMER
19
+
20
+ The Website is maintained by MWNF. The European Union funded the initial development of this Website during the realisation of the Discover Islamic Art project. Since EU funding concluded in 2007, the Website has been maintained and further developed solely by MWNF. Content is provided "as is" and constitutes a work in progress. While MWNF makes every effort to ensure accuracy, the Museum is not liable for damages arising from the use of, or reliance on, the Content.
21
+
22
+ ## TERMS AND CONDITIONS FOR USE
23
+
24
+ 1. **Copyright Protection**: The Content is protected by copyright. MWNF retains all rights unless proprietary rights are held by third parties.
25
+ 2. **Permitted Use**: Non-commercial, personal, educational, or scientific use is permitted strictly within the limits of the Austrian Copyright Act (Urheberrechtsgesetz - Urhg) and international treaties.
26
+ 3. **Citations and Attribution**: All citations must include either the URL www.museumwnf.org or the specific 'source-URL' published on the relevant page.
27
+ 4. **Mandatory Reporting**: Users are required to provide MWNF with a full digital or physical copy of any publication that makes use of Website Content
28
+ 5. **Unauthorised Use**: Any reproduction, downloading, printing, or communication to the public of Content from the Website (including text, images, and documentation) for commercial purposes—including commercial publication or personal financial gain—is strictly prohibited without prior written permission from MWNF. Unauthorised use includes, but is not limited to, the redistribution of Content, removing author or source credits, or failing to acknowledge www.museumwnf.org as the source. Furthermore, works identified as belonging to third-party artists or their heirs cannot be copied or downloaded without separate permission from the respective rights holder.
29
+ 6. **Enquiries**: Please submit requests or notifications to: [management@museumwnf.net](mailto:management@museumwnf.net).
30
+ 7. **Artificial Intelligence & Data Mining (AI Opt-Out)**:
31
+ - **Express Prohibition**: Pursuant to Article 4(3) of Directive (EU) 2019/790 and the corresponding implementation in Austrian law, the Museum expressly reserves all rights regarding Text and Data Mining (TDM) and automated data scraping.
32
+ - **AI Training**: The use of any Content for the training, development, or operation of Artificial Intelligence models, machine learning systems, or Large Language Models (LLMs) is strictly prohibited.
33
+ - **Automated Access**: Unauthorised web scraping, crawling, or automated extraction of data for commercial AI purposes constitutes a breach of these terms.
34
+ 8. **Orphan Works**:
35
+ - MWNF displays certain works identified as Orphan Works for cultural and educational purposes, following a diligent search for rightsholders.
36
+ - If you are the rightsholder of a work displayed on this site and wish to assert your rights, please contact MWNF Management.
37
+
38
+ ## PRIVACY POLICY
39
+
40
+ Personal data processing is governed by the EU General Data Protection Regulation (GDPR). MWNF undertakes not to sell or rent personal data provided via the Website or newsletter to any third party.
41
+
42
+ ## MISCELLANEOUS
43
+
44
+ This Legal Notice is governed by the laws of Austria. Any disputes shall be submitted to the exclusive jurisdiction of the courts of Vienna.
package/README.md CHANGED
@@ -1,173 +1,173 @@
1
- # viewer-i18n
2
-
3
- The texts shared by the MWNF websites: menu labels, buttons, the labels of an
4
- item sheet, and the editorial blocks that are the same on every website of a
5
- kind. A text that belongs to **one** website is not here — it lives in that
6
- website's own `locales/` folder.
7
-
8
- The museum content itself — the objects, the exhibitions, the partners — is not
9
- here either. It arrives already translated with each website's data.
10
-
11
- ## Editing a text
12
-
13
- You need a GitHub account and a browser; nothing else.
14
-
15
- 1. **Open the folder for the section you want** — `core/`, `layout/`,
16
- `gallery/` or `exhibition/` — and click the file for your language.
17
- `en.json` is English, `fr.json` French, and so on.
18
- 2. **Click the pencil** (✏️, top right). Change only the text between the
19
- second pair of quotation marks on a line. The part before the colon is the
20
- name of the entry and must stay exactly as it is.
21
- 3. **Click "Commit changes…", then "Propose changes".**
22
- 4. **Wait for the automatic check.** After a minute or two the page shows a
23
- green tick and the change is merged by itself. If something is off, a
24
- comment appears explaining in plain language what to fix; edit again on the
25
- same page and the check runs afresh.
26
-
27
- The websites pick the change up at their next platform update.
28
-
29
- ## Starting a new language
30
-
31
- Open `en.json` in a section, copy all of it, then **Add file → Create new
32
- file**, name it with the two-letter code (`ar.json`, `es.json`, `fr.json`, …),
33
- paste, and translate. Do the same in each section the language needs.
34
-
35
- A language does not have to be complete: any text you have not translated yet
36
- shows in English. There is nothing to declare anywhere and no code to change.
37
-
38
- ## What a text may contain
39
-
40
- A text is **just text**. It may be formatted with Markdown — `**bold**`,
41
- `*italic*`, `[a link](https://example.org)`, blank lines between paragraphs —
42
- and that is all.
43
-
44
- It may not contain `{` or `}`. Nothing is ever inserted into a text: a number,
45
- a date or a name is placed next to the text by the website, never inside it.
46
- This is why a text can be translated freely, without having to preserve
47
- anything.
48
-
49
- Writing an HTML tag is not forbidden, because it does not work: the websites
50
- escape HTML instead of rendering it, so `<b>Home</b>` appears on the page as
51
- those exact characters, angle brackets and all. Use Markdown.
52
-
53
- ## The sections
54
-
55
- | Folder | Holds the texts of |
56
- | --- | --- |
57
- | `core/` | the pages every website builds on |
58
- | `layout/` | the frame around a page: navigation, language chooser, footer |
59
- | `gallery/` | the galleries (Carpets, Amulets, …) |
60
- | `catalogue/` | the list pages every website has: the filters, the search form, the results and their pages |
61
- | `sheet/` | the labels of a record's sheet — name, date, dimensions, provenance, who prepared it |
62
- | `record/` | what surrounds the sheet: back, timeline, related items, credits, citation, the glossary, the dynasties popout |
63
- | `exhibition/` | the exhibitions (Water in Islam, The Use of Colours in Art, …) |
64
- | `timeline/` | the timeline pages: the country and period form, the results, the errors — worded so the same text serves a gallery, an exhibition or a standalone site |
65
- | `partner/` | the partner pages: the profile fields, the map, the list and its sorting, "not found" — worded the same way |
66
-
67
- `gallery/` and `exhibition/` hold only what a gallery or an exhibition says and no other kind of website does — the sections, the navigation, the partner page's intro, the timeline page's intro, the notices, the themes. What every website says the same way lives once, in `catalogue/`, `sheet/`, `record/`, `timeline/` and `partner/`, so that the seven websites read one vocabulary rather than seven; since 2.0.0 the two family sections carry no copy of it. `timeline/` and `partner/` carry no product name: they say "in this site", never "Gallery" or "Exhibition", so the one text serves every kind of website — the few entries whose wording is a product's own stay in `gallery` and `exhibition`.
68
-
69
- Entry names are written as `section.group.name` — three parts, so
70
- `gallery.sheet.inventoryNumber` reads as "in the galleries, on the item sheet,
71
- the inventory number", and `sheet.field.inventoryNumber` "on any sheet, the
72
- field, the inventory number".
73
-
74
- A shared label carries no trailing colon: whether a label ends in a colon is a
75
- matter of layout, which the page decides.
76
-
77
- ## Which languages a section must exist in
78
-
79
- A website offers the languages its data package declares, and a visitor who
80
- picks one reads the whole page in it — the records from the package, the
81
- texts from here. So each kind of website names, in `namespaces.json` under
82
- `languages`, the languages its websites offer, and **every section that kind
83
- receives has to be complete in each of them**. The shared sections are in
84
- every bundle, so they need the union: today `ar cs de el en es fr it pt se tr`.
85
- The automatic check refuses a section that is missing a language, or an entry
86
- in one, that a website of that kind offers.
87
-
88
- To add a language a website is about to offer: add it to the kind's list,
89
- then create the file in every section that kind receives. [`sources.md`](sources.md)
90
- says where the existing translations came from.
91
-
92
- `se` is Swedish: the data packages declare it with the legacy code, and the
93
- websites match codes as written, so the file is named after what they say.
94
-
95
- ## For developers
96
-
97
- Each kind of website receives one prebuilt bundle, and nothing else:
98
-
99
- | Kind | Bundle | Contains |
100
- | --- | --- | --- |
101
- | Products (Islamic Art, Baroque Art, Sharing History) | `@museumwnf/viewer-i18n/standalone` | `core` + `layout` + `catalogue` + `sheet` + `record` + `exhibition` + `timeline` + `partner` |
102
- | Galleries | `@museumwnf/viewer-i18n/gallery` | the same, with `gallery` in place of `exhibition` |
103
- | Exhibitions | `@museumwnf/viewer-i18n/exhibition` | the same as Products |
104
-
105
- ```js
106
- import { catalogues } from '@museumwnf/viewer-i18n/gallery'
107
- // { en: { 'core.nav.home': 'Home', … } }
108
- ```
109
-
110
- A website merges its own `locales/<lang>.json` over that bundle, and the local
111
- value wins. That is the only merge rule in the system: a website may overload
112
- any entry it receives and add entries of its own, but it cannot delete one.
113
-
114
- It says which bundle it receives, and what its own entries are called, in its
115
- `package.json`:
116
-
117
- ```json
118
- "viewerI18n": { "class": "gallery", "namespace": "carpets" }
119
- ```
120
-
121
- `class` is one of `standalone`, `gallery`, `exhibition`. `namespace` is one
122
- lowercase word, no hyphens (`carpets`, `waterInIslam`) — it cannot be one of
123
- the shared section names, and it is the prefix the website's own entries carry.
124
- The checks below read this to know what a file may contain, so they refuse to
125
- run without it.
126
-
127
- `namespaces.json` is the registry: the sections that exist and what each bundle
128
- contains. `tools/build.mjs` produces the bundles; `tools/check.mjs` is the
129
- whole rulebook, and also ships with the package so websites enforce the same
130
- rules on their own texts:
131
-
132
- ```bash
133
- npx viewer-i18n-check --site . # a website's locales/, on its own
134
- npx viewer-i18n-check --app . # …and every entry its code asks for
135
- npx viewer-i18n-check --app . --languages ar,en,fr # …for a set other than the package's
136
- ```
137
-
138
- `--app` reads a name wherever the website asks for one: a `t('…')` or `$t('…')`
139
- call, an `I18nText` keypath, and — since 2.1.0 — a name written in a spec the
140
- platform renders, such as `title: 'carpets.identity.title'` in a
141
- `dataset.config.js` or a label in a catalogue or sheet spec for viewer-layout's
142
- composed views. A plain string reads as a name when it has three parts and its
143
- first is a section the website receives; every name found has to exist.
144
-
145
- `--app` also reads the languages the website offers — `manifest.site.languages`
146
- of the installed `@museumwnf/<dataset>-data`, the list the website itself reads —
147
- and fails when the installed bundle has no complete file for one of them: that
148
- visitor would read the records in their language and every label in English.
149
- `--languages` asks about another set, for a website about to offer one.
150
-
151
- ## Licence
152
-
153
- This package is Content of the MWNF Website under the [MWNF legal
154
- notice](https://www.museumwnf.org/about/legal-notice), which governs its use
155
- (non-commercial, personal, educational and scientific use is permitted, with
156
- attribution and mandatory reporting — see the notice for the full terms). The
157
- notice text also ships in this package as `LICENSE.md`. This package carries
158
- translated data (the dictionary), not just code, so the notice governs the
159
- texts as much as it governs the data packages.
160
-
161
- ## Release procedure
162
-
163
- 1. Merge to `main` via a pull request (CI validates the texts and builds every
164
- website against the packed tarball).
165
- 2. Create a GitHub release tagged `vX.Y.Z` — CI publishes to npmjs (versions up
166
- to 3.0.1, published as `@metanull/viewer-i18n`, remain available on GitHub
167
- Packages, frozen; no new version is published there).
168
- 3. Semver: **patch** = a text changed; **minor** = an entry or a language
169
- added; **major** = an entry renamed or removed.
170
-
171
- Websites receive it through the platform's propagation run — see
172
- [MAINTENANCE.md](https://github.com/metanull/viewer-workflows/blob/main/MAINTENANCE.md)
173
- in `viewer-workflows`.
1
+ # viewer-i18n
2
+
3
+ The texts shared by the MWNF websites: menu labels, buttons, the labels of an
4
+ item sheet, and the editorial blocks that are the same on every website of a
5
+ kind. A text that belongs to **one** website is not here — it lives in that
6
+ website's own `locales/` folder.
7
+
8
+ The museum content itself — the objects, the exhibitions, the partners — is not
9
+ here either. It arrives already translated with each website's data.
10
+
11
+ ## Editing a text
12
+
13
+ You need a GitHub account and a browser; nothing else.
14
+
15
+ 1. **Open the folder for the section you want** — `core/`, `layout/`,
16
+ `gallery/` or `exhibition/` — and click the file for your language.
17
+ `en.json` is English, `fr.json` French, and so on.
18
+ 2. **Click the pencil** (✏️, top right). Change only the text between the
19
+ second pair of quotation marks on a line. The part before the colon is the
20
+ name of the entry and must stay exactly as it is.
21
+ 3. **Click "Commit changes…", then "Propose changes".**
22
+ 4. **Wait for the automatic check.** After a minute or two the page shows a
23
+ green tick and the change is merged by itself. If something is off, a
24
+ comment appears explaining in plain language what to fix; edit again on the
25
+ same page and the check runs afresh.
26
+
27
+ The websites pick the change up at their next platform update.
28
+
29
+ ## Starting a new language
30
+
31
+ Open `en.json` in a section, copy all of it, then **Add file → Create new
32
+ file**, name it with the two-letter code (`ar.json`, `es.json`, `fr.json`, …),
33
+ paste, and translate. Do the same in each section the language needs.
34
+
35
+ A language does not have to be complete: any text you have not translated yet
36
+ shows in English. There is nothing to declare anywhere and no code to change.
37
+
38
+ ## What a text may contain
39
+
40
+ A text is **just text**. It may be formatted with Markdown — `**bold**`,
41
+ `*italic*`, `[a link](https://example.org)`, blank lines between paragraphs —
42
+ and that is all.
43
+
44
+ It may not contain `{` or `}`. Nothing is ever inserted into a text: a number,
45
+ a date or a name is placed next to the text by the website, never inside it.
46
+ This is why a text can be translated freely, without having to preserve
47
+ anything.
48
+
49
+ Writing an HTML tag is not forbidden, because it does not work: the websites
50
+ escape HTML instead of rendering it, so `<b>Home</b>` appears on the page as
51
+ those exact characters, angle brackets and all. Use Markdown.
52
+
53
+ ## The sections
54
+
55
+ | Folder | Holds the texts of |
56
+ | --- | --- |
57
+ | `core/` | the pages every website builds on |
58
+ | `layout/` | the frame around a page: navigation, language chooser, footer |
59
+ | `gallery/` | the galleries (Carpets, Amulets, …) |
60
+ | `catalogue/` | the list pages every website has: the filters, the search form, the results and their pages |
61
+ | `sheet/` | the labels of a record's sheet — name, date, dimensions, provenance, who prepared it |
62
+ | `record/` | what surrounds the sheet: back, timeline, related items, credits, citation, the glossary, the dynasties popout |
63
+ | `exhibition/` | the exhibitions (Water in Islam, The Use of Colours in Art, …) |
64
+ | `timeline/` | the timeline pages: the country and period form, the results, the errors — worded so the same text serves a gallery, an exhibition or a standalone site |
65
+ | `partner/` | the partner pages: the profile fields, the map, the list and its sorting, "not found" — worded the same way |
66
+
67
+ `gallery/` and `exhibition/` hold only what a gallery or an exhibition says and no other kind of website does — the sections, the navigation, the partner page's intro, the timeline page's intro, the notices, the themes. What every website says the same way lives once, in `catalogue/`, `sheet/`, `record/`, `timeline/` and `partner/`, so that the seven websites read one vocabulary rather than seven; since 2.0.0 the two family sections carry no copy of it. `timeline/` and `partner/` carry no product name: they say "in this site", never "Gallery" or "Exhibition", so the one text serves every kind of website — the few entries whose wording is a product's own stay in `gallery` and `exhibition`.
68
+
69
+ Entry names are written as `section.group.name` — three parts, so
70
+ `gallery.sheet.inventoryNumber` reads as "in the galleries, on the item sheet,
71
+ the inventory number", and `sheet.field.inventoryNumber` "on any sheet, the
72
+ field, the inventory number".
73
+
74
+ A shared label carries no trailing colon: whether a label ends in a colon is a
75
+ matter of layout, which the page decides.
76
+
77
+ ## Which languages a section must exist in
78
+
79
+ A website offers the languages its data package declares, and a visitor who
80
+ picks one reads the whole page in it — the records from the package, the
81
+ texts from here. So each kind of website names, in `namespaces.json` under
82
+ `languages`, the languages its websites offer, and **every section that kind
83
+ receives has to be complete in each of them**. The shared sections are in
84
+ every bundle, so they need the union: today `ar cs de el en es fr it pt se tr`.
85
+ The automatic check refuses a section that is missing a language, or an entry
86
+ in one, that a website of that kind offers.
87
+
88
+ To add a language a website is about to offer: add it to the kind's list,
89
+ then create the file in every section that kind receives. [`sources.md`](sources.md)
90
+ says where the existing translations came from.
91
+
92
+ `se` is Swedish: the data packages declare it with the legacy code, and the
93
+ websites match codes as written, so the file is named after what they say.
94
+
95
+ ## For developers
96
+
97
+ Each kind of website receives one prebuilt bundle, and nothing else:
98
+
99
+ | Kind | Bundle | Contains |
100
+ | --- | --- | --- |
101
+ | Products (Islamic Art, Baroque Art, Sharing History) | `@museumwnf/viewer-i18n/standalone` | `core` + `layout` + `catalogue` + `sheet` + `record` + `exhibition` + `timeline` + `partner` |
102
+ | Galleries | `@museumwnf/viewer-i18n/gallery` | the same, with `gallery` in place of `exhibition` |
103
+ | Exhibitions | `@museumwnf/viewer-i18n/exhibition` | the same as Products |
104
+
105
+ ```js
106
+ import { catalogues } from '@museumwnf/viewer-i18n/gallery'
107
+ // { en: { 'core.nav.home': 'Home', … } }
108
+ ```
109
+
110
+ A website merges its own `locales/<lang>.json` over that bundle, and the local
111
+ value wins. That is the only merge rule in the system: a website may overload
112
+ any entry it receives and add entries of its own, but it cannot delete one.
113
+
114
+ It says which bundle it receives, and what its own entries are called, in its
115
+ `package.json`:
116
+
117
+ ```json
118
+ "viewerI18n": { "class": "gallery", "namespace": "carpets" }
119
+ ```
120
+
121
+ `class` is one of `standalone`, `gallery`, `exhibition`. `namespace` is one
122
+ lowercase word, no hyphens (`carpets`, `waterInIslam`) — it cannot be one of
123
+ the shared section names, and it is the prefix the website's own entries carry.
124
+ The checks below read this to know what a file may contain, so they refuse to
125
+ run without it.
126
+
127
+ `namespaces.json` is the registry: the sections that exist and what each bundle
128
+ contains. `tools/build.mjs` produces the bundles; `tools/check.mjs` is the
129
+ whole rulebook, and also ships with the package so websites enforce the same
130
+ rules on their own texts:
131
+
132
+ ```bash
133
+ npx viewer-i18n-check --site . # a website's locales/, on its own
134
+ npx viewer-i18n-check --app . # …and every entry its code asks for
135
+ npx viewer-i18n-check --app . --languages ar,en,fr # …for a set other than the package's
136
+ ```
137
+
138
+ `--app` reads a name wherever the website asks for one: a `t('…')` or `$t('…')`
139
+ call, an `I18nText` keypath, and — since 2.1.0 — a name written in a spec the
140
+ platform renders, such as `title: 'carpets.identity.title'` in a
141
+ `dataset.config.js` or a label in a catalogue or sheet spec for viewer-layout's
142
+ composed views. A plain string reads as a name when it has three parts and its
143
+ first is a section the website receives; every name found has to exist.
144
+
145
+ `--app` also reads the languages the website offers — `manifest.site.languages`
146
+ of the installed `@museumwnf/<dataset>-data`, the list the website itself reads —
147
+ and fails when the installed bundle has no complete file for one of them: that
148
+ visitor would read the records in their language and every label in English.
149
+ `--languages` asks about another set, for a website about to offer one.
150
+
151
+ ## Licence
152
+
153
+ This package is Content of the MWNF Website under the [MWNF legal
154
+ notice](https://www.museumwnf.org/about/legal-notice), which governs its use
155
+ (non-commercial, personal, educational and scientific use is permitted, with
156
+ attribution and mandatory reporting — see the notice for the full terms). The
157
+ notice text also ships in this package as `LICENSE.md`. This package carries
158
+ translated data (the dictionary), not just code, so the notice governs the
159
+ texts as much as it governs the data packages.
160
+
161
+ ## Release procedure
162
+
163
+ 1. Merge to `main` via a pull request (CI validates the texts and builds every
164
+ website against the packed tarball).
165
+ 2. Create a GitHub release tagged `vX.Y.Z` — CI publishes to npmjs (versions up
166
+ to 3.0.1, published as `@metanull/viewer-i18n`, remain available on GitHub
167
+ Packages, frozen; no new version is published there).
168
+ 3. Semver: **patch** = a text changed; **minor** = an entry or a language
169
+ added; **major** = an entry renamed or removed.
170
+
171
+ Websites receive it through the platform's propagation run — see
172
+ [MAINTENANCE.md](https://github.com/metanull/viewer-workflows/blob/main/MAINTENANCE.md)
173
+ in `viewer-workflows`.
package/namespaces.json CHANGED
@@ -1,13 +1,13 @@
1
- {
2
- "namespaces": ["core", "layout", "catalogue", "sheet", "record", "gallery", "exhibition", "timeline", "partner"],
3
- "bundles": {
4
- "standalone": ["core", "layout", "catalogue", "sheet", "record", "exhibition", "timeline", "partner"],
5
- "gallery": ["core", "layout", "catalogue", "sheet", "record", "gallery", "timeline", "partner"],
6
- "exhibition": ["core", "layout", "catalogue", "sheet", "record", "exhibition", "timeline", "partner"]
7
- },
8
- "languages": {
9
- "standalone": ["ar", "cs", "de", "el", "en", "es", "fr", "it", "pt", "se", "tr"],
10
- "gallery": ["ar", "en", "es", "fr"],
11
- "exhibition": ["en"]
12
- }
13
- }
1
+ {
2
+ "namespaces": ["core", "layout", "catalogue", "sheet", "record", "gallery", "exhibition", "timeline", "partner"],
3
+ "bundles": {
4
+ "standalone": ["core", "layout", "catalogue", "sheet", "record", "exhibition", "timeline", "partner"],
5
+ "gallery": ["core", "layout", "catalogue", "sheet", "record", "gallery", "timeline", "partner"],
6
+ "exhibition": ["core", "layout", "catalogue", "sheet", "record", "exhibition", "timeline", "partner"]
7
+ },
8
+ "languages": {
9
+ "standalone": ["ar", "cs", "de", "el", "en", "es", "fr", "it", "pt", "se", "tr"],
10
+ "gallery": ["ar", "en", "es", "fr"],
11
+ "exhibition": ["en"]
12
+ }
13
+ }
package/package.json CHANGED
@@ -1,38 +1,38 @@
1
- {
2
- "name": "@museumwnf/viewer-i18n",
3
- "version": "3.1.0",
4
- "description": "Shared static texts for the MWNF website platform: the core, layout, catalogue, sheet, record, gallery, exhibition, timeline and partner namespaces.",
5
- "type": "module",
6
- "license": "SEE LICENSE IN LICENSE.md",
7
- "repository": {
8
- "type": "git",
9
- "url": "git+https://github.com/metanull/viewer-i18n.git"
10
- },
11
- "publishConfig": {
12
- "access": "public",
13
- "registry": "https://registry.npmjs.org/"
14
- },
15
- "files": [
16
- "dist",
17
- "namespaces.json",
18
- "tools/check.mjs"
19
- ],
20
- "exports": {
21
- "./standalone": "./dist/standalone/index.js",
22
- "./gallery": "./dist/gallery/index.js",
23
- "./exhibition": "./dist/exhibition/index.js",
24
- "./namespaces.json": "./namespaces.json",
25
- "./package.json": "./package.json"
26
- },
27
- "bin": {
28
- "viewer-i18n-check": "tools/check.mjs"
29
- },
30
- "scripts": {
31
- "build": "node tools/build.mjs",
32
- "check": "node tools/check.mjs --dictionary .",
33
- "test": "node --test \"tools/*.test.mjs\" && npm run check && npm run build"
34
- },
35
- "devDependencies": {
36
- "@vue/compiler-sfc": "^3.5.42"
37
- }
38
- }
1
+ {
2
+ "name": "@museumwnf/viewer-i18n",
3
+ "version": "3.1.1",
4
+ "description": "Shared static texts for the MWNF website platform: the core, layout, catalogue, sheet, record, gallery, exhibition, timeline and partner namespaces.",
5
+ "type": "module",
6
+ "license": "SEE LICENSE IN LICENSE.md",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/metanull/viewer-i18n.git"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public",
13
+ "registry": "https://registry.npmjs.org/"
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "namespaces.json",
18
+ "tools/check.mjs"
19
+ ],
20
+ "exports": {
21
+ "./standalone": "./dist/standalone/index.js",
22
+ "./gallery": "./dist/gallery/index.js",
23
+ "./exhibition": "./dist/exhibition/index.js",
24
+ "./namespaces.json": "./namespaces.json",
25
+ "./package.json": "./package.json"
26
+ },
27
+ "bin": {
28
+ "viewer-i18n-check": "tools/check.mjs"
29
+ },
30
+ "scripts": {
31
+ "build": "node tools/build.mjs",
32
+ "check": "node tools/check.mjs --dictionary .",
33
+ "test": "node --test \"tools/*.test.mjs\" && npm run check && npm run build"
34
+ },
35
+ "devDependencies": {
36
+ "@vue/compiler-sfc": "^3.5.42"
37
+ }
38
+ }