Internationalization translation pattern templates.
Template A: Basic Translation Structure#
strings.i18n.yaml (Korean)#
@@locale: ko
common:
appName: ํซ๋ฉ๋
ok: ํ์ธ
cancel: ์ทจ์
save: ์ ์ฅ
delete: ์ญ์
edit: ์์
close: ๋ซ๊ธฐ
loading: ๋ก๋ฉ ์ค...
error: ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค
retry: ๋ค์ ์๋
noData: ๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค
auth:
login: ๋ก๊ทธ์ธ
logout: ๋ก๊ทธ์์
signUp: ํ์๊ฐ์
email: ์ด๋ฉ์ผ
password: ๋น๋ฐ๋ฒํธ
forgotPassword: ๋น๋ฐ๋ฒํธ๋ฅผ ์์ผ์
จ๋์?
navigation:
home: ํ
search: ๊ฒ์
mypage: ๋ง์ดํ์ด์ง
settings: ์ค์
strings_en.i18n.yaml (English)#
@@locale: en
common:
appName: Petmedi
ok: OK
cancel: Cancel
save: Save
delete: Delete
edit: Edit
close: Close
loading: Loading...
error: An error occurred
retry: Retry
noData: No data available
auth:
login: Login
logout: Logout
signUp: Sign Up
email: Email
password: Password
forgotPassword: Forgot password?
navigation:
home: Home
search: Search
mypage: My Page
settings: Settings
Template B: Parameter Patterns#
User Greetings#
user:
# name: User ' s name
greeting: ' $name๋, ์๋
ํ์ธ์! '
welcomeBack: ' $name๋, ๋ค์ ์ค์
จ๊ตฐ์! '
# date: Join date (yyyy-MM-dd format)
memberSince: ' $date์ ๊ฐ์
'
# count: Number of points
points: ' $count ํฌ์ธํธ ๋ณด์ '
# level: Membership tier
levelInfo: ' $level ๋ฑ๊ธ ํ์์
๋๋ค '
Dart Usage Example#
// User greeting
Text(context.t.user.greeting(name: user.displayName))
// Points display
Text(context.t.user.points(count: user.points.toString()))
// Join date display
Text(context.t.user.memberSince(date: DateFormat('yyyy-MM-dd').format(user.createdAt)))
Template C: Pluralization Patterns#
Item Counts#
items:
count(param=n):
zero: ํญ๋ชฉ ์์
one: ํญ๋ชฉ 1๊ฐ
other: ํญ๋ชฉ $n๊ฐ
cart:
itemCount(param=count):
zero: ์ฅ๋ฐ๊ตฌ๋๊ฐ ๋น์ด์์ต๋๋ค
one: ์ฅ๋ฐ๊ตฌ๋์ ์ํ 1๊ฐ
other: ์ฅ๋ฐ๊ตฌ๋์ ์ํ $count๊ฐ
notifications:
unread(param=count):
zero: ์ฝ์ง ์์ ์๋ฆผ ์์
one: ์ฝ์ง ์์ ์๋ฆผ 1๊ฐ
other: ์ฝ์ง ์์ ์๋ฆผ $count๊ฐ
messages:
count(param=n):
zero: ๋ฉ์์ง ์์
one: ๋ฉ์์ง 1๊ฐ
other: ๋ฉ์์ง $n๊ฐ
followers:
count(param=n):
zero: ํ๋ก์ ์์
one: ํ๋ก์ 1๋ช
other: ํ๋ก์ $n๋ช
Dart Usage Example#
// Cart item count
Text(context.t.cart.itemCount(count: cartItems.length))
// Notification badge
Badge(
label: Text(context.t.notifications.unread(count: unreadCount)),
)
// Follower count
Text(context.t.followers.count(n: followerCount))
Template D: Context-Based Patterns#
Enum-Based Translation#
pet:
type(context=PetType):
dog: ๊ฐ์์ง
cat: ๊ณ ์์ด
bird: ์
fish: ๋ฌผ๊ณ ๊ธฐ
hamster: ํ์คํฐ
other: ๊ธฐํ
order:
status(context=OrderStatus):
pending: ๋๊ธฐ ์ค
confirmed: ํ์ธ๋จ
shipping: ๋ฐฐ์ก ์ค
delivered: ๋ฐฐ์ก ์๋ฃ
cancelled: ์ทจ์๋จ
payment:
method(context=PaymentMethod):
card: ์นด๋ ๊ฒฐ์
bank: ๊ณ์ข์ด์ฒด
kakao: ์นด์นด์คํ์ด
naver: ๋ค์ด๋ฒํ์ด
Dart Enum Definition#
// lib/domain/entity/pet_type.dart
enum PetType {
dog,
cat,
bird,
fish,
hamster,
other,
}
// Usage
Text(context.t.pet.type(context: pet.type))
Text(context.t.order.status(context: order.status))
Template E: Error Message Patterns#
Form Validation Errors#
validation:
required: ํ์ ์
๋ ฅ ํญ๋ชฉ์
๋๋ค
email:
invalid: ์ฌ๋ฐ๋ฅธ ์ด๋ฉ์ผ ํ์์ด ์๋๋๋ค
exists: ์ด๋ฏธ ์ฌ์ฉ ์ค์ธ ์ด๋ฉ์ผ์
๋๋ค
password:
tooShort: ๋น๋ฐ๋ฒํธ๋ ์ต์ 8์ ์ด์์ด์ด์ผ ํฉ๋๋ค
tooWeak: ๋น๋ฐ๋ฒํธ๊ฐ ๋๋ฌด ์ฝํฉ๋๋ค
mismatch: ๋น๋ฐ๋ฒํธ๊ฐ ์ผ์นํ์ง ์์ต๋๋ค
phone:
invalid: ์ฌ๋ฐ๋ฅธ ์ ํ๋ฒํธ ํ์์ด ์๋๋๋ค
error:
network: ๋คํธ์ํฌ ์ฐ๊ฒฐ์ ํ์ธํด์ฃผ์ธ์
server: ์๋ฒ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค
timeout: ์์ฒญ ์๊ฐ์ด ์ด๊ณผ๋์์ต๋๋ค
unauthorized: ๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค
forbidden: ์ ๊ทผ ๊ถํ์ด ์์ต๋๋ค
notFound: ์์ฒญํ ์ ๋ณด๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค
unknown: ์ ์ ์๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค
Dart Usage Example#
// Form validation
TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return context.t.validation.required;
}
if (!EmailValidator.validate(value)) {
return context.t.validation.email.invalid;
}
return null;
},
)
// Error handling
result.fold(
(failure) => ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(context.t.error.network)),
),
(success) => navigateToHome(),
);
Template F: Date/Time Patterns#
Relative Time#
time:
justNow: ๋ฐฉ๊ธ ์
minutesAgo: ' $minutes๋ถ ์ '
hoursAgo: ' $hours์๊ฐ ์ '
daysAgo: ' $days์ผ ์ '
weeksAgo: ' $weeks์ฃผ ์ '
monthsAgo: ' $months๊ฐ์ ์ '
yearsAgo: ' $years๋
์ '
# Future
inMinutes: ' $minutes๋ถ ํ '
inHours: ' $hours์๊ฐ ํ '
inDays: ' $days์ผ ํ '
Dart Usage Example#
String getRelativeTime(BuildContext context, DateTime dateTime) {
final now = DateTime.now();
final difference = now.difference(dateTime);
if (difference.inMinutes < 1) {
return context.t.time.justNow;
} else if (difference.inMinutes < 60) {
return context.t.time.minutesAgo(minutes: difference.inMinutes.toString());
} else if (difference.inHours < 24) {
return context.t.time.hoursAgo(hours: difference.inHours.toString());
} else if (difference.inDays < 7) {
return context.t.time.daysAgo(days: difference.inDays.toString());
} else if (difference.inDays < 30) {
return context.t.time.weeksAgo(weeks: (difference.inDays ~/ 7).toString());
} else if (difference.inDays < 365) {
return context.t.time.monthsAgo(months: (difference.inDays ~/ 30).toString());
} else {
return context.t.time.yearsAgo(years: (difference.inDays ~/ 365).toString());
}
}
Template G: Rich Text Patterns#
Text with Links#
legal:
termsAgreement: ' ์ด์ฉ์ฝ๊ด์ ๋์ํฉ๋๋ค. < link > ์์ธํ ๋ณด๊ธฐ < /link > '
privacyAgreement: ' ๊ฐ์ธ์ ๋ณด ์ฒ๋ฆฌ๋ฐฉ์นจ์ ๋์ํฉ๋๋ค. < link > ์์ธํ ๋ณด๊ธฐ < /link > '
marketing:
promotion: ' < highlight > ํน๋ณ ํ ์ธ < /highlight > ์ด๋ฒคํธ๊ฐ ์งํ ์ค์
๋๋ค! '
newFeature: ' ์๋ก์ด ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋์์ต๋๋ค. < link > ํ์ธํ๊ธฐ < /link > '
Dart Usage Example#
// Rich text builder
Text.rich(
context.t.legal.termsAgreement(
link: (text) => TextSpan(
text: text,
style: TextStyle(
color: AppColors.primary,
decoration: TextDecoration.underline,
),
recognizer: TapGestureRecognizer()
..onTap = () => Navigator.pushNamed(context, '/terms'),
),
),
)
// Highlighted text
Text.rich(
context.t.marketing.promotion(
highlight: (text) => TextSpan(
text: text,
style: TextStyle(
color: AppColors.accent,
fontWeight: FontWeight.bold,
),
),
),
)
Slang Configuration Template#
slang.yaml#
# Slang configuration file
base_locale: ko
fallback_strategy: base_locale
# Input settings
input_directory: lib/translations
input_file_pattern: .i18n.yaml
# Output settings
output_directory: lib/src/translations
output_file_name: translations.g.dart
output_format: single_file
# Case settings
key_case: camel
key_map_case: camel
param_case: camel
# Other settings
string_interpolation: dart
flat_map: false
timestamp: true
statistics: true
# Interface generation (if needed)
interfaces:
PageData:
paths:
- home
- settings
- profile
GPT Translation Hint Template#
Comments for Improving Translation Quality#
# App name - do not translate
common:
appName: Petmedi
# Button text - keep short and clear
buttons:
submit: ์ ์ถ # Submit
confirm: ํ์ธ # Confirm, OK
# Pet-related terms - maintain friendly tone
pet:
# Represents pet species
type(context=PetType):
dog: ๊ฐ์์ง # puppy/dog - use " dog " for general
cat: ๊ณ ์์ด # cat/kitty - use " cat " for general