0
# Localization and Internationalization (i18n)
1
2
Disnake's internationalization system enables application commands to support multiple languages through Discord's native localization features. The system provides both high-level convenience classes and low-level protocols for custom localization implementations.
3
4
## Capabilities
5
6
### Localized Strings
7
8
Container class for managing localized strings across different languages/locales.
9
10
```python { .api }
11
class Localized(Generic[StringT]):
12
def __init__(
13
self,
14
string: StringT,
15
*,
16
key: Optional[str] = None,
17
**localizations: StringT
18
):
19
"""
20
Create a localized string container.
21
22
Parameters:
23
- string: Base/default string value
24
- key: Localization key for lookups
25
- localizations: Locale-specific string values
26
"""
27
28
def set(self, locale: Union[Locale, str], value: StringT) -> Self:
29
"""
30
Set localized value for a specific locale.
31
32
Parameters:
33
- locale: Target locale
34
- value: Localized string value
35
36
Returns:
37
Self for method chaining
38
"""
39
40
@property
41
def localizations(self) -> Dict[Locale, StringT]:
42
"""Dictionary of all localized values."""
43
44
@property
45
def key(self) -> Optional[str]:
46
"""Localization key for external lookup."""
47
```
48
49
### Localization Value
50
51
Represents a localized value with support for fallback languages and placeholder substitution.
52
53
```python { .api }
54
class LocalizationValue:
55
def __init__(
56
self,
57
message: str,
58
key: Optional[str] = None,
59
**kwargs: Any
60
):
61
"""
62
Create a localization value with optional formatting.
63
64
Parameters:
65
- message: Base message string
66
- key: Localization key identifier
67
- kwargs: Format arguments for string interpolation
68
"""
69
70
def format(self, **kwargs: Any) -> LocalizationValue:
71
"""
72
Create new LocalizationValue with additional format arguments.
73
74
Parameters:
75
- kwargs: Format arguments to merge
76
77
Returns:
78
New LocalizationValue with combined formatting
79
"""
80
```
81
82
### Localization Protocol
83
84
Abstract protocol defining the interface for localization providers.
85
86
```python { .api }
87
class LocalizationProtocol(ABC):
88
@abstractmethod
89
async def get(
90
self,
91
key: str,
92
locale: Locale,
93
*,
94
default: Optional[str] = None,
95
**kwargs: Any
96
) -> Optional[str]:
97
"""
98
Get localized string for key and locale.
99
100
Parameters:
101
- key: Localization key
102
- locale: Target locale
103
- default: Default value if key not found
104
- kwargs: Format arguments for string interpolation
105
106
Returns:
107
Localized string or None if not found
108
"""
109
110
@abstractmethod
111
async def bulk_get(
112
self,
113
keys: Sequence[str],
114
locale: Locale,
115
**kwargs: Any
116
) -> Dict[str, Optional[str]]:
117
"""
118
Get multiple localized strings at once.
119
120
Parameters:
121
- keys: List of localization keys
122
- locale: Target locale
123
- kwargs: Format arguments for all strings
124
125
Returns:
126
Dictionary mapping keys to localized strings
127
"""
128
```
129
130
### Localization Store
131
132
Default file-based localization provider that loads translations from JSON files.
133
134
```python { .api }
135
class LocalizationStore(LocalizationProtocol):
136
def __init__(
137
self,
138
files: Union[os.PathLike, Dict[Locale, os.PathLike]],
139
*,
140
strict: bool = False,
141
fallback: Optional[Locale] = None
142
):
143
"""
144
Initialize localization store with translation files.
145
146
Parameters:
147
- files: Path to directory or mapping of locales to file paths
148
- strict: Whether to raise errors for missing keys
149
- fallback: Fallback locale when translation missing
150
"""
151
152
@classmethod
153
def from_directory(
154
cls,
155
directory: os.PathLike,
156
*,
157
pattern: str = "{locale}.json",
158
strict: bool = False,
159
fallback: Optional[Locale] = None
160
) -> LocalizationStore:
161
"""
162
Create store from directory of JSON translation files.
163
164
Parameters:
165
- directory: Directory containing translation files
166
- pattern: Filename pattern with {locale} placeholder
167
- strict: Whether to raise errors for missing keys
168
- fallback: Fallback locale for missing translations
169
170
Returns:
171
Configured LocalizationStore instance
172
"""
173
174
async def reload(self) -> None:
175
"""Reload all translation files from disk."""
176
177
@property
178
def locales(self) -> Set[Locale]:
179
"""All available locales in the store."""
180
```
181
182
## Types
183
184
```python { .api }
185
# Type aliases for localized strings
186
LocalizedRequired = Union[str, "Localized[str]"]
187
LocalizedOptional = Union[Optional[str], "Localized[Optional[str]]"]
188
LocalizationsDict = Union[Dict[Locale, str], Dict[str, str]]
189
190
# Alias for British English spelling
191
Localised = Localized
192
```
193
194
## Usage Examples
195
196
### Basic Localized Strings
197
198
```python
199
import disnake
200
from disnake.i18n import Localized
201
202
# Create localized command name and description
203
@bot.slash_command(
204
name=Localized("hello", es="hola", fr="salut"),
205
description=Localized(
206
"Say hello to someone",
207
es="Saluda a alguien",
208
fr="Dire bonjour à quelqu'un"
209
)
210
)
211
async def hello(
212
inter: disnake.ApplicationCommandInteraction,
213
user: disnake.User = disnake.Param(
214
description=Localized(
215
"The user to greet",
216
es="El usuario a saludar",
217
fr="L'utilisateur à saluer"
218
)
219
)
220
):
221
await inter.response.send_message(f"Hello {user.mention}!")
222
```
223
224
### File-based Localization Store
225
226
```python
227
import disnake
228
from disnake.i18n import LocalizationStore
229
from disnake.enums import Locale
230
231
# Set up localization store
232
i18n_store = LocalizationStore.from_directory(
233
"locales/",
234
pattern="{locale}.json",
235
fallback=Locale.en_US
236
)
237
238
# Configure client with localization
239
bot = disnake.Bot(
240
command_prefix="!",
241
intents=disnake.Intents.default(),
242
localization_provider=i18n_store
243
)
244
245
# Use localization keys in commands
246
@bot.slash_command(
247
name="greet",
248
description=Localized(key="commands.greet.description")
249
)
250
async def greet(
251
inter: disnake.ApplicationCommandInteraction,
252
target: disnake.User = disnake.Param(
253
description=Localized(key="commands.greet.target_param")
254
)
255
):
256
# Get localized response message
257
greeting = await i18n_store.get(
258
key="messages.greeting",
259
locale=inter.locale,
260
username=target.display_name
261
)
262
await inter.response.send_message(greeting)
263
```
264
265
### Translation File Structure
266
267
Example `locales/en-US.json`:
268
```json
269
{
270
"commands": {
271
"greet": {
272
"description": "Greet another user",
273
"target_param": "User to greet"
274
}
275
},
276
"messages": {
277
"greeting": "Hello, {username}!"
278
}
279
}
280
```
281
282
Example `locales/es.json`:
283
```json
284
{
285
"commands": {
286
"greet": {
287
"description": "Saluda a otro usuario",
288
"target_param": "Usuario a saludar"
289
}
290
},
291
"messages": {
292
"greeting": "¡Hola, {username}!"
293
}
294
}
295
```