번역
임의의 공급자 API를 사용하여 필드 값을 번역하는 디렉티브 @strTranslate.
설명
String 타입의 임의 필드에 디렉티브 @strTranslate를 추가하면 해당 필드를 원하는 언어로 번역할 수 있습니다.
예를 들어, 다음 쿼리는 게시물의 title 필드와 excerpt 필드를 영어에서 프랑스어로 번역합니다(기본 API 공급자 사용):
{
posts {
enTitle: title
frTitle: title @strTranslate(from: "en", to: "fr")
enExcerpt: excerpt
frExcerpt: excerpt @strTranslate(from: "en", to: "fr")
}
}...결과로 다음이 생성됩니다:
{
"data": {
"posts": [
{
"enTitle": "Welcome to a single post full of blocks!",
"frTitle": "Bienvenue dans un poste unique plein de blocs !",
"enExcerpt": "When I look back on my past and think how much time I wasted on nothing, how much time has been lost in futilities, errors, laziness, incapacity to live; how little I appreciated it, how many times I sinned against my heart and soul-then my heart bleeds. Life is a gift, life is happiness, every…",
"frExcerpt": "Quand je repense à mon passé et que je pense au temps que j'ai perdu pour rien, au temps perdu en futilités, en erreurs, en paresse, en incapacité de vivre ; combien je l'ai peu apprécié, combien de fois j'ai péché contre mon cœur et mon âme, alors mon cœur saigne. La vie est un cadeau, la vie est un bonheur, chaque…"
},
{
"enTitle": "Explaining the privacy policy",
"frTitle": "Expliquer la politique de confidentialité",
"enExcerpt": "Our privacy policy is at https://gato-graphql-pro.lndo.site/privacy/, and we are based in Carimano.",
"frExcerpt": "Notre politique de confidentialité se trouve sur https://gato-graphql-pro.lndo.site/privacy/, et nous sommes basés à Carimano."
},
{
"enTitle": "HTTP caching improves performance",
"frTitle": "La mise en cache HTTP améliore les performances",
"enExcerpt": "Categories Block Latest Posts Block Did you know? We are not rich by what we possess but by what we can do without. Patience is the strength of the weak, impatience is the weakness of the strong.",
"frExcerpt": "Catégories Bloquer les derniers messages Bloquer Le saviez-vous ? Nous ne sommes pas riches de ce que nous possédons mais de ce dont nous pouvons nous passer. La patience est la force du faible, l'impatience est la faiblesse du fort."
}
]
}
}Schema Configuration
디렉티브 @strTranslate에는 세 가지 인수가 필요합니다:
provider: 번역에 사용할 공급자from: 텍스트의 언어 코드to: 번역할 대상 언어 코드
설정 페이지의 「Schema Configuration => Translation」 탭에서 이러한 속성의 기본값을 정의할 수 있습니다. 쿼리에서 해당 인수가 제공되지 않은 경우 이 값이 사용됩니다:
{
posts {
title @strTranslate
}
}또한, 기본값을 정의하면 GraphQL 스키마에서 해당 인수가 필수가 아닌 것으로 바뀝니다.
기본적으로 from의 기본값은 WordPress에서 사용되는 언어입니다.
설정을 통한 방법
설정 페이지의 해당 입력란에 provider/from/to 필드를 입력하고 「Save Changes (All)」을 클릭합니다:

wp-config.php에서의 설정
wp-config.php에 상수를 추가합니다:
GATOGRAPHQL_TRANSLATION_DEFAULT_PROVIDERGATOGRAPHQL_TRANSLATION_DEFAULT_FROM_LANG_CODEGATOGRAPHQL_TRANSLATION_DEFAULT_TO_LANG_CODE
예:
define( 'GATOGRAPHQL_TRANSLATION_DEFAULT_TO_LANG_CODE', 'fr' );환경 변수를 통한 방법
다음 환경 변수를 정의합니다:
TRANSLATION_DEFAULT_PROVIDERTRANSLATION_DEFAULT_FROM_LANG_CODETRANSLATION_DEFAULT_TO_LANG_CODE
동기/비동기 다국어 번역
디렉티브 @strTranslate는 번역할 언어마다 요청을 전송합니다. 여러 언어로 번역할 때 요청을 비동기적(즉, 병렬)으로 전송할지, 동기적(즉, 순차적)으로 전송할지 선택할 수 있습니다.
동기 요청 대 비동기 요청:
- 동기: 각 번역 요청은 이전 요청이 완료된 후 시작됩니다. 느리지만 속도 제한에 더 안전합니다.
- 비동기: 모든 번역 요청이 동시에 전송됩니다. 빠르지만 한 번에 너무 많은 요청이 전송되면 속도 제한에 도달할 수 있습니다.

요청 타임아웃 및 연결 타임아웃
서드파티 공급자를 통해 긴 문서를 번역하는 것은 시간이 걸릴 수 있으며, 상위 서버가 응답하지 않으면 PHP 자체가 요청을 종료할 때까지 PHP 워커를 점유하게 됩니다.
웹 서버는 max_execution_time 디렉티브(php.ini에서 설정하거나 호스팅 제어판에서 설정 — cPanel에서는 일반적으로 「Select PHP Version」→「Options」 에서 확인할 수 있으며, SiteGround / Kinsta Engine 같은 매니지드 호스트에서는 PHP 설정에서 확인할 수 있습니다)를 통해 모든 PHP 요청의 최대 실행 시간을 적용합니다.
이 플러그인은 설정 페이지의 Plugin Configuration > Translation 아래에 두 가지 옵션을 제공합니다:
- Request timeout: 번역 공급자로부터 전체 응답을 기다리는 최대 시간(초 단위)
- Connection timeout: 번역 공급자에 연결을 설정하는 데 기다리는 최대 시간(초 단위)

이 값들은 서버의 max_execution_time보다 낮게 유지해야 합니다. 그렇게 하면 번역이 중단된 경우 일반적인 서버 타임아웃(HTTP 502 / 504, 또는 「Maximum execution time of N seconds exceeded」 빈 페이지)이 발생하는 대신 제어된 오류 메시지와 함께 정상적으로 실패합니다. 번역이 정기적으로 타임아웃되는 경우 이 두 값과 서버의 max_execution_time을 함께 늘려 주세요.
API 요청 디버깅
번역 공급자(ChatGPT, Claude, Google Translate 등)에 전송되는 요청과 응답을 디버깅하려면 로그 설정에서 🔵 Info 심각도 수준을 활성화하세요.
활성화하면 로그에 번역 공급자와의 모든 상호작용이 api-requests 항목 아래에 저장됩니다.

로그에 기록되는 내용
AI 공급자의 경우 api-requests 항목에는 다음에 대한 자세한 정보가 포함됩니다:
- 번역 공급자에 전송된 프롬프트
- 수신된 전체 응답
- 통신 중 발생한 오류나 문제
- 사용된 모델
- 사용된 토큰 수

예를 들어, 다음 「Additional context」 JSON은 ChatGPT에 전송된 요청과 그 응답의 세부 정보를 보여줍니다:
{
"request": {
"model": "gpt-4o-mini",
"messages": [
{
"role": "system",
"content": "You are a language translator."
},
{
"role": "user",
"content": "I'm working on internationalizing my application.\n\nI've created a JSON with sentences in English. Please translate the sentences to Spanish from .\n\nIf a sentence contains HTML, do not translate inside the HTML tags. Keep emojis exactly as they are, do not translate them.\n\nThis is the JSON:\n\n[\"Welcome to a single post full of blocks!\",\"Repeating the privacy policy\",\"Explaining the privacy policy\",\"HTTP caching improves performance\",\"Public or Private API mode, for extra security\",\"GraphQL or REST? Why not both?\",\"Customize the schema for each client\",\"Nested mutations are a must have\",\"Working on flat chain syntax next\",\"Released v0.6, check it out\"]"
}
],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "translation_response",
"strict": true,
"schema": {
"type": "object",
"properties": {
"translations": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"translations"
],
"additionalProperties": false
}
}
}
},
"response": {
"id": "chatcmpl-BbjNiuO5Si1vhalfIXYU0hWiCmg12",
"object": "chat.completion",
"created": 1748332282,
"model": "gpt-4o-mini-2024-07-18",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "{\"translations\":[\"¡Bienvenido a una publicación única llena de bloques!\",\"Repitiendo la política de privacidad\",\"Explicando la política de privacidad\",\"La caché HTTP mejora el rendimiento\",\"Modo API Público o Privado, para mayor seguridad\",\"¿GraphQL o REST? ¿Por qué no ambos?\",\"Personaliza el esquema para cada cliente\",\"Las mutaciones anidadas son imprescindibles\",\"Próximamente trabajando en la sintaxis de cadena plana\",\"Lanzada la versión v0.6, ¡échale un vistazo!\"]}",
"refusal": null,
"annotations": []
},
"logprobs": null,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 184,
"completion_tokens": 112,
"total_tokens": 296,
"prompt_tokens_details": {
"cached_tokens": 0,
"audio_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 0,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
}
},
"service_tier": "default",
"system_fingerprint": "fp_34a54ae93c"
}
}