Integrationen

Sanity (TMS)

Inhalte werden von Phrase Language AI maschinell aus dem Englischen übersetzt.

Das Plug-in bietet Zugriff auf Phrase übersetzten Content aus dem Sanity Studio heraus.

Es werden nur Übersetzungen auf Dokumentebene unterstützt. Übersetzungen auf Feldebene werden nicht unterstützt.

Funktionen:

  • Echtzeit-Vorschau

    Übersetzungen werden synchron gehalten, damit Linguisten und Übersetzer Vorschau-Änderungen in Echtzeit sehen können.

  • Intelligente Neuübersetzungen

    Das Plug-in gleicht ab, welcher Content sich seit der letzten Übersetzung geändert hat, und sendet nur diese Änderungen an Phrase.

  • Automatische Referenzübersetzung

    Beim Erstellen von Übersetzungen können Editoren wählen, auch Dokumente zu übersetzen, auf die verwiesen wird, und das Plug-in verknüpft diese automatisch nach Zielsprache.

  • Flexible Schemas

    Unabhängig von der Struktur passt sich das Plug-in an und stellt sicher, dass der finale übersetzte Content den Sanity-Schemas entspricht.

  • Phrase Workflows

    Die Übersetzungs-Workflows in Phrase bleiben gleich; eine Umschulung oder Neukonfiguration der Vorgänge ist nicht erforderlich.

Sanity Plugin Installation

Die Installation erfolgt über die Befehlszeile.

Es wird vorausgesetzt, dass ein Website-Generator und Sanity Studio bereits konfiguriert sind. Falls nicht, verwenden Sie eine der Starter-Vorlagen, die von Sanity bereitgestellt werden.

Installation

Navigieren Sie zu dem Projekt, das die Sanity Studio-Instanz enthält, und installieren Sie das Plug-in:

npm install sanity-plugin-phrase

# oder pnpm, yarn, bun

Umgebungsvariablen

Bevor Sie das Plug-in konfigurieren, müssen die folgenden Umgebungsvariablen festlegen werden. Erstellen Sie eine `.env`-Datei (oder `.env.local` für Next.js) im Projekt-Stammverzeichnis.

Die folgenden Beispiele beziehen sich auf NextJS. Für andere Frameworks lesen Sie bitte deren spezifische Dokumentation und beachten Sie, dass das Präfix `NEXT_PUBLIC_` für öffentliche Variablen möglicherweise entfernt werden muss.

Wichtig

Server-seitige Variablen (SANITY_WRITE_TOKEN, PHRASE_USER_NAME, PHRASE_PASSWORD) sollten niemals dem Kunde gegenüber offengelegt werden. In Next.js werden nur Variablen mit dem Präfix NEXT_PUBLIC_ im Browser offengelegt.

# Basis-URL Ihrer Website (wird für Vorschau-Links verwendet)
NEXT_PUBLIC_BASE_URL="http://localhost:3000"

# URL, unter der sich der Plug-in-Backend-Handler befinden wird
NEXT_PUBLIC_PHRASE_PLUGIN_API_ENDPOINT="http://localhost:3000/api/phrase"

# Phrase-Rechenzentrumsregion ('eu' oder 'us')
NEXT_PUBLIC_PHRASE_REGION="eu"

# Sanity-Projektkonfiguration
NEXT_PUBLIC_SANITY_PROJECT_ID="your-project-id"
NEXT_PUBLIC_SANITY_DATASET="production"

# Sanity-API-Token mit Schreibberechtigungen (nur Server-seitig)
SANITY_WRITE_TOKEN=""

# Phrase-Anmeldeinformationen (nur Server-seitig)
# Hinweis: Die Phrase-API erwartet nur den Benutzernamen, NICHT die vollständige E-Mail-Adresse
PHRASE_USER_NAME="phraseUsername"
PHRASE_PASSWORD="secretPassword"

Plug-in-Konfiguration

Das Plug-in wird sanity.config.ts mit den erforderlichen Konfigurationsoptionen hinzugefügt:

// sanity.config.ts
importieren { defineConfig } from 'sanity'
importieren {
  phrasePlugin,
  definePhraseOptions,
  documentInternationalizationAdapter,
} from 'sanity-plugin-phrase'

const PHRASE_CONFIG = definePhraseOptions({
  // Erforderlich: i18n-Adapter für Dokument-Internationalisierung
  i18nAdapter: documentInternationalizationAdapter(),

  // Erforderlich: Dokument-Typen, die übersetzt werden können
  translatableTypes: ['page', 'post', 'article'],

  // Erforderlich: Ausgangssprache (Primärsprache)
  // Dies muss mit der Sprache übereinstimmen, die in Ihrer Phrase-Projekt-Vorlage definiert ist
  sourceLang: 'en',

  // Erforderlich: Zielsprachen, in die Benutzer übersetzen können
  // Verwenden Sie dieselben Codes wie für Ihre Sanity-Dokumente
  // Diese Liste muss mit den Sprachen übereinstimmen, die in Ihrer Phrase-Projekt-Vorlage definiert sind
  supportedTargetLangs: ['es', 'fr', 'de', 'pt'],

  // Erforderlich: Ihre Backend-API-Endpunkt-URL
  apiEndpoint: process.env.NEXT_PUBLIC_PHRASE_PLUGIN_API_ENDPOINT!,"

  // Erforderlich: Phrase-Rechenzentrumsregion ('eu' oder 'us')
  phraseRegion: process.env.NEXT_PUBLIC_PHRASE_REGION as 'eu' | 'us',

  // Erforderlich: Phrase-Projekt-Vorlagen, die für Editoren verfügbar sind
  phraseTemplates: [
    {
      templateUid: 'YOUR_TEMPLATE_UID_HERE',
      label: 'Default Translation Vorlage',
    },
  ],

  // Erforderlich: Generieren Sie Vorschau-URLs für Linguisten
  getDocumentPreview: (doc, sanityClient) => {
    const publishedID = doc._ID.Ersetzen('drafts.', '')
    return `${process.env.NEXT_PUBLIC_BASE_URL}/api/draft?id=${publishedId}`
  },

  // Optionale Einstellungen

  // Maximale Tiefe für das Übersetzen referenzierter Dokumente (Standard: 3)
  maxReferencesDepth: 3,

  // Übersetzung von Entwurfsdokumenten erlauben (Standard: false)
  translateDrafts: false,

  // benutzerdefinierte Datentransformatoren für spezielle Content-Typen
  dataTransformers: [],

  // Protokollierungskonfiguration für das Debugging
  logger: {
    minimumLogLevel: 'info', // 'debug' | 'info' | 'warning' | 'error' | 'fatal'
  },

  // Phrase Dashboard basierend auf User-Rollen Ausblenden
  isPhraseDashboardHidden: (context) =>
    !(context.currentUser.roles || []).some((r) => r.name === 'admin'),
})

export default defineConfig({
  // ... Ihre bestehende Konfiguration
  plugins: [
    phrasePlugin(PHRASE_CONFIG),
    // ... andere Plug-ins
  ],
})// sanity.config.(js|ts)
importieren {
  phrasePlugin,
  documentInternationalizationAdapter,
} from 'sanity-plugin-phrase'

const PHRASE_CONFIG = definePhraseOptions({
  /**
   * Der i18n-Adapter, der für dieses Plug-in zu verwenden ist.
   * Er ist für das Abrufen und Ändern von Dokumenten für jede Zielsprache verantwortlich.
   *
   * Weitere Informationen zu Adaptern finden Sie unten.
   */
  i18nAdapter: documentInternationalizationAdapter(),

  /**
   * Sanity-Schematypen, die das Plug-in übersetzen kann
   */
  translatableTypes: ['page', 'post', 'course', 'lesson', 'definition'],

  /**
   * Sprachcode aller Sprachen, in die Benutzer übersetzen können.
   * Sollte mit dem in Ihren Sanity-Dokumenten gespeicherten und von Ihrem Front-End verwendeten Code übereinstimmen. Das Plug-in übersetzt es automatisch in das Format von Phrase.
   */
  supportedTargetLangs: ['cz', 'es', 'pt', 'fr', 'de', 'it', 'nl', 'pl', 'ru'],

  /**
   * Sprachcode der Ausgangssprache, die übersetzt werden soll.
   * Sollte mit dem in Ihren Sanity-Dokumenten gespeicherten und von Ihrem Front-End verwendeten Code übereinstimmen. Das Plug-in übersetzt es automatisch in das Format von Phrase.
   */
  sourceLang: 'en',

  /**
   * Wie in den Einstellungen Ihres Phrase-User-Kontos definiert
   * Entweder `eu` oder `us`
   */
  phraseRegion: 'us|eu',

  /**
   * Die URL zu Ihrer konfigurierten Plug-in-Backend-API.
   *
   * **Hinweis:** Befolgen Sie die unten aufgeführten Schritte zur Einrichtung des Endpunkts.
   */
  apiEndpoint: 'https://my-site.com/api/phrase',

  /**
   * Wird verwendet, um Linguisten vom Phrase-Dashboard zur Front-End-Vorschau ihrer Übersetzungen weiterzuleiten.
   */
  getDocumentPreview: async (doc, sanityClient) => {
    const publishedID = doc._ID.Ersetzen('drafts.', '')
    return `${process.env.NEXT_PUBLIC_FRONT_END_URL}/api/draft?publishedId=${publishedId}`
  },

  /**
   * Phrase-Projekt-Vorlagen, die Ihre Redakteure beim Anfordern von Übersetzungen verwenden können.
   *
   * **Hinweis:** Befolgen Sie die unten aufgeführten Schritte zum Festlegen von Vorlagen.
   */
  phraseTemplates: [
    {
      templateUid: '1jYg0Pc1d8kAHUyM0tgdmt',
      label: '[Sanity.io] Default Vorlage',
    },
  ],

  /**
   * @optional
   * Falls Sie das Phrase Dashboard gemäß User-Berechtigungen anzeigen oder ausblenden möchten.
   *
   * Empfängt einen Kontext mit dem aktuellen User und Dokument und muss einen booleschen Wert zurückgeben.
   */
  isPhraseDashboardHidden: (context) =>
    !(context.currentUser.roles || []).some((r) => r.name === 'admin'),
})

export default defineConfig({
  // ...
  plugins: [
    // ...
    phrasePlugin(PHRASE_CONFIG),
  ],
})

Sanity Plug-in Konfiguration

Schema-Injektion

Um dem Plug-in mitzuteilen, welche Dokumenttypen übersetzbar sind, übergeben Sie ein Array von Dokumenttypen an die injectPhraseIntoSchema Funktion in der sanity.config.ts Datei:

// sanity.config.ts
import { injectPhraseIntoSchema } from 'sanity-plugin-phrase'

// Liste übersetzbarer Schematypen. Normalerweise aus einer Indexdatei exportiert
// wo auch immer sich Ihr Sanity-Schema befindet
const TRANSLATABLE_SCHEMAS = ['page', 'post', 'course', 'lesson', 'definition']

export default defineConfig({
  schema: {
    types: injectPhraseIntoSchema(TRANSLATABLE_SCHEMAS, PHRASE_CONFIG),
    templates: (prev) =>
      prev.filtern((template) => !TRANSLATABLE_SCHEMAS.includes(template.id)),
  },
  plugins: [
    // ...
    phrasePlugin({
      // Ihre Konfigurationsoptionen hier
    }),
  ],
})

Ausschluss von PTDs aus Dokumentlisten

PTDs (Phrase Translation Documents) sind temporäre Dokumente, die nicht in normalen Dokumentlisten innerhalb von Sanity Studio erscheinen sollten. Die NOT_PTD Konstante stellt zu diesem Zweck einen GROQ-filter bereit:

// sanity.config.ts
import { NOT_PTD } from 'sanity-plugin-phrase/utils'

export default defineConfig({
  // ... andere Konfiguration
  plugins: [
    structureTool({
      structure: (S) =>
        S.list()
          .title('Content')
          .items([
            S.listItem()
              .title('Posts')
              .schemaType('post')
              .child(
                S.documentList()
                  .title('Posts')
                  .filter(`_type == "post" && ${NOT_PTD}`),
              ),
            // ... andere Elemente
          ]),
    }),
  ],
})

Ausblenden des Übersetzungsmenüs von PTDs

Bei der Verwendung des Dokument-Internationalisierungs-Plug-ins sollte das Übersetzungsmenü vor PTDs verborgen werden. Das isPtdId Dienstprogramm identifiziert PTD-Dokumente:

import { isPtdId } from 'sanity-plugin-phrase/utils'
importieren { DocumentInternationalizationMenu } from '@sanity/document-internationalization'

// Verwenden Sie dasselbe Array wie translatableTypes aus Ihrer PHRASE_CONFIG
const TRANSLATABLE_TYPES = ['page', 'post', 'article']

export default defineConfig({
  Dokument: {
    unstable_languageFilter: (prev, ctx) => {
      const { schemaType, documentId } = ctx

      // Nur Übersetzungsmenü für echte Dokumente anzeigen, nicht für PTDs
      return TRANSLATABLE_TYPES.includes(schemaType) &&
        documentId &&
        !isPtdId(documentId)
        ? [...prev, DocumentInternationalizationMenu]
        : prev
    },
  },
})

Phrase Konfiguration

Das Plug-in hat keine Konfiguration in der Phrase UI, aber Phrase muss so konfiguriert werden, dass Webhook-Benachrichtigungen an den Backend-API-Endpunkt gesendet werden. Dies ermöglicht Echtzeit-Aktualisierungen, während der Fortschritt der Übersetzungen voranschreitet.

Webhook erstellen

Einen Webhook mit diesen Einstellungen erstellen:

  • URL

    Die URL zum API-Endpunkt des Plug-ins, wie in der Option apiEndpoint konfiguriert.

  • Veranstaltungen:

    • Jobs

      • Job gelöscht

      • Job assigned

      • Fälligkeitsdatum des Jobs geändert

      • Job-Ziel aktualisiert

    • Projekte

      • Projekt gelöscht

      • Fälligkeitsdatum des Projekts geändert

    • Andere

      • Vorübersetzung abgeschlossen

Dies stellt sicher, dass das Plug-in über alle Änderungen an Phrase-Projekten benachrichtigt wird und Sanity-Daten synchron halten kann.

Projektvorlage(n) einrichten

Konfigurieren Sie Phrase-Projektvorlage(n) mit den Eigenschaften, die für Workflows und Team-Anforderungen erforderlich sind. Es können eine oder mehrere Vorlagen zur Auswahl angeboten werden, wenn eine neue Übersetzung in Auftrag gegeben wird. Phrase-Projektvorlagen müssen über spezifische JSON-Importeinstellungen verfügen, damit das Plug-in korrekt funktioniert. Diese Einstellungen steuern, welche Felder an Übersetzer gesendet und welche als Metadaten beibehalten werden.

JSON-Datei importieren

Regex verwenden, um bestimmte Keys auszuschließen:

(^|.*\/)
(_createdAt|_id|_rev|_type|_updatedAt|_ref|_key|_sanityRev|_sanityContext|_strengthenOnPublish|phraseMetadata|_spanMeta|_blockMeta|_diff|marks|YOUR_IGNORED_KEYS_HERE|
(_createdAt|_id|_rev|_type|_updatedAt|_ref|_key|_sanityRev|_sanityContext|_strengthenOnPublish|phraseMetadata|_spanMeta|_blockMeta|_diff|marks|YOUR_IGNORED_KEYS_HERE)
/.*)

Dieser Ausdruck enthält absichtlich duplizierte Keys, um sicherzustellen, dass sie vom RegEx-Parser von Phrase ignoriert werden. Stellen Sie sicher, dass sie korrekt dupliziert sind.

  • Lokalisierungsspezifische Daten ausschließen, wie die Sprache eines bestimmten Dokuments, wenn @sanity/document-internationalization verwendet wird.

  • Projektspezifische Keys einschließen, die keine Übersetzung erfordern, wie z. B. ein Slug für Content, der in allen Sprachen denselben Pfad verwendet. Ersetzen Sie YOUR_IGNORED_KEYS_HERE durch eine durch Pipes getrennte Liste von Keys, die ignoriert werden sollen.

  • Context note: /_sanityContext

Ausgangssprache

Derzeit geht dieses Plug-in von der Annahme aus, dass eine einzelne Ausgangssprache vorhanden ist. Die Projekt-Vorlage(n) müssen dieselbe Ausgangssprache haben wie die im sourceLanguage des Plug-ins konfigurierte.

Zielsprachen

Stellen Sie sicher, dass die in Phrase ausgewählten Sprachen mit denen in der Konfiguration des Plug-ins synchron sind.

Sanity apiEndpoint

Dies ist der Endpunkt, den das Plug-in verwendet, um mit dem Sanity Studio zu kommunizieren. Er wird verwendet, um sich bei der API von Phrase zu authentifizieren sowie Webhooks und User-Anfragen aus dem Sanity Studio zu empfangen.

Erstellen Sie einen Individuellen API-Endpunkt im Sanity-Projekt, um diese Anfragen zu verarbeiten. Eine der einfachsten Möglichkeiten hierfür ist die Verwendung von serverlosen Funktionen über Front-End-Frameworks wie NextJS, Remix, SvelteKit oder Nuxt.

Zugreifen konfigurieren Sie den Handler mit einem Request-Response-Muster über import {createRequestHandler} from sanity-plugin-phrase/backend oder verwenden Sie den internen Handler direkt über import {createInternalHandler} from sanity-plugin-phrase/backend. Stellen Sie sicher, dass CORS-Anfragen korrekt behandelt werden, da das Studio und der Endpunkt unterschiedliche Ursprünge haben.

Das App-Verzeichnis von NextJS wird derzeit nicht unterstützt, da es den Backend-Handler fälschlicherweise als React-Kunde-Komponente parst.

Dieses Beispiel demonstriert das Erstellen eines Route-Handlers unter dem konfigurierten apiEndpoint-Pfad unter /api/phrase unter Verwendung des Next.js Pages Routers:

// app/api/phrase/route.ts
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from 'next'
import { PHRASE_CONFIG } from 'phraseConfig'
import { createInternalHandler } from 'sanity-plugin-phrase/backend'

import { writeToken } from '~/lib/sanity.api'
import { client } from '~/lib/sanity.client'

export const maxDuration = 60
exportieren const dynamic = 'force-dynamic'

const phraseHandler = createInternalHandler({
  phraseCredentials: {
    userName: process.env.PHRASE_USER_NAME || '',
    password: process.env.PHRASE_PASSWORD || '',
  },
  sanityClient: Kunde.withConfig({ Token: writeToken }),
  pluginOptions: PHRASE_CONFIG,
})

exportieren default async function handler(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  res.setHeader('Access-Control-Allow-Origin', '*')
  res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS')
  res.setHeader('Access-Control-Allow-Headers', '*')

  if (req.method?.toUpperCase() === 'OPTIONS') {
    res.status(200).json({})
    return
  }

  if (
    !req.method ||
    (req.method.toUpperCase() !== 'POST' && req.method.toUpperCase() !== 'GET')
  ) {
    res.status(405).json({ error: 'Method not allowed' })
    return
  }

  const phraseRes = await phraseHandler(
    req.method.toUpperCase() === 'POST' ? req.body : req.query,
  )
  const resBody = await phraseRes.json().catch(() => {})

  Array.from(phraseRes.headers.entries()).forEach((value: [Zeichenfolge, any]) => {
    res.setHeader(value[0], value[1])
  })
  res.status(phraseRes.status).json(resBody)
}// src/pages/API/Phrase.ts
// Next.js API route: https://nextjs.org/docs/pages/building-your-application/routing/api-routes
import type { NextApiRequest, NextApiResponse } from 'next'
import { PHRASE_CONFIG } from 'phraseConfig'
import { createInternalHandler } from 'sanity-plugin-phrase/backend'
import { writeToken } from '~/lib/sanity.api'
import { client } from '~/lib/sanity.client'

const phraseHandler = createInternalHandler({
  phraseCredentials: {
    userName: process.env.PHRASE_USER_NAME || '',
    password: process.env.PHRASE_PASSWORD || '',
  },
  sanityClient: Kunde.withConfig({ Token: writeToken }),
  pluginOptions: PHRASE_CONFIG,
})

exportieren default async function handler(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  res.setHeader('Access-Control-Allow-Origin', '*')
  res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS')
  res.setHeader('Access-Control-Allow-Headers', '*')

  if (req.method?.toUpperCase() === 'OPTIONS') {
    res.status(200).json({})
    return
  }

  if (
    !req.method ||
    (req.method.toUpperCase() !== 'POST' && req.method.toUpperCase() !== 'GET')
  ) {
    res.status(405).json({ error: 'Method not allowed' })
    return
  }

  const phraseRes = await phraseHandler(
    req.method.toUpperCase() === 'POST' ? req.body : req.query,
  )
  const resBody = await phraseRes.json().catch(() => {})

  Array.from(phraseRes.headers.entries()).forEach((value) => {
    res.setHeader(value[0], value[1])
  })
  res.status(phraseRes.status).json(resBody)
}

i18n-Adapter

Sanity hat keinen präskriptiven Ansatz für die Internationalisierung, und es gibt viele Möglichkeiten, diese zu implementieren. Dieses Plug-in verwendet ein Adaptermuster, um eine Konfiguration basierend darauf zu ermöglichen, wie der Content strukturiert ist und wie er übersetzt werden soll.

Derzeit ist nur der Adapter documentInternationalizationAdapter verfügbar, der von Sanitys offiziellem document-internationalization Plug-in (Version ^2.0.0) verwendet wird. Erstellen Sie ein Problem, falls ein spezifischer Adapter erforderlich ist, oder beziehen Sie sich auf dieses Repository-Paket/src/adapters/document-internationalization.ts für ein Beispiel zur Implementierung eines benutzerdefiniert-en Adapters.

Benutzerdefiniert-e Datentransformatoren

Wenn eine Transformation der Daten vor dem Senden an Phrase erforderlich ist, verwenden Sie die Option dataTransformers. Dies ist nützlich, wenn die Struktur der Daten geändert werden soll oder wenn bestimmte Felder von der Übersetzung ausgeschlossen werden sollen.

Jeder Datentransformator muss die Daten kodieren, bevor sie an Phrase gesendet werden, und sie dekodieren, wenn sie zurückerhalten werden, um sie vor dem speichern in Sanity zu transformieren. Mehrere Transformatoren können gestapelt und nacheinander ausgeführt werden.

Das Plug-in bietet keine Möglichkeit, Transformatoren isoliert zu testen, daher kann die Entwicklung komplex sein. Speichern Sie echte Zielsprache-Dokumente aus dem Sanity-Datensatz als .JSON und verwenden Sie diese als Testdaten für jede Kodierungs-/Dekodierungsfunktion.

Beispiel für die Modifizierung von JSON-kodierten VTT-Dateien in HTML, damit Phrase das Content der Untertitel besser segmentieren kann:

import { DataTransformer } from 'sanity-plugin-phrase'

const vttJsonTransformer: DataTransformer = {
  encode: {
    array(arr) {
      // Prüfen, ob das Array VTT-Untertitelknoten enthält
      if (
        arr.every(
          (item) =>
            typeof item === 'object' &&
            !!item &&
            '_type' in item &&
            typeof item._type === 'string' &&
            item._type.startsWith('vtt.'),
        )
      ) {
        return encodeSubtitles(arr as StoredSubtitleNode[])
      }
      return undefined // Return undefined to skip transformation
    },
  },
  decode: {
    object(obj) {
      if (!!obj && '_type' in obj && obj._type === 'encodedSubtitles') {
        return decodeSubtitles(obj as EncodedSubtitles)
      }
      return undefined
    },
  },
}

export const PHRASE_CONFIG = definePhraseOptions({
  // ...
  dataTransformers: [vttJsonTransformer],
})export const PHRASE_CONFIG = definePhraseOptions({
  // ...
  dataTransformers: [vttJsonTransformer],
})

const vttJsonTransformer: DataTransformer = {
  encode: {
    array(arr) {
      if (
        arr.every(
          (item) =>
            typeof item === 'object' &&
            !!item &&
            '_type' in item &&
            typeof item._type === 'string' &&
            item._type.startsWith('vtt.'),
        )
      ) {
        return encodeSubtitles(arr as StoredSubtitleNode[])
      }

      return undefined
    },
  },
  decode: {
    object(obj) {
      if (!!obj && '_type' in obj && obj._type === 'encodedSubtitles') {
        return decodeSubtitles(obj as EncodedSubtitles)
      }

      return undefined
    },
  },
}

// Implementierung überspringen
// Siehe /demo-nextjs/src/utils/vttJsonTransformer.ts für den vollständigen Ausgangssprache-Code
declare function decodeSubtitles(
  encoded: EncodedSubtitles,
): StoredSubtitleNode[]
declare function encodeSubtitles(nodes: StoredSubtitleNode[]): EncodedSubtitles

Einschränken des Editor-zugreifen

Welche Editoren auf das Phrase Dashboard zugreifen können, lässt sich durch die Implementierung der Option isPhraseDashboardHidden einschränken. Diese Funktion entspricht derjenigen, die an die hidden-Eigenschaft eines Feldes in Sanity übergeben wird. Sie empfängt einen Kontext mit dem aktuellen User und Dokument und muss einen booleschen Wert zurückgeben.

Beispiel für die Einschränkung des Zugriffs auf das Phrase Dashboard für User mit der Admin-Rolle:

const PHRASE_CONFIG = definePhraseOptions({
  // ...
  isPhraseDashboardHidden: (context) => {
    const isAdmin = (context.currentUser.roles || []).some(
      (r) => r.name === 'admin',
    )
    // Ausblenden, wenn kein Admin
    return !isAdmin
  },
})
War dieser Beitrag hilfreich?

Sorry about that! In what way was it not helpful?

The article didn’t address my problem.
I couldn’t understand the article.
The feature doesn’t do what I need.
Other reason.

Note that feedback is provided anonymously so we aren't able to reply to questions.
If you'd like to ask a question, submit a request to our Support team.
Thank you for your feedback.