@sanity/document-internationalization 2.0.0-studio-v3-plugin-v2.13 → 2.0.0-studio-v3-plugin-v2.14

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/README.md CHANGED
@@ -1,62 +1,59 @@
1
1
  # @sanity/document-internationalization
2
2
 
3
+ All new rewrite exclusively for Sanity Studio v3!
4
+
3
5
  - [@sanity/document-internationalization](#sanitydocument-internationalization)
4
- - [Upgrading](#upgrading)
6
+ - [What this plugin solves](#what-this-plugin-solves)
7
+ - [Many projects use both!](#many-projects-use-both)
8
+ - [Upgrade](#upgrade)
5
9
  - [Install](#install)
6
10
  - [Usage](#usage)
7
11
  - [Basic configuration](#basic-configuration)
8
12
  - [Advanced configuration](#advanced-configuration)
9
13
  - [Language field](#language-field)
10
- - [Importing plugin components](#importing-plugin-components)
11
- - [useDocumentInternationalizationContext](#usedocumentinternationalizationcontext)
12
- - [DocumentInternationalizationMenu](#documentinternationalizationmenu)
13
- - [Code examples](#code-examples)
14
+ - [Querying translations](#querying-translations)
14
15
  - [Querying with GROQ](#querying-with-groq)
15
16
  - [Querying with GraphQL](#querying-with-graphql)
16
- - [Allowing the same slug on different language versions](#allowing-the-same-slug-on-different-language-versions)
17
- - [Deleting documents](#deleting-documents)
18
- - [Deleting a single translated document](#deleting-a-single-translated-document)
19
- - [Deleting all translations](#deleting-all-translations)
20
17
  - [Note on document quotas](#note-on-document-quotas)
18
+ - [Documentation](#documentation)
21
19
  - [License](#license)
22
20
  - [Develop \& test](#develop--test)
23
21
  - [Release new version](#release-new-version)
24
22
 
25
- This is the all-new, **Sanity Studio v3 exclusive version** of @sanity/document-internationalization released as v2.0.0
23
+ ![v3 Studio with @sanity/document-internationalization v1 Installed](./docs/img/sanity-document-internationalization-v2.png)
26
24
 
27
- ![v3 Studio with @sanity/document-internationalization v1 Installed](/img/sanity-document-internationalization-v2.png)
25
+ ## What this plugin solves
28
26
 
29
- A complete rewrite of the original Document Internationalization plugin, exclusively for Sanity Studio v3. Major **benefits** from the previous versions include:
27
+ There are two popular methods of internationalization in Sanity Studio:
30
28
 
31
- - Create new documents in any language and link translated references later
32
- - Translation references are written to a separate "meta" document
33
- - Updates to one translation no longer affect the change history of others
34
- - Does not require custom - nor modify the built-in - [Document Actions](https://www.sanity.io/docs/document-actions)
35
- - Changes made to one translation do not patch changes to other documents
36
- - Configurable "language" field on documents
37
- - Built-in static and parameterized initial value templates for new documents
29
+ - **Document-level translation**
30
+ - A unique document version for every language
31
+ - Joined together by references in a `translation.metadata` document
32
+ - Best for documents that have unique, language-specific fields and no common content across languages
33
+ - Best for translating content using Portable Text
34
+ - **Field-level translation**
35
+ - A single document with many languages of content
36
+ - Achieved by mapping over languages on each field
37
+ - Best for documents that have a mix of language-specific and common fields
38
+ - Not recommended for Portable Text
38
39
 
39
- ## Upgrading
40
+ This plugin adds features to the Studio to improve handling **document-level translations**.
40
41
 
41
- If this is your first time installing Document Internationalization, skip to the [Install](#install) section.
42
+ - A Language Selector to create and browse language-specific versions of a Document
43
+ - Hooks and components to use throughout your custom components to handle translations
44
+ - Document Badges to highlight the language version of a document
42
45
 
43
- **I'm on Sanity Studio v3 and upgrading from plugin v1.0.0 and above**
46
+ For **field-level translations** you should use the [sanity-plugin-internationalized-array](https://github.com/sanity-io/sanity-plugin-internationalized-array).
44
47
 
45
- - You will need to perform a content migration to upgrade. [See the plugin upgrade documentation](./docs/00-upgrade-from-v1.md)
46
- - Your queries will also need to change, as translation references have moved. See the [Querying](#querying-with-groq) and [Querying with GraphQL](#querying-with-graphql) sections below. [GraphQL](#)
48
+ ### Many projects use both!
47
49
 
48
- **I'm on Sanity Studio v3 but will stay with the older plugin for now**
50
+ An example of **document-level** translation could be a `lesson` schema, the `title`, `slug` and `content` fields would be unique in every language.
49
51
 
50
- - Please refer to the [v2 branch](https://github.com/sanity-io/document-internationalization/tree/studio-v2)
51
- - Install from `v1.0.0` and above
52
- - This version of the plugin will not be updated with new features
52
+ A good use of **field-level** translation could be a `person` schema. It could have the same `name` and `image` in every language, but only the `biography` would need translating.
53
53
 
54
- **I'm on Sanity Studio v2**
54
+ ## Upgrade
55
55
 
56
- - Please refer to the [studio-v2 branch](https://github.com/sanity-io/document-internationalization/tree/studio-v2)
57
- - Install from `v0.0.0` and above
58
- - This version of the plugin will not be updated with new features
59
- - You will not need to perform a content migration to move to Sanity Studio v3, if you install the v1 plugin.
56
+ See the Upgrade Guide for [v1](./docs/00-upgrade-from-v1.md) for instructions on how to upgrade from the original Document Internationalization plugin.
60
57
 
61
58
  ## Install
62
59
 
@@ -64,19 +61,16 @@ If this is your first time installing Document Internationalization, skip to the
64
61
  npm install --save @sanity/document-internationalization@studio-v3-plugin-v2
65
62
  ```
66
63
 
67
- or
68
-
69
- ```
70
- yarn add @sanity/document-internationalization@studio-v3-plugin-v2
71
- ```
72
-
73
64
  ## Usage
74
65
 
75
66
  Add it as a plugin in `sanity.config.ts` (or .js):
76
67
 
77
68
  ### Basic configuration
78
69
 
79
- The only required configuration is the `supportedLanguages` array and the `schemaTypes` array.
70
+ The only required configuration is:
71
+
72
+ - The `supportedLanguages` array and
73
+ - The `schemaTypes` array
80
74
 
81
75
  ```ts
82
76
  // sanity.config.ts
@@ -135,7 +129,7 @@ export const createConfig({
135
129
  languageField: `language` // defauts to "language"
136
130
 
137
131
  // Optional
138
- // Keep translations.metadata references weak
132
+ // Keep translation.metadata references weak
139
133
  weakReferences: true // defaults to false
140
134
 
141
135
  // Optional
@@ -160,7 +154,7 @@ export const createConfig({
160
154
 
161
155
  ### Language field
162
156
 
163
- The schema types that use document internationalization must also have a `string` field type with the same name configured in the `languageField` setting. Unless you want content creators to be able to change the language of a document, you may hide this field since the plugin will handle writing patches to it.
157
+ The schema types that use document internationalization must also have a `string` field type with the same name configured in the `languageField` setting. Unless you want content creators to be able to change the language of a document, you may hide or disable this field since the plugin will handle writing patches to it.
164
158
 
165
159
  ```ts
166
160
  // ./schema/lesson.ts
@@ -175,44 +169,7 @@ defineField({
175
169
  })
176
170
  ```
177
171
 
178
- ## Importing plugin components
179
-
180
- Some components and functions from the plugin are exported for you to use throughout the Studio. For example, a custom Tool that lists documents but also needs to pull from available languages, create new translations, show the language of an existing document and link to the metadata document.
181
-
182
- ![custom-tool](https://github.com/sanity-io/document-internationalization/assets/9684022/66c1cd3d-a964-4632-b57c-998a49a2c9b6)
183
-
184
- ### useDocumentInternationalizationContext
185
-
186
- The `useDocumentInternationalizationContext` hook can be used to access all plugin configuration values, including the result of `supportedLanguages` if it is an async function.
187
-
188
- ```tsx
189
- import {useDocumentInternationalizationContext} from '@sanity/document-internationalization'
190
-
191
- export function MyComponent({doc}: {doc: SanityDocument}) {
192
- const {languageField} = useDocumentInternationalizationContext()
193
-
194
- return <Badge>{doc[languageField] ?? `No Language`}</Badge>
195
- }
196
- ```
197
-
198
- ### DocumentInternationalizationMenu
199
-
200
- The menu button shown at the top of documents can be imported anywhere and requires the published document ID of a document and its schema type to set the language of the document and handle creating new translations and the metadata document.
201
-
202
- ```tsx
203
- import {DocumentInternationalizationMenu} from '@sanity/document-internationalization'
204
-
205
- export function MyComponent({_id, _type}) {
206
- return (
207
- <DocumentInternationalizationMenu
208
- documentId={_id.replace(`drafts.`, ``)}
209
- schemaType={_type}
210
- />
211
- )
212
- }
213
- ```
214
-
215
- ## Code examples
172
+ ## Querying translations
216
173
 
217
174
  ### Querying with GROQ
218
175
 
@@ -221,12 +178,11 @@ To query a single document and all its translations, we use the `references()` f
221
178
  ```json5
222
179
  // All `lesson` documents of a single language
223
180
  *[_type == "lesson" && language == $language]{
224
- // Just these fields
225
181
  title,
226
182
  slug,
227
183
  language,
228
184
  // Get the translations metadata
229
- // And resolve the `value` field in each array item
185
+ // And resolve the `value` reference field in each array item
230
186
  "_translations": *[_type == "translation.metadata" && references(^._id)].translations[].value->{
231
187
  title,
232
188
  slug,
@@ -271,86 +227,6 @@ query GetTranslations($id: ID!) {
271
227
  }
272
228
  ```
273
229
 
274
- ### Allowing the same slug on different language versions
275
-
276
- Often your translated documents will share the same slug. You might wish to move this into the metadata document itself using the `metadataFields` option in the plugin. Alternatively, you can customize the `isUnique` function on a [slug type field](https://www.sanity.io/docs/slug-type#isUnique-**3dd89e75a768**).
277
-
278
- ```ts
279
- // Add the isUnique option to your slug field
280
- defineField({
281
- name: 'slug',
282
- type: 'slug',
283
- options: {
284
- isUnique: isUniqueOtherThanLanguage
285
- },
286
- }),
287
-
288
- // Create the function
289
- // This checks that there are no other documents
290
- // With this published or draft _id
291
- // Or this schema type
292
- // With the same slug and language
293
- export async function isUniqueOtherThanLanguage(slug: string, context: SlugValidationContext) {
294
- const {document, getClient} = context
295
- if (!document?.language) {
296
- return true
297
- }
298
- const client = getClient({apiVersion: '2023-04-24'})
299
- const id = document._id.replace(/^drafts\./, '')
300
- const params = {
301
- draft: `drafts.${id}`,
302
- published: id,
303
- language: document.language,
304
- slug,
305
- }
306
- const query = `!defined(*[
307
- !(_id in [$draft, $published]) &&
308
- slug.current == $slug &&
309
- language == $language
310
- ][0]._id)`
311
- const result = await client.fetch(query, params)
312
- return result
313
- }
314
- ```
315
-
316
- ## Deleting documents
317
-
318
- ### Deleting a single translated document
319
-
320
- By default, this plugin creates a strong reference between a document and its connected translation metadata document. Because reference integrity is maintained by the API, you cannot delete a document that has a strong reference to it. To offset this difficulty, the plugin exports a document action that will allow you to remove the translation reference from the action, before proceeding to delete the document. It is not added by default to your schema types.
321
-
322
- ![delete translation document action](https://github.com/sanity-io/document-internationalization/assets/9684022/edccb456-f6e1-4782-9602-b279e9689357)
323
-
324
- Import into your Studio's config file
325
-
326
- ```ts
327
- import {
328
- documentInternationalization,
329
- DeleteTranslationAction,
330
- } from '@sanity/document-internationalization'
331
-
332
- export default defineConfig({
333
- // ...all other config
334
- document: {
335
- actions: (prev, {schemaType}) => {
336
- // Add to the same schema types you use for internationalization
337
- if (['page'].includes(schemaType)) {
338
- // You might also like to filter out the built-in "delete" action
339
- return [...prev, DeleteTranslationAction]
340
- }
341
-
342
- return prev
343
- },
344
- },
345
- })
346
- ```
347
-
348
- ### Deleting all translations
349
-
350
- The metadata document also contains a "Delete all translations" document action which is queued by default for only that schema type. It will delete all of the documents in the `translations` array of references, as well as the metadata document itself.
351
-
352
- ![delete all translations document action](https://github.com/sanity-io/document-internationalization/assets/9684022/fda956f1-26e7-430a-aeef-1db4166e9cd6)
353
-
354
230
  ## Note on document quotas
355
231
 
356
232
  In previous versions of this plugin, translations were stored as an array of references on the actual documents. This required a base language, lead to messy transaction histories and made deleting documents difficult.
@@ -359,6 +235,17 @@ In this version of the plugin, translations of a document are stored as an array
359
235
 
360
236
  This means if you have 100 documents and they are all translated into 3 languages, you will have 400 documents. Keep this in mind for extremely high-volume datasets.
361
237
 
238
+ ## Documentation
239
+
240
+ For more advanced topics see the documentation. For installation see [Usage](#usage).
241
+
242
+ - [Upgrade from v1](./docs/00-upgrade-from-v1.md)
243
+ - [Creating translations of singleton documents](./docs/01-singleton-documents.md)
244
+ - [Importing and creating documents](./docs/02-importing-and-creating-documents.md)
245
+ - [Deleting translated documents](./docs/03-deleting-translated-documents.md)
246
+ - [Importing plugin components](./docs/04-importing-plugin-components.md)
247
+ - [Allowing the same slug on different language versions](./docs/05-allowing-the-same-slug-on-different-language-versions.md)
248
+
362
249
  ## License
363
250
 
364
251
  [MIT](LICENSE) © Sanity.io
package/lib/index.esm.js CHANGED
@@ -364,12 +364,27 @@ function LanguageManage(props) {
364
364
  id
365
365
  } = props;
366
366
  const open = useOpenInNewPane(id, METADATA_SCHEMA_NAME);
367
- return /* @__PURE__ */jsx(Button, {
368
- disabled: !id,
369
- mode: "ghost",
370
- text: "Manage Translations",
371
- icon: CogIcon,
372
- onClick: () => open()
367
+ return /* @__PURE__ */jsx(Tooltip, {
368
+ content: id ? null : /* @__PURE__ */jsx(Box, {
369
+ padding: 2,
370
+ children: /* @__PURE__ */jsx(Text, {
371
+ muted: true,
372
+ size: 1,
373
+ children: "Document has no other translations"
374
+ })
375
+ }),
376
+ fallbackPlacements: ["right", "left"],
377
+ placement: "top",
378
+ portal: true,
379
+ children: /* @__PURE__ */jsx(Stack, {
380
+ children: /* @__PURE__ */jsx(Button, {
381
+ disabled: !id,
382
+ mode: "ghost",
383
+ text: "Manage Translations",
384
+ icon: CogIcon,
385
+ onClick: () => open()
386
+ })
387
+ })
373
388
  });
374
389
  }
375
390
  function createReference(key, ref, type) {
@@ -635,15 +650,15 @@ function DocumentInternationalizationMenu(props) {
635
650
  }
636
651
  return valid;
637
652
  }, [supportedLanguages]);
638
- const content = /* @__PURE__ */jsx(Card, {
653
+ const content = /* @__PURE__ */jsx(Box, {
654
+ padding: 1,
639
655
  children: error ? /* @__PURE__ */jsx(Card, {
640
656
  tone: "critical",
641
- padding: 2,
657
+ padding: 1,
642
658
  children: /* @__PURE__ */jsx(Text, {
643
659
  children: "There was an error returning translations metadata"
644
660
  })
645
661
  }) : /* @__PURE__ */jsxs(Stack, {
646
- padding: 1,
647
662
  space: 1,
648
663
  children: [/* @__PURE__ */jsx(LanguageManage, {
649
664
  id: metadata == null ? void 0 : metadata._id