{"id":26474001,"url":"https://github.com/mova-rb/mova","last_synced_at":"2025-03-19T22:39:45.799Z","repository":{"id":56884627,"uuid":"24290683","full_name":"mova-rb/mova","owner":"mova-rb","description":"Translation and localization library","archived":false,"fork":false,"pushed_at":"2014-12-06T15:12:31.000Z","size":152,"stargazers_count":5,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-18T01:12:14.389Z","etag":null,"topics":["i18n","ruby","translation"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","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/mova-rb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-09-21T12:43:12.000Z","updated_at":"2017-11-10T13:34:37.000Z","dependencies_parsed_at":"2022-08-20T13:10:56.123Z","dependency_job_id":null,"html_url":"https://github.com/mova-rb/mova","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mova-rb%2Fmova","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mova-rb%2Fmova/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mova-rb%2Fmova/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mova-rb%2Fmova/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mova-rb","download_url":"https://codeload.github.com/mova-rb/mova/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244519094,"owners_count":20465585,"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","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":["i18n","ruby","translation"],"created_at":"2025-03-19T22:39:45.222Z","updated_at":"2025-03-19T22:39:45.788Z","avatar_url":"https://github.com/mova-rb.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Mova\n\n[![Gem Version](https://badge.fury.io/rb/mova.svg)](http://badge.fury.io/rb/mova)\n[![Build Status](https://travis-ci.org/mova-rb/mova.svg?branch=master)](https://travis-ci.org/mova-rb/mova)\n\n**Mova** is a translation and localization library that aims to be simple and fast.\n\n## Name origin\n\n\"Мова\" [['mɔwɑ][mova-pronounce]] in Ukrainian and Belarusian means \"language\".\n\n## Why\n\nBecause [I18n][i18n] code is hard to reason about.\n\n## Status\n\nNot tested in production. Localization part is yet to be implemented.\n\n## Installation\n\nAdd this line to your application's Gemfile and run `bundle`:\n\n```ruby\ngem 'mova'\n```\n\n## Usage\n\n```ruby\nrequire \"mova\"\n\n# instantiate a translator with in-memory storage\ntranslator = Mova::Translator.new\n\n# store translations\ntranslator.put(en: {hello: \"world!\"})\n\n# retreive translations\ntranslator.get(\"hello\", :en) #=\u003e \"world!\"\n\n# wrap existing storage\nrequire \"redis-activesupport\"\nredis = ActiveSupport::Cache::RedisStore.new(\"localhost:6379/0\")\ntranslator = Mova::Translator.new(storage: redis)\ntranslator.get(:hi_from_redis, :en) #=\u003e \"Hi!\"\n```\n\n## Documentation\n\nhttp://rubydoc.info/github/mova-rb/mova/master/frames\n\n## Design principles\n\n1.  **Translation and localization data should be decoupled.**\n\n    Localization info describes how dates, numbers, currencies etc. should be rendered,\nand what pluralization rules and writing direction should be used. This data is rarely if ever\nchanged during project lifetime.\n\n    On the other hand translation data is always subject to change, because you may need to\nadjust text length to fit it into new design, update your product title to be more SEO friendly\nand so on.\n\n    It is more performant to keep localization data in a static Ruby class, rather then\nfetch it from a translation storage each time when we want to localize a date. This still\nallows to modify locales on per project level.\n\n    Ruby class is also a natural place for methods and collection data types, while procs and hashes\nbeing put into a translation storage feels awkward.\n\n2.  **Translations should be kept in a simple key-value storage.**\n\n    Simple storage means that given a string key it should return only a string or\nnil if nothing found. No object serialization. No hashes as a return value.\n\n    Such limitation allows to use almost anything as a storage: Ruby hash, file storage that maps\nto a hash, any RDMBS, any key-value store, or any combination of them.\n\n    This also forces decoupling of translation retrieval and translation management (finding\nuntranslated strings, providing hints to translators etc.) since not much data can be put in a key.\n\n3.  **Translation framework should not be aware of any file format.**\n\n    If we need to import translations from a file, hash should be used as input format. No matter\nwhich file format is used to store data on a disk, whether it be YAML or JSON, or TOML, any option\nshould work transparently.\n\n4.  **Exception should be used as a last resort when controlling flow.**\n\n    Raising and catching an exception in Ruby is a very expensive operation and should be avoided\nwhenever possible.\n\n5.  **Instance is better than singleton.**\n\n    You can have separate versions of translator for models and templates. You can have different\nstorages. You can use different interpolation rules.\n\n## Related projects\n\n* [mova-i18n][mova-i18n] - integrating with/replacing I18n.\n\n[mova-pronounce]: http://upload.wikimedia.org/wikipedia/commons/f/ff/Uk-%D0%BC%D0%BE%D0%B2%D0%B0.ogg\n[mova-i18n]: https://github.com/mova-rb/mova-i18n\n[i18n]: https://github.com/svenfuchs/i18n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmova-rb%2Fmova","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmova-rb%2Fmova","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmova-rb%2Fmova/lists"}