{"id":23553383,"url":"https://github.com/aymanizz/ktor-i18n","last_synced_at":"2025-09-05T02:05:45.655Z","repository":{"id":42039335,"uuid":"255629168","full_name":"aymanizz/ktor-i18n","owner":"aymanizz","description":"Ktor Internationalization Feature","archived":false,"fork":false,"pushed_at":"2023-11-16T14:28:42.000Z","size":106,"stargazers_count":41,"open_issues_count":5,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-28T13:57:21.403Z","etag":null,"topics":["kotlin","ktor","ktor-feature","ktor-framework","ktor-server"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aymanizz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-04-14T14:15:55.000Z","updated_at":"2024-09-06T04:07:14.000Z","dependencies_parsed_at":"2023-11-16T16:00:47.027Z","dependency_job_id":null,"html_url":"https://github.com/aymanizz/ktor-i18n","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/aymanizz/ktor-i18n","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aymanizz%2Fktor-i18n","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aymanizz%2Fktor-i18n/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aymanizz%2Fktor-i18n/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aymanizz%2Fktor-i18n/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aymanizz","download_url":"https://codeload.github.com/aymanizz/ktor-i18n/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aymanizz%2Fktor-i18n/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273699712,"owners_count":25152286,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-05T02:00:09.113Z","response_time":402,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kotlin","ktor","ktor-feature","ktor-framework","ktor-server"],"created_at":"2024-12-26T11:15:03.250Z","updated_at":"2025-09-05T02:05:40.636Z","avatar_url":"https://github.com/aymanizz.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Ktor I18n\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Latest Version](https://jitpack.io/v/aymanizz/ktor-i18n.svg)](https://jitpack.io/#aymanizz/ktor-i18n)\n![CI](https://github.com/aymanizz/ktor-i18n/workflows/CI/badge.svg?branch=master\u0026event=push)\n\nInternationalization support for Ktor framework.\n\n### Usage\n\n#### Add The Dependency\n\nadd the dependency to your gradle build file:\n\n```groovy\nrepositories {\n    jcenter()\n    maven { url \"https://jitpack.io\" }\n}\n\ndependencies {\n    implementation 'com.github.aymanizz:ktor-i18n:VERSION'\n}\n```\nwhere \"VERSION\" is dependent on the ktor version you are using.\nIf you are using ktor 2.0.0 or newer, use version 2.0.0.\nIf you are using older ktor versions, use version 1.0.0.\n\n#### Usage Example\n\nFor this example we will create a messages bundle with English and Arabic localizations.\n\nStart by installing the feature in your application:\n```kotlin\ninstall(I18n) {\n    supportedLocales = listOf(\"en\", \"ar\").map(Locale::forLanguageTag)\n}\n```\nBecause the english locale is the first in the supported locales list, it will be considered the default/fallback locale.\n\nNext, let's create `i18n/` folder inside the resources directory, and create two files: `Messages_en.properties` and\n`Messages_ar.properties`, in this folder with the following content:\n\n- inside Messages_en.properties\n```properties\ngreeting=Hello!\n```\n- inside Messages_ar.properties\n```properties\ngreeting=هلا!\n```\n\nWe now have the most basic setup for the i18n feature, we can use it as follows:\n```kotlin\nrouting {\n    get(\"/greeting\") {\n        call.respondText(call.t(R(\"greeting\")))\n    }\n}\n```\n\nNow that the route `/greeting` is set up, we can send a request and expect a response depending on the request's\n`Accept-Language` header value.\n\nFor example, if the header value is `en-US` the response will be `Hello`, if it's `en;q=0.7,ar;q=0.9` then the response\nwill be `هلا`, and if it's `de` then the response will fallback to `Hello` because english is the default locale.\n\nNow let's add more keys to our messages. This time we will use a key with a count, and also a placeholder:\n\n- in Messages_en.properties\n```properties\npieces=You have {0,number} pieces.\npieces.1=You have a single piece.\npieces.2=You have two pieces.\n```\n- in Messages_ar.properties\n```properties\npieces=لديك {0,number} قطع\npieces.1=لديك قطعة واحدة\npieces.2=لديك قطعتان\n```\n\nAnd use it like so:\n```kotlin\nrouting {\n    get(\"/greeting\") { /* ... */ }\n    get(\"/pieces\") {\n        val count = call.parameters[\"count\"]?.toIntOrNull() ?: 1\n        call.respondText(call.t(R(\"pieces\", count = count), count))\n    }\n}\n```\n\nNote that we have passed count twice, once to the `R` class constructor which generates the keys to lookup the\nlocalization, this class will generate the keys `\"pieces.$count\"` and `\"pieces\"`, the localization provider will try\neach key until one of them is present in the messages bundle, then the obtained message is formatted using `count` (the\nsecond parameter passed to `t` call.) In the case of the `pieces.1` and `pieces.2` messages, the extra argument is\nignored. But in the case of `peices` message, the `{}` placeholder is replaced with the value of `count`.\n\nGo ahead and try your application now with different `Accept-Language` header values and different `count` query\nparameter values.\n\n#### Different Key Generation Strategy\n\nSo far we have used the default strategy provided by the `R` key generator instances. However, one can implement any\nother strategy to suit their needs. For example, here is how to add a gender key to our keys:\n```kotlin\nenum class Gender { Male, Female }\n\n// implement a key generator\nclass MyKey(\n        @PropertyKey(resourceBundle = \"i18n.Messages\")\n        baseKey: String,\n        count: Int? = null,\n        gender: Gender? = null\n) : DelimitedKeyGenerator(baseKey, count?.toString(), gender?.name?.toLowerCase())\n```\n\nThen we can use it in our code as before, in messages:\n```properties\ngreeting=Hello!\ngreeting.female=Hi!\n```\n\nAnd the application code:\n```kotlin\ncall.t(MyKey(\"greeting\", gender=Gender.Female)) // result is Hi!\n```\n\nThe key generator could be any iterable that produces strings, so you can customize the generation even further.\n\n#### Usage with FreeMaker\n\nYou can use this plugin along with the [ktorx:ktor-i18n-freemarker](https://github.com/nathanfallet/ktorx) plugin developed by [Nathan Fallet](https://github.com/nathanfallet).\n\n### Contribution\n\n#### Development\n\nTo run the tests:\n```\n./gradlew test\n```\n\nTo run the formatter:\n```\n./gradlew spotlessApply\n```\n\nTo run all checks at once:\n```\n./gradlew check\n```\n\n#### Issues\n\nIf you encounter any issues with this feature, let us know by opening a new issue with the issue description.\nMake sure that there are no similar issues already open.\n\n#### Features\n\nBefore starting on development for a new feature please open a feature request issue for discussion.\n\n### License\n\nThe project is licensed under the MIT License. For further details see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faymanizz%2Fktor-i18n","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faymanizz%2Fktor-i18n","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faymanizz%2Fktor-i18n/lists"}