Integrationen

Sanity (TMS)

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

Das Plug-in bietet Zugriff auf die in Phrase übersetzten Inhalte aus dem Sanity-Studio.

Nur Dokumentübersetzungen werden unterstützt. Feldübersetzungen werden nicht unterstützt.

Funktionen:

  • Echtzeit-Vorschauen

    Übersetzungen werden synchron gehalten, damit Linguisten und Übersetzer Vorschänderungen in Echtzeit sehen können.

  • Intelligente Neuübersetzungen

    Das Plug-in vergleicht, welche Inhalte sich seit der letzten Übersetzung geändert haben, und sendet nur diese Änderungen an Phrase.

  • Automatische Referenzübersetzung

    Bei der Ausgabe von Übersetzungen können Redakteure auch wählen, Dokumente zu übersetzen, die von der aktuellen Referenz und dem Plug-in automatisch mit der Zielsprache verknüpft werden.

  • Flexible Schemata

    Egal wie die Struktur ist, das Plug-in passt sich an und stellt sicher, dass der endgültige übersetzte Inhalt den Sanity-Schemata entspricht.

  • Phrase-Workflows

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

Sanity Plug-in Installation

Die Installation erfolgt über die Befehlszeile.

Es wird davon ausgegangen, dass ein Website-Generator und Sanity Studio bereits konfiguriert sind. Falls nicht, verwenden Sie eine der von Sanity bereitgestellten Starter-Vorlagen.

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 das Plug-in konfiguriert wird, müssen die folgenden Umgebungsvariablen festgelegt werden. Erstellen Sie eine `.env`-Datei (oder `.env.local` für Next.js) im Projektstamm.

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

Wichtig

Serverseitige Variablen (SANITY_WRITE_TOKEN, PHRASE_USER_NAME, PHRASE_PASSWORD) sollten niemals dem Kunden ausgesetzt werden. In Next.js sind nur Variablen, die mit NEXT_PUBLIC_ beginnen, im Browser sichtbar.

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

# URL, an der der Backend-Handler des Plug-ins zu finden sein wird
NEXT_PUBLIC_PHRASE_PLUGIN_API_ENDPOINT="http://localhost:3000/api/phrase"

# Phrase-Datacenter-Region ('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 serverseitig)
SANITY_WRITE_TOKEN=""

# Phrase-Anmeldeinformationen (nur serverseitig)
# 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 zu sanity.config.ts mit den erforderlichen Konfigurationsoptionen hinzugefügt:

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

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

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

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

  // Erforderlich: Zielsprache, in die Benutzer übersetzen können
  // Verwenden Sie dieselben Codes wie Ihre Sanity-Dokumente
  // Diese Liste muss mit den in Ihrer Phrase-Projektvorlage definierten Sprachen übereinstimmen
  supportedTargetLangs: ['es', 'fr', 'de', 'pt'],

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

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

  // Erforderlich: Phrase-Projektvorlagen, die für Redakteure verfügbar sind
  phraseTemplates: [
    {
      templateUid: 'YOUR_TEMPLATE_UID_HERE',
      label: 'Standardübersetzungsvorlage',
    },
  ],

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

  // Optionale Einstellungen

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

  // Erlauben Sie die Übersetzung von Entwurfsdokumenten (Standard: false)
  translateDrafts: false,

  // Benutzerdefinierte Daten-Transformatoren für spezielle Inhaltstypen
  dataTransformers: [],

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

  // Verstecken Sie das Phrase-Dashboard basierend auf Benutzerrollen
  isPhraseDashboardHidden: (context) =>
    !(context.currentUser.roles || []).some((r) => r.name === 'admin'),
})

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

const PHRASE_CONFIG = definePhraseOptions({
  /**
   * Der i18n-Adapter, der für dieses Plugin verwendet werden soll.
   * Er ist verantwortlich für das Abrufen und Modifizieren von Dokumenten für jede Zielsprache.
   *
   * Siehe unten für weitere Informationen zu Adaptern.
   */
  i18nAdapter: documentInternationalizationAdapter(),

  /**
   * Sanity-Schema-Typen, die das Plugin übersetzen kann
   */
  translatableTypes: ['Seite', 'Beitrag', 'Kurs', 'Lektion', 'Definition'],

  /**
   * Sprachcode aller Sprachen, in die Benutzer übersetzen können.
   * Sollte derselbe sein wie der, der in Ihren Sanity-Dokumenten gespeichert ist und von Ihrem Frontend verwendet wird. Das Plugin wird es automatisch in das Format von Phrase übersetzen.
   */
  supportedTargetLangs: ['cz', 'es', 'pt', 'fr', 'de', 'it', 'nl', 'pl', 'ru'],

  /**
   * Sprachcode der Ausgangssprache, die übersetzt werden soll.
   * Sollte derselbe sein wie der, der in Ihren Sanity-Dokumenten gespeichert ist und von Ihrem Frontend verwendet wird. Das Plugin wird es automatisch in das Format von Phrase übersetzen.
   */
  sourceLang: 'en',

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

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

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

  /**
   * Phrase-Projektvorlagen, die Ihre Redakteure bei der Anforderung von Übersetzungen verwenden können.
   *
   * **Hinweis:** Befolgen Sie die Schritte zur Einrichtung von Vorlagen, die weiter unten aufgeführt sind.
   */
  phraseTemplates: [
    {
      templateUid: '1jYg0Pc1d8kAHUyM0tgdmt',
      label: '[Sanity.io] Standardvorlage',
    },
  ],

  /**
   * @optional
   * Falls Sie das Phrase-Dashboard je nach Benutzerberechtigungen anzeigen oder ausblenden möchten.
   *
   * Erhält einen Kontext mit dem aktuellen Benutzer 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 Plugin-Konfiguration

Schema-Injektion

Um dem Plugin mitzuteilen, welche Dokumenttypen übersetzt werden können, ü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 der übersetzbaren Schema-Typen. In der Regel 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),
    vorlagen: (vorher) =>
      prev.filter((template) => !TRANSLATABLE_SCHEMAS.includes(template.id)),
  },
  plugins: [
    // ...
    phrasePlugin({
      // Ihre Konfigurationsoptionen hier
    }),
  ],
})

Ausschluss von PTDs aus Dokumentenlisten

PTDs (Phrase-Übersetzungsdokumente) sind temporäre Dokumente, die nicht in normalen Dokumentenlisten innerhalb von Sanity Studio erscheinen sollten. Die NICHT_PTD Konstante bietet einen GROQ-Filter für diesen Zweck:

// sanity.config.ts
import { NICHT_PTD } von 'sanity-plugin-phrase/utils'

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

Das Übersetzungsmenü von PTDs ausblenden

Beim Einsatz des Dokumenten-Internationalisierungs-Plugins sollte das Übersetzungsmenü von PTDs ausgeblendet werden. Das isPtdId Dienstprogramm identifiziert PTD-Dokumente:

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

// Verwende dasselbe Array wie translatableTypes aus deiner PHRASE_CONFIG
const TRANSLATABLE_TYPES = ['Seite', 'Beitrag', 'Artikel']

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

      // Zeige das Übersetzungsmenü nur für echte Dokumente, 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-Benutzeroberfläche, aber Phrase muss konfiguriert werden, um Webhook-Benachrichtigungen an den Backend-API-Endpunkt zu senden. Dies ermöglicht Echtzeit-Updates, während die Übersetzungen fortschreiten.

Erstelle einen Webhook

Erstelle einen webhook mit diesen Einstellungen:

  • URL

    Die URL zum API-Endpunkt des Plug-ins, wie im apiEndpoint Option 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 Änderungen an Phrase-Projekten informiert wird und die Sanity-Daten synchron halten kann.

Setup-Projekte Vorlage(n)

Konfigurieren Sie die Phrase Projektvorlage(n) mit den für Workflows und Teamanforderungen erforderlichen Eigenschaften. Einer oder mehrere Vorlagen können zur Auswahl angeboten werden, wenn eine neue Übersetzung bestellt wird. Phrase-Projektvorlagen müssen spezifische JSON-Importeinstellungen haben, damit das Plug-in korrekt funktioniert. Diese Einstellungen steuern, welche Felder an Übersetzer gesendet werden und welche als Metadaten erhalten bleiben.

JSON-Datei-Import

Verwenden Sie Regex, um bestimmte Keys auszuschließen:

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

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

  • Schließen Sie lokalisierungsspezifische Daten aus, wie die Sprache eines bestimmten Dokuments, wenn Sie @sanity/document-internationalization verwenden.

  • Fügen Sie alle projektspezifischen Keys hinzu, die keine Übersetzung erfordern, wie einen Slug für Inhalte, die denselben Pfad in allen Sprachen verwenden. Ersetzen Sie IHRE_IGNORIERTEN_KEYS_HIER durch eine durch Pipes getrennte Liste von Keys, die ignoriert werden sollen.

  • Context note: /_sanityContext

Ausgangssprache

Derzeit geht dieses Plug-in davon aus, dass es eine einzige Ausgangssprache gibt. Die Projektvorlage(n) müssen die gleiche Quelle wie die im Plug-in konfigurierte sourceLanguage haben.

Zielsprache(n)

Stellen Sie sicher, dass die in Phrase gewählten Sprachen mit den Konfigurationen des Plug-ins synchronisiert sind.

Sanity apiEndpoint

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

Erstellen Sie einen individuellen API-Endpunkt im Sanity-Projekt, um diese Anfragen zu bearbeiten. Eine der einfachsten Möglichkeiten, dies zu tun, besteht darin, serverlose Funktionen über Front-End-Frameworks wie NextJS, Remix, SvelteKit oder Nuxt zu verwenden.

Zugreifen Sie auf die Konfiguration des Handlers mit einem Request-Response-Muster über import {createRequestHandler} von sanity-plugin-phrase/backend oder verwenden Sie den internen Handler direkt über import {createInternalHandler} von 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-Client-Komponente analysiert.

Dieses Beispiel zeigt, wie man einen Routen-Handler am konfigurierten apiEndpoint Pfad bei /api/phrase mit dem Next.js Pages Router erstellt:

// app/api/phrase/route.ts
// Next.js API-Routenunterstützung: 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
export const dynamic = 'force-dynamic'

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

export 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: 'Methode nicht erlaubt' })
    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: [string, 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: client.withConfig({ token: writeToken }),
  pluginOptions: PHRASE_CONFIG,
})

export 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: 'Methode nicht erlaubt' })
    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 vorschreibenden Ansatz zur Internationalisierung, und es gibt viele Möglichkeiten, dies umzusetzen. 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 der einzige verfügbare Adapter documentInternationalizationAdapter, der von Sanitys offiziellem document-internationalization plugin (Version ^2.0.0) verwendet wird. Reichen Sie ein Problem ein, wenn ein spezifischer Adapter benötigt wird, oder verweisen Sie auf dieses repository's package/src/adapters/document-internationalization.ts für ein Beispiel, wie man einen benutzerdefinierten implementiert.

Benutzerdefinierte Daten-Transformatoren

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

Jeder Daten-Transformator muss die Daten vor dem Senden an Phrase kodieren und sie dekodieren, wenn sie zurückkommen, 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, sodass die Entwicklung komplex sein kann. Speichern Sie echte Ziel-Dokumente aus dem Sanity-Datensatz als .JSON und verwenden Sie sie als Testdaten für jede der Funktionen encode/decode.

Beispiel für die Modifizierung von JSON-kodierten VTT-Dateien zu HTML, damit Phrase den Inhalt von Untertiteln besser segmentieren kann:

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

const vttJsonTransformer: DataTransformer = {
  encode: {
    array(arr) {
      // Überprüfen, ob das Array VTT-Untertitelknoten enthält
      if (
        arr.jede(
          (element) =>
            typeof element === 'object' &&
            !!item &&
            '_type' in item &&
            typeof item._type === 'string' &&
            item._type.startsWith('vtt.'),
        )
      ) {
        return encodeSubtitles(arr as StoredSubtitleNode[])
      }
      return undefined // Rückgabe von undefined, um die Transformation zu überspringen
    },
  },
  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.jede(
          (element) =>
            typeof element === '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 Quellcode
declare function decodeSubtitles(
  encoded: EncodedSubtitles,
): StoredSubtitleNode[]
deklariere Funktion encodeSubtitles(Knoten: StoredSubtitleNode[]): EncodedSubtitles

Eingeschränkter Zugriff für Editor

Welche Editoren auf das Phrase-Dashboard zugreifen können, kann durch Implementierung der isPhraseDashboardHidden Option eingeschränkt werden. Diese Funktion entspricht der, die an die hidden Eigenschaft eines Feldes in Sanity übergeben wird. Sie erhält einen Kontext mit dem aktuellen Benutzer und Dokument und muss einen booleschen Wert zurückgeben.

Beispiel für die Einschränkung des Zugriffs auf das Phrase-Dashboard für Benutzer 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.