LogoCocode Skills

i18n Reference

slang 기반 국제화 상세 API 및 문법 레퍼런스입니다.

i18n Reference Guide#

slang 기반 국제화 상세 API 및 문법 레퍼런스입니다.

YAML 문법 레퍼런스#

기본 문자열#

common:
  appName: 펫메디
  ok: 확인
  cancel: 취소
  save: 저장
  loading: 로딩 중...

중첩 구조#

auth:
  login:
    title: 로그인
    button: 로그인하기
    error: 로그인에 실패했습니다
  signup:
    title: 회원가입
    button: 가입하기

파라미터 (Placeholders)#

user:
  greeting: '$name님, 안녕하세요!'
  points: '$count 포인트 보유'
  joinDate: '$date에 가입'

Dart 사용:

context.t.user.greeting(name: 'John')
context.t.user.points(count: '100')

복수형 (Pluralization)#

items:
  count(param=n):
    zero: 항목 없음
    one: 항목 1개
    other: 항목 $n개

cart:
  itemCount(param=count):
    zero: 장바구니가 비어있습니다
    one: 장바구니에 상품 1개
    other: 장바구니에 상품 $count개

Dart 사용:

context.t.items.count(n: 0)     // "항목 없음"
context.t.items.count(n: 1)     // "항목 1개"
context.t.items.count(n: 5)     // "항목 5개"

컨텍스트 기반 (Context-Based)#

pet:
  type(context=PetType):
    dog: 강아지
    cat: 고양이
    bird: 새
    other: 반려동물

gender:
  pronoun(context=Gender):
    male: 그
    female: 그녀
    other: 그들

Dart 사용:

context.t.pet.type(context: PetType.dog)  // "강아지"

리치 텍스트 (Rich Text)#

terms:
  agreement: '이용약관에 동의합니다. <link>자세히 보기</link>'

Dart 사용:

context.t.terms.agreement(
  link: (text) => TextSpan(
    text: text,
    style: TextStyle(color: Colors.blue),
    recognizer: TapGestureRecognizer()..onTap = () => openTerms(),
  ),
)

파일 구조 레퍼런스#

디렉토리 레이아웃#

shared/
├── i10n/                           # 앱 번역
│   └── lib/
│       ├── translations/
│       │   ├── strings.i18n.yaml   # 기본 (한국어)
│       │   └── strings_en.i18n.yaml # 영어
│       └── src/
│           └── translations/
│               └── translations.g.dart
│
└── i10n_web/                       # 웹 번역 (별도)
    └── lib/
        ├── translations/
        │   ├── strings.i18n.yaml
        │   └── strings_en.i18n.yaml
        └── src/
            └── translations/
                └── translations.g.dart

slang.yaml 설정#

base_locale: ko
fallback_strategy: base_locale
input_directory: lib/translations
input_file_pattern: .i18n.yaml
output_directory: lib/src/translations
output_file_name: translations.g.dart
output_format: single_file
key_case: camel
key_map_case: camel
param_case: camel
string_interpolation: dart
flat_map: false
timestamp: true
statistics: true

코드 사용 레퍼런스#

기본 접근#

import 'package:i10n/i10n.dart';

// BuildContext 확장
Text(context.t.common.appName)

// 직접 접근 (context 없이)
final appName = AppLocale.ko.translations.common.appName;

앱 설정#

MaterialApp(
  locale: TranslationProvider.of(context).flutterLocale,
  supportedLocales: AppLocaleUtils.supportedLocales,
  localizationsDelegates: GlobalMaterialLocalizations.delegates,
)

로케일 변경#

// 로케일 변경
LocaleSettings.setLocale(AppLocale.en);

// 현재 로케일 확인
final currentLocale = LocaleSettings.currentLocale;

// 시스템 로케일 사용
LocaleSettings.useDeviceLocale();

웹 번역 (별도)#

import 'package:i10n_web/i10n_web.dart';

// 웹 전용 번역
Text(context.wt.common.title)

명령어 레퍼런스#

코드 생성#

# 번역 코드 생성
melos run generate:locale

# 강제 재생성
cd shared/i10n && dart run slang

GPT 자동 번역#

# 영어 자동 번역 (API 키 필요)
melos run generate:locale:gpt

# 직접 실행
cd shared/i10n && dart run slang:gpt

분석#

# 누락된 번역 확인
dart run slang analyze

# 통계 출력
dart run slang analyze --stats

트러블슈팅#

번역이 적용 안 됨#

증상원인해결
키가 없다는 에러코드 생성 안 됨melos run generate:locale 실행
영어가 표시 안 됨영어 파일 누락strings_en.i18n.yaml 확인
복수형 동작 안 함문법 오류param=n 형식 확인

코드 생성 에러#

증상원인해결
YAML 파싱 에러들여쓰기 오류스페이스 2개로 통일
중복 키 에러동일 키 존재키 이름 변경
파라미터 에러$ 누락$name 형식 사용

GPT 번역 에러#

증상원인해결
API 에러키 없음OPENAI_API_KEY 환경 변수 설정
번역 품질 낮음컨텍스트 부족주석으로 힌트 제공

Best Practices#

키 네이밍#

# ✅ 좋은 예
user:
  profile:
    editButton: 프로필 수정
    saveButton: 저장

# ❌ 나쁜 예
editProfileBtn: 프로필 수정  # 중첩 구조 사용하지 않음
user_profile_save: 저장       # snake_case 사용

복수형 처리#

# ✅ 모든 케이스 처리
notifications:
  count(param=n):
    zero: 알림 없음
    one: 알림 1개
    other: 알림 $n개

# ❌ 불완전한 처리
notifications:
  count: '알림 $n개'  # 0, 1 케이스 처리 안 됨

파라미터 설명#

# ✅ 주석으로 파라미터 설명
user:
  # name: 사용자 이름
  greeting: '$name님, 안녕하세요!'

  # count: 보유 포인트 수
  points: '$count 포인트'