LogoSkills

slang-i18n Templates

Internationalization translation pattern templates.

i18n Templates#

Internationalization translation pattern templates.


Template A: Basic Translation Structure#

ko.i18n.json (Korean, base)#

{
   " common " : {
     " app_name " :  " Unibook " ,
     " ok " :  " ํ™•์ธ " ,
     " cancel " :  " ์ทจ์†Œ " ,
     " save " :  " ์ €์žฅ " ,
     " delete " :  " ์‚ญ์ œ " ,
     " edit " :  " ์ˆ˜์ • " ,
     " close " :  " ๋‹ซ๊ธฐ " ,
     " loading " :  " ๋กœ๋”ฉ ์ค‘... " ,
     " error " :  " ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค " ,
     " retry " :  " ๋‹ค์‹œ ์‹œ๋„ " ,
     " no_data " :  " ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค " 
   },
   " auth " : {
     " login " :  " ๋กœ๊ทธ์ธ " ,
     " logout " :  " ๋กœ๊ทธ์•„์›ƒ " ,
     " sign_up " :  " ํšŒ์›๊ฐ€์ž… " ,
     " email " :  " ์ด๋ฉ”์ผ " ,
     " password " :  " ๋น„๋ฐ€๋ฒˆํ˜ธ " ,
     " forgot_password " :  " ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์žŠ์œผ์…จ๋‚˜์š”? " 
   },
   " navigation " : {
     " home " :  " ํ™ˆ " ,
     " search " :  " ๊ฒ€์ƒ‰ " ,
     " mypage " :  " ๋งˆ์ดํŽ˜์ด์ง€ " ,
     " settings " :  " ์„ค์ • " 
   }
}

en.i18n.json (English)#

{
   " common " : {
     " app_name " :  " Unibook " ,
     " ok " :  " OK " ,
     " cancel " :  " Cancel " ,
     " save " :  " Save " ,
     " delete " :  " Delete " ,
     " edit " :  " Edit " ,
     " close " :  " Close " ,
     " loading " :  " Loading... " ,
     " error " :  " An error occurred " ,
     " retry " :  " Retry " ,
     " no_data " :  " No data available " 
   },
   " auth " : {
     " login " :  " Login " ,
     " logout " :  " Logout " ,
     " sign_up " :  " Sign Up " ,
     " email " :  " Email " ,
     " password " :  " Password " ,
     " forgot_password " :  " Forgot password? " 
   },
   " navigation " : {
     " home " :  " Home " ,
     " search " :  " Search " ,
     " mypage " :  " My Page " ,
     " settings " :  " Settings " 
   }
}

Template B: Parameter Patterns#

User Greetings#

{
   " user " : {
     " greeting " :  " {name}๋‹˜, ์•ˆ๋…•ํ•˜์„ธ์š”! " ,
     " welcome_back " :  " {name}๋‹˜, ๋‹ค์‹œ ์˜ค์…จ๊ตฐ์š”! " ,
     " member_since " :  " {date}์— ๊ฐ€์ž… " ,
     " points " :  " {count} ํฌ์ธํŠธ ๋ณด์œ  " ,
     " level_info " :  " {level} ๋“ฑ๊ธ‰ ํšŒ์›์ž…๋‹ˆ๋‹ค " 
   }
}

Dart Usage Example#

// User greeting
Text(context.i10n.user.greeting(name: user.displayName))

// Points display
Text(context.i10n.user.points(count: user.points.toString()))

// Join date display
Text(context.i10n.user.member_since(date: DateFormat('yyyy-MM-dd').format(user.createdAt)))

Template C: Pluralization Patterns#

Item Counts#

{
   " items " : {
     " count(param=n) " : {
       " zero " :  " ํ•ญ๋ชฉ ์—†์Œ " ,
       " one " :  " ํ•ญ๋ชฉ 1๊ฐœ " ,
       " other " :  " ํ•ญ๋ชฉ {n}๊ฐœ " 
     }
  },
   " cart " : {
     " item_count(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.i10n.cart.item_count(count: cartItems.length))

// Notification badge
Badge(
  label: Text(context.i10n.notifications.unread(count: unreadCount)),
)

// Follower count
Text(context.i10n.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.i10n.pet.type(context: pet.type))
Text(context.i10n.order.status(context: order.status))

Template E: Error Message Patterns#

Form Validation Errors#

{
   " validation " : {
     " required " :  " ํ•„์ˆ˜ ์ž…๋ ฅ ํ•ญ๋ชฉ์ž…๋‹ˆ๋‹ค " ,
     " email " : {
       " invalid " :  " ์˜ฌ๋ฐ”๋ฅธ ์ด๋ฉ”์ผ ํ˜•์‹์ด ์•„๋‹™๋‹ˆ๋‹ค " ,
       " exists " :  " ์ด๋ฏธ ์‚ฌ์šฉ ์ค‘์ธ ์ด๋ฉ”์ผ์ž…๋‹ˆ๋‹ค " 
     },
     " password " : {
       " too_short " :  " ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ์ตœ์†Œ 8์ž ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค " ,
       " too_weak " :  " ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ๋„ˆ๋ฌด ์•ฝํ•ฉ๋‹ˆ๋‹ค " ,
       " mismatch " :  " ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค " 
     },
     " phone " : {
       " invalid " :  " ์˜ฌ๋ฐ”๋ฅธ ์ „ํ™”๋ฒˆํ˜ธ ํ˜•์‹์ด ์•„๋‹™๋‹ˆ๋‹ค " 
     }
  },
   " error " : {
     " network " :  " ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ์„ ํ™•์ธํ•ด์ฃผ์„ธ์š” " ,
     " server " :  " ์„œ๋ฒ„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค " ,
     " timeout " :  " ์š”์ฒญ ์‹œ๊ฐ„์ด ์ดˆ๊ณผ๋˜์—ˆ์Šต๋‹ˆ๋‹ค " ,
     " unauthorized " :  " ๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค " ,
     " forbidden " :  " ์ ‘๊ทผ ๊ถŒํ•œ์ด ์—†์Šต๋‹ˆ๋‹ค " ,
     " not_found " :  " ์š”์ฒญํ•œ ์ •๋ณด๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค " ,
     " unknown " :  " ์•Œ ์ˆ˜ ์—†๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค " 
   }
}

Dart Usage Example#

// Form validation
TextFormField(
  validator: (value) {
    if (value == null || value.isEmpty) {
      return context.i10n.validation.required;
    }
    if (!EmailValidator.validate(value)) {
      return context.i10n.validation.email.invalid;
    }
    return null;
  },
)

// Error handling
result.fold(
  (failure) => ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(content: Text(context.i10n.error.network)),
  ),
  (success) => navigateToHome(),
);

Template F: Date/Time Patterns#

Relative Time#

{
   " time " : {
     " just_now " :  " ๋ฐฉ๊ธˆ ์ „ " ,
     " minutes_ago " :  " {minutes}๋ถ„ ์ „ " ,
     " hours_ago " :  " {hours}์‹œ๊ฐ„ ์ „ " ,
     " days_ago " :  " {days}์ผ ์ „ " ,
     " weeks_ago " :  " {weeks}์ฃผ ์ „ " ,
     " months_ago " :  " {months}๊ฐœ์›” ์ „ " ,
     " years_ago " :  " {years}๋…„ ์ „ " ,
     " in_minutes " :  " {minutes}๋ถ„ ํ›„ " ,
     " in_hours " :  " {hours}์‹œ๊ฐ„ ํ›„ " ,
     " in_days " :  " {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.i10n.time.just_now;
  } else if (difference.inMinutes < 60) {
    return context.i10n.time.minutes_ago(minutes: difference.inMinutes.toString());
  } else if (difference.inHours < 24) {
    return context.i10n.time.hours_ago(hours: difference.inHours.toString());
  } else if (difference.inDays < 7) {
    return context.i10n.time.days_ago(days: difference.inDays.toString());
  } else if (difference.inDays < 30) {
    return context.i10n.time.weeks_ago(weeks: (difference.inDays ~/ 7).toString());
  } else if (difference.inDays < 365) {
    return context.i10n.time.months_ago(months: (difference.inDays ~/ 30).toString());
  } else {
    return context.i10n.time.years_ago(years: (difference.inDays ~/ 365).toString());
  }
}

Template G: Rich Text Patterns#

{
   " legal " : {
     " terms_agreement " :  " ์ด์šฉ์•ฝ๊ด€์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.  < link > ์ž์„ธํžˆ ๋ณด๊ธฐ < /link > " ,
     " privacy_agreement " :  " ๊ฐœ์ธ์ •๋ณด ์ฒ˜๋ฆฌ๋ฐฉ์นจ์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.  < link > ์ž์„ธํžˆ ๋ณด๊ธฐ < /link > " 
   },
   " marketing " : {
     " promotion " :  " < highlight > ํŠน๋ณ„ ํ• ์ธ < /highlight >   ์ด๋ฒคํŠธ๊ฐ€ ์ง„ํ–‰ ์ค‘์ž…๋‹ˆ๋‹ค! " ,
     " new_feature " :  " ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.  < link > ํ™•์ธํ•˜๊ธฐ < /link > " 
   }
}

Dart Usage Example#

// Rich text builder
Text.rich(
  context.i10n.legal.terms_agreement(
    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.i10n.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/src/json
input_file_pattern: .i18n.json

# Output settings
output_directory: lib/src/translations
output_file_name: translations.g.dart
output_format: single_file

# Case settings
key_case: snake
key_map_case: snake
param_case: snake

# Other settings
string_interpolation: braces
flat_map: false
timestamp: true
statistics: true
translate_var: translations

# Interface generation (if needed)
interfaces:
  PageData:
    paths:
      - home
      - settings
      - profile

GPT Translation Hint Template#

JSON does not support inline comments, so translation hints for slang_gpt are provided via the reserved @ metadata keys (for example @app_name) rather than comments.

{
   " common " : {
     " app_name " :  " Unibook " ,
     " @app_name " : {
       " description " :  " App name - do not translate, keep as Unibook " 
     }
  },
   " buttons " : {
     " submit " :  " ์ œ์ถœ " ,
     " @submit " : {  " description " :  " Button text - keep short and clear (Submit) "   },
     " confirm " :  " ํ™•์ธ " ,
     " @confirm " : {  " description " :  " Button text - Confirm / OK "   }
  },
   " pet " : {
     " type(context=PetType) " : {
       " dog " :  " ๊ฐ•์•„์ง€ " ,
       " cat " :  " ๊ณ ์–‘์ด " 
     },
     " @type " : {
       " description " :  " Pet species - maintain friendly tone; dog=dog, cat=cat " 
     }
  }
}