기능플러그인가격리소스
언어 변경
리소스msgctxt 사용하기: Gettext 번역에 맥락 추가하기

msgctxt 사용하기: Gettext 번역에 맥락 추가하기

SimplePoTranslate Team2026년 5월 15일
msgctxt 사용하기: Gettext 번역에 맥락 추가하기

영어 단어 "Book"을 독일어로 번역했는데, 번역가가 자신 있게 "Buch"라고 돌려줬습니다. 3주 후 버그 보고서가 도착합니다. 예약 양식의 "Book a table" 버튼이 이제 "Buch a table"이라고 표시됩니다. 명사(noun)형이지 동사(verb)형이 아닙니다. 단어는 맞았지만, 맥락이 누락된 것입니다. 이것은 소프트웨어 현지화에서 가장 흔한 조용한 실패 중 하나이며, Gettext에는 수십 년 동안 그 해결책이 존재해 왔습니다: msgctxt.

하나의 영어 문자열이 한 곳에서는 올바르고 다른 곳에서는 의미 없는 번역을 배포한 적이 있다면, 모호성 문제에 부딪힌 것입니다. 동일한 원본 단어가 나타나는 위치에 따라 다른 번역으로 매핑됩니다. msgctxt가 없으면 번역가(사람 또는 AI)는 이 경우들을 구분할 방법이 없습니다. 그들이 보는 것은 오직 msgid "Book"이라는 문자열뿐이기 때문입니다. 이 가이드는 Gettext에서 msgctxt가 어떻게 작동하는지, _x()_ex()를 사용하여 소스 코드를 어떻게 마크업하는지, .po 파일에 어떻게 나타나는지, 그리고 맥락을 인지하는 번역 파이프라인이 이러한 문자열을 대규모로 올바르게 처리하는 유일한 신뢰할 수 있는 방법인 이유를 설명합니다.

모호성 문제: 한 단어, 여러 의미

자연어는 단일 영어 토큰으로 축약되지만 다른 언어에서는 여러 단어로 나뉘는 단어로 가득합니다. 번역가는 원본 문자열만 보기 때문에, 서로 관련 없는 두 UI 요소가 동일한 영어 단어를 공유하면 같은 msgid를 공유하게 되고, Gettext는 이를 하나의 항목으로 병합합니다.

언어마다 나뉘는 단어들

세 가지 대표적인 예를 살펴보겠습니다:

  • "Book" - 명사(선반 위의 물건) 대 동사("비행기를 예약하다"). 독일어: Buchbuchen.
  • "Post" - 콘텐츠 게시 대 우편물 발송. 프랑스어: publiercourrier.
  • "Order" - 순서/정렬 대 구매. 스페인어: ordenpedido.

영어에서는 코드에서 두 곳 모두 동일한 문자열 리터럴을 사용합니다:

// Somewhere in a library catalog screen
echo __( 'Book', 'mytextdomain' );

// Somewhere in a reservation form button
echo __( 'Book', 'mytextdomain' );

동일한 문자열이 하나의 항목으로 병합되는 방식

wp i18n make-pot 또는 xgettext를 실행하면, 두 호출 모두 하나의 .po 항목으로 병합됩니다:

#: catalog.php:42 reservation-form.php:88
msgid "Book"
msgstr ""

채워 넣을 msgstr은 정확히 하나뿐입니다. 번역가가 무엇을 선택하든, 두 화면 중 하나는 틀리게 될 것입니다. 번역가가 문제를 이해하더라도 이를 고칠 수 없습니다. 형식 자체에서 하나의 msgid에 대해 두 개의 번역을 제공할 수 없기 때문입니다. 모호성이 데이터에 내재되어 있습니다.

msgctxt란 무엇이며 어떻게 모호성을 해소하는가?

msgctxt는 번역 항목에 첨부된 맥락 문자열입니다. 간단히 말해, msgid와 함께 두 번째 키를 추가하여 Gettext가 (맥락, msgid)를 고유한 쌍으로 처리하도록 합니다. 동일한 msgid를 가지지만 다른 msgctxt를 가진 두 항목은 두 개의 별개이며 독립적으로 번역 가능한 문자열이 됩니다.

Gettext의 조회 모델에서 번역은 일반적으로 원본 문자열만으로 키가 지정됩니다. msgctxt를 사용하면 키가 맥락과 원본의 조합이 됩니다. 이것이 전체 메커니즘이며, 깔끔하게 작동하는 이유입니다. 표시되는 텍스트를 변경하는 것이 아니라 내부 조회 키만 변경하는 것입니다.

.po 파일의 msgctxt 라인

.po 파일에서 맥락은 msgid 바로 위에 별도의 줄로 나타납니다:

#: catalog.php:42
msgctxt "noun"
msgid "Book"
msgstr "Buch"

#: reservation-form.php:88
msgctxt "verb"
msgid "Book"
msgstr "Reservieren"

이제 두 개의 항목이 있습니다. 이들은 동일한 msgid 값을 가지지만 다른 msgctxt 값을 가지므로, 각각 고유한 msgstr을 얻습니다. 카탈로그는 Buch로 렌더링되고, 예약 버튼은 Reservieren으로 렌더링됩니다. 런타임은 코드가 어떤 맥락을 사용할지 알려주었기 때문에 올바른 것을 선택합니다.

위의 손상된 단일 항목 버전과 비교해 보세요. 차이점은 번역 품질이 아니라 데이터 모델 자체가 올바른 답변의 존재를 허용하는지 여부입니다.

코드 마크업하기: _x()_ex()

.po 템플릿에 msgctxt를 내보내려면 일반 번역 함수 대신 맥락 인식 번역 함수를 호출해야 합니다. WordPress에서는 _x()와 그 에코 함수인 _ex(); 순수 Gettext에서는 pgettext()에 해당합니다.

_x()_ex() 선택하기

일반 __() 함수는 문자열과 텍스트 도메인을 받습니다. 맥락 변형 함수는 맥락을 두 번째 인수로 삽입합니다:

// Without context - ambiguous
__( 'Book', 'mytextdomain' );

// With context - the second argument is the msgctxt
_x( 'Book', 'noun', 'mytextdomain' );        // returns the translated string
_ex( 'Book', 'verb', 'mytextdomain' );       // echoes it directly

// Real-world disambiguation
_x( 'Post', 'verb: publish content', 'mytextdomain' );
_x( 'Post', 'noun: mail item', 'mytextdomain' );
_x( 'Order', 'sequence or sorting', 'mytextdomain' );
_x( 'Order', 'customer purchase', 'mytextdomain' );

두 번째 인수는 맥락 레이블입니다. 이것은 사용자에게 절대 표시되지 않으며, Gettext 조회와 번역을 수행하는 주체(사람 또는 무엇이든) 모두에게 모호성을 해소하기 위해 순수하게 존재합니다. 맥락은 짧고 설명적인 힌트처럼 작성하세요: 'noun', 'verb', 'button label', 'admin menu'. '1'과 같이 모호한 맥락은 기술적으로 유효하지만 번역가에게는 쓸모가 없습니다.

템플릿을 다시 생성하면 추출기는 이러한 호출을 인식하고 msgctxt 라인을 내보냅니다. Poedit 및 다른 PO 편집기와 같은 도구는 항목을 맥락별로 시각적으로 그룹화하여, 인간 번역가가 "Book (명사)"와 "Book (동사)"가 서로 다른 작업임을 즉시 알 수 있도록 합니다. 아직 추출 툴체인을 구축 중이거나 변수가 이러한 문자열과 상호 작용하는 방식에 어려움을 겪고 있다면, 코드 변수를 손상시키지 않고 PO 파일 번역하기에 대한 저희 가이드가 관련 워크플로를 심층적으로 다룹니다.

왜 순진한 번역가와 많은 AI 도구가 이것을 잘못 이해하는가

여기에 불편한 부분이 있습니다. 소스에 msgctxt를 추가하는 것은 필수적이지만 충분하지 않습니다. 맥락은 번역을 수행하는 주체가 실제로 그것을 읽을 때만 도움이 됩니다.

맥락이 버려지는 실패 모드

순진한 배치 번역 스크립트는 다음과 같이 작동합니다. 항목들을 반복하고, 각 msgid를 가져와 번역 API로 보내고, 그 결과를 msgstr에 씁니다. 이것은 msgctxt 라인을 전혀 보지 않습니다. 따라서 여러분이 신중하게 _x( 'Book', 'noun' )_x( 'Book', 'verb' )를 작성했더라도, 스크립트는 "Book 번역"이라는 두 개의 동일한 요청을 보내고 동일한 답변을 둘 다에 붙여넣습니다. 여러분의 모든 마크업 노력은 마지막 단계에서 버려집니다.

많은 범용 AI 번역 도구도 동일한 사각지대를 가지고 있습니다. 이들은 텍스트를 번역하도록 만들어졌으며, msgctxt는 텍스트가 아닌 메타데이터입니다. 도구가 .po 파일을 모델로 보내기 전에 문자열 목록으로 평탄화하면, 맥락은 모델의 프롬프트에 도달하지 못합니다. 어떤 신호도 없는 모델은 해당 단어의 통계적으로 가장 일반적인 의미(보통 "Book"의 명사, "Post"의 게시 의미)로 기본 설정되어 소수 사례를 조용히 오역합니다. 오류는 보이지 않을 것입니다. 몇 주 후 독일 사용자로부터 버그 보고서를 받게 될 것입니다.

맥락과 복수형은 같은 근본 원인을 공유합니다

여기는 복수형 처리와 맥락이 교차하는 지점이기도 합니다. 둘 다 파일 자체를 일반 텍스트로 취급하기보다 Gettext의 구조를 이해하는 도구에 의존하기 때문입니다. 문자열에 개수 기반 형태가 포함되어 있다면, 동일한 구조적 인식이 중요합니다. 이에 대한 자세한 내용은 Gettext 복수형 이해하기에서 다룹니다.

맥락 인식 파이프라인이 msgctxt를 사용하는 방법

msgctxt를 존중하는 번역 파이프라인은 순진한 스크립트와는 반대로 작동합니다. 이것은 .po 파일을 구조화된 데이터로 파싱하고, 각 항목의 맥락을 원본 문자열에 연결한 다음, 그 맥락을 프롬프트의 일부로 AI에 전달합니다. 따라서 모델은 "Book"을 추상적인 의미가 아닌 특정 동사로 번역하고 있다는 것을 알게 됩니다.

일등 시민 신호로서의 맥락

SimplePoTranslate는 이 문제에 정확히 이 방식으로 접근합니다. 그것의 맥락 인식 AImsgctxt 라인을 일등 시민 신호로 읽습니다. 두 항목이 msgid를 공유하지만 맥락이 다를 때, 실제로는 별개의 문자열로 번역되며, 맥락 힌트가 모델의 단어 선택에 영향을 줍니다. 그 결과, "Book (명사)"는 Buch로 돌아오고 "Book (동사)"는 buchen 또는 reservieren으로 돌아옵니다. 모든 모호한 용어를 수동으로 수정할 필요 없이 자동으로 처리됩니다.

마찬가지로 중요한 것은, 파이프라인이 출력에서 msgctxt 라인을 보존한다는 것입니다. 성능이 떨어지는 도구는 왕복 과정에서 맥락을 제거하여 두 항목을 조용히 다시 하나로 병합하고 다음 병합 시 모호성을 재도입할 수 있습니다. 완전한 Gettext 지원은 맥락이 번역, .mo 컴파일, 그리고 이후의 모든 재가져오기 과정에서도 유지되어, 모호성 해소가 일회성 수동 패치가 아닌 영구적임을 의미합니다. 이러한 문자열 내의 플레이스홀더에 대한 **구문 잠금(Syntax Locking)**과 결합하여, 맥락적으로 올바르고 구조적으로 손상되지 않은 번역을 얻을 수 있습니다.

마크업 결정은 여전히 여러분의 몫입니다. 특정 "Book"이 동사라는 것은 오직 여러분만이 압니다. 하지만 _x()_ex()로 소스에 주석을 달면, 맥락 인식 파이프라인은 그 주석을 모든 대상 언어에 걸쳐 문자열별로 일일이 관리할 필요 없이 올바른 번역으로 변환합니다.

결론

하나의 영어 단어에 여러 의미가 있는 모호성 문제는 무시할 수 있는 기벽이 아니라, Gettext가 문자열을 저장하는 방식의 구조적 특징입니다. 해결책은 msgctxt입니다. 소스의 모호한 문자열에 _x()_ex()로 주석을 달고, 각 등장에 명확한 맥락 레이블을 부여하며, Gettext가 (맥락, msgid) 쌍을 기준으로 번역을 키잉하도록 하십시오. 그 부분은 여러분의 몫이며, 몇 분밖에 걸리지 않습니다.

더 어려운 부분은 번역 단계가 맥락을 버리지 않고 실제로 존중하는지 확인하는 것입니다. 순진한 스크립트와 텍스트 전용 AI 도구는 msgctxt를 무시하고 여러분이 방지하려던 바로 그 버그를 다시 도입합니다. 맥락 인식 파이프라인은 맥락을 읽고, 각 모호성이 해소된 항목을 올바르게 번역하며, 컴파일 및 재가져오기를 통해 이를 보존합니다.

맥락을 무시한 오역 배포를 멈출 준비가 되셨습니까? SimplePoTranslate를 무료로 사용해 보세요 — 신용카드 필요 없습니다. 무료 티어는 완전한 msgctxt 맥락 지원을 통해 실제 .po.pot 파일을 처리하므로, 모호성이 해소된 문자열이 처음부터 올바르게 번역됩니다.