gt-sanity@2.1.0
Обзор
gt-sanity v2.1 добавляет локализацию на уровне полей: вместо создания отдельного документа для каждой локали теперь можно хранить значения для всех языков в одном документе, используя интернационализированные массивы. Плагин сам генерирует типы схем, предоставляет встроенный UI для редактирования по локалям и отправляет перевод через тот же workflow GT, которым вы уже пользуетесь, — переведённые значения затем встраиваются обратно в исходный документ на месте.
Структура данных соответствует sanity-plugin-internationalized-array ([{ _key, _type, language, value }]), поэтому существующий контент с интернационализированными массивами работает без какой-либо миграции.
Что нового
Локализация на уровне полей (интернационализированный массив)
Перевод на уровне документа по-прежнему остаётся вариантом по умолчанию: для каждой локали создаётся отдельный документ, связанный через @sanity/document-internationalization. Такая модель подходит для документов, в которых всё различается в зависимости от языка.
Новая модель на уровне полей сохраняет один документ и локализует отдельные поля прямо в нём:
{
_id: 'post-123',
_type: 'post',
title: [
{ _key: 'x1', _type: 'internationalizedArrayStringValue', language: 'en', value: 'Hello' },
{ _key: 'x2', _type: 'internationalizedArrayStringValue', language: 'es', value: 'Hola' },
],
}Включите это с помощью новой опции internationalizedArray (или её более понятного псевдонима fieldLevelLocalization):
import { defineConfig } from 'sanity';
import { gtPlugin } from 'gt-sanity';
export default defineConfig({
plugins: [
gtPlugin({
sourceLocale: 'en',
locales: ['es', 'fr', 'ja'],
translateDocuments: [{ type: 'post' }],
internationalizedArray: { enabled: true },
translationLevel: 'internationalizedArray',
}),
],
});Сгенерированные типы схем
Если эта возможность включена, плагин генерирует типы схем internationalizedArray* (например, internationalizedArrayString, internationalizedArrayText) на основе тех же sourceLocale / locales, которые вы уже передаёте в gtPlugin, — локаль определяется один раз. Используйте их в своих схемах, как и любой другой тип:
defineField({
name: 'title',
type: 'internationalizedArrayString',
});fieldTypes определяет, какие типы будут генерироваться. По умолчанию используется ['string', 'text']; также поддерживается 'block' для Portable Text и пользовательские определения объектов для произвольных структур значений:
internationalizedArray: {
enabled: true,
fieldTypes: [
'string',
'text',
'block',
{ name: 'seo', type: 'seoFields' }, // генерирует internationalizedArraySeo
],
},Вы также можете настроить имена сгенерированных типов с помощью typePrefix (алиасы для совместимости под стандартными именами internationalizedArray* по умолчанию сохраняются), а также названия локалей, отображаемые в Studio, с помощью languageTitles или getLanguageTitle.
Интерфейс встроенного редактирования для каждой локали
Для сгенерированных типов предусмотрено специальное поле ввода в Studio: каждый язык отображается как встроенный редактор с подписью (без свернутых строк объектов и диалогов редактирования), с отдельными кнопками добавления и удаления для каждой локали. Исходный язык удалить нельзя.
Если вы предпочитаете использовать собственный UI, опция components позволяет переопределить слоты input, item и field — или передать false, чтобы вернуться к стандартному рендерингу Sanity. На перевод это никак не влияет, поскольку он работает с сохраненными данными, а не с компонентами.
translationLevel и смешанный режим
Генерация схемы и маршрутизация перевода не зависят друг от друга: включение internationalizedArray только добавляет редактируемые типы полей. Новый параметр translationLevel определяет, как переводятся подходящие документы:
'document'(по умолчанию) — перевод всего документа с отдельным документом для каждой локали, без изменений по сравнению с v2.0.'internationalizedArray'— все подходящие документы локализуются на месте с помощью интернационализированных массивов.'mixed'— типы документов, перечисленные вfieldLevelDocuments, используют стратегию массивов; всё остальное остаётся на уровне документа.
gtPlugin({
sourceLocale: 'en',
locales: ['es', 'fr'],
translateDocuments: [{ type: 'post' }, { type: 'siteSettings' }],
internationalizedArray: { enabled: true },
translationLevel: 'mixed',
fieldLevelDocuments: [{ type: 'siteSettings' }], // локализация на месте
});Типы документов, локализуемые на месте, автоматически исключаются из @sanity/document-internationalization, поэтому для них не отображаются языковые бейджи и не создаются шаблоны документов для каждой локали.
Импорт на месте
Документы с переводом на уровне полей проходят через тот же workflow GT, которым вы уже пользуетесь. При импорте переведённые значения записываются обратно в тот же документ: обновляется только целевая локаль, а все остальные языки — включая правки, внесённые во время выполнения перевода, — остаются без изменений.
Статусы переводов в Studio теперь тоже остаются корректными после импорта на месте и обновления страницы, а завершённые переводы больше не отображаются как «не начато».