التدويل (i18n) في Kotlin: دليل شامل مع أمثلة
التدويل (i18n) هو عملية تصميم وتطوير البرمجيات بحيث يمكن تكييفها مع لغات ومناطق مختلفة دون إجراء تغييرات على الكود المصدري. في نظام Kotlin البيئي، سواء كانت تطبيقات Android، أو مشاريع الخادم باستخدام Ktor، أو الحلول متعددة المنصات باستخدام Kotlin Multiplatform، فإن التنفيذ الصحيح لـ i18n يعد أمرًا بالغ الأهمية لنجاح المنتج عالميًا. في هذه المقالة، سنستعرض الأساليب الرئيسية والأدوات وأفضل الممارسات لتدويل تطبيقات Kotlin.
لماذا يعتبر i18n مهمًا في Kotlin؟
باعتبار Kotlin لغة حديثة ومتوافقة تمامًا مع Java، فإنها ترث جميع إمكانيات Java للترجمة، ولكنها تقدم أيضًا حلولها الفريدة. يتيح التدويل الصحيح ما يلي:
- توسيع نطاق جمهور تطبيقك بشكل كبير
- تحسين تجربة المستخدم لمتحدثي اللغات المختلفة
- الامتثال للمتطلبات القانونية لمختلف البلدان (مثل تلك المتعلقة بالعملات أو تنسيقات التواريخ)
- تبسيط عملية إضافة لغات جديدة في المستقبل
الأساليب الرئيسية لـ i18n في Kotlin
1. استخدام Resource Bundle (النهج المتوافق مع Java)
الطريقة الأكثر شيوعًا وبساطة هي استخدام ResourceBundle القياسي وملفات الخصائص (.properties). هذه الطريقة مثالية لتطبيقات وحدة التحكم ومشاريع الخادم في Kotlin.
// messages_en.properties
greeting=Hello, {0}!
farewell=Goodbye
// messages_ru.properties
greeting=Привет, {0}!
farewell=До свидания
import java.util.ResourceBundle
import java.text.MessageFormat
fun main() {
val bundle = ResourceBundle.getBundle("messages", Locale("ru"))
val greeting = MessageFormat.format(bundle.getString("greeting"), "Мир")
println(greeting) // Выведет: Привет, Мир!
println(bundle.getString("farewell")) // Выведет: До свидания
}
2. النهج الخاص بـ Kotlin باستخدام دوال التوسيع
يتيح Kotlin إنشاء واجهة برمجة تطبيقات أكثر إيجازًا وأمانًا للعمل مع الترجمة، باستخدام دوال التوسيع والخصائص المفوضة.
import java.util.*
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
class I18n(private val baseName: String) {
private val bundle: ResourceBundle
get() = ResourceBundle.getBundle(baseName)
operator fun provideDelegate(
thisRef: Any?,
prop: KProperty<*>
): ReadOnlyProperty {
return ReadOnlyProperty { _, _ -> bundle.getString(prop.name) }
}
}
object Strings {
val i18n = I18n("messages")
val greeting by i18n
val farewell by i18n
}
fun main() {
// Автоматически использует локаль системы
println(Strings.greeting) // Выведет соответствующее значение из файла свойств
println(Strings.farewell)
}
أدوات الترجمة في Kotlin
1. Kotlin Multiplatform (KMP) و expect/actual
للمشاريع متعددة المنصات، يقدم Kotlin آلية قوية expect/actual، مما يسمح بتعريف واجهة برمجة تطبيقات مشتركة لـ i18n وتنفيذها بشكل منفصل لكل منصة.
// В общем коде (commonMain)
expect class PlatformStringResources {
fun getString(key: String, vararg args: Any?): String
}
// В Android (androidMain)
actual class PlatformStringResources {
private val context: Context = // получаем контекст
actual fun getString(key: String, vararg args: Any?): String {
val resId = context.resources.getIdentifier(key, "string", context.packageName)
return context.getString(resId, *args)
}
}
// В iOS (iosMain)
actual class PlatformStringResources {
actual fun getString(key: String, vararg args: Any?): Str
```