# Okrand - an internationalization/translation tool for Django

**URL:** <https://forum.djangoproject.com/t/okrand-an-internationalization-translation-tool-for-django/18910>\
**Category:** Show & Tell\
**Created:** [February 17, 2023, 12:51pm UTC](https://forum.djangoproject.com/t/okrand-an-internationalization-translation-tool-for-django/18910 "2023-02-17T12:51:17Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![boxed](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/boxed/32/11975_2.png) [@boxed](https://forum.djangoproject.com/u/boxed)\
**Post date:** [February 17, 2023, 12:51pm UTC](https://forum.djangoproject.com/t/okrand-an-internationalization-translation-tool-for-django/18910/1 "2023-02-17T12:51:17Z")

</div>

I released [Okrand](https://github.com/boxed/okrand) today, which is something I’ve been working on a little while. The i18n system in Django is 15 years old and it shows, with the dependency on the gettext tool being the biggest liability. Okrand is a pure python tool, and has a built in view to make translation easy. This tool also highlights some common mistakes.

Check out the readme for more.

---

<div class="post-metadata">

**Author:** ![stribny](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/stribny/32/5592_2.png) [@stribny](https://forum.djangoproject.com/u/stribny)\
**Post date:** [March 11, 2023, 4:54pm UTC](https://forum.djangoproject.com/t/okrand-an-internationalization-translation-tool-for-django/18910/2 "2023-03-11T16:54:38Z")

</div>

Hi @boxed! It is indeed good to see people think about improvements to the i18n system. My first though was that this would replace the po and mo files to use e.g. JSON but this doesn’t seem to be the case.

So if I understand it well, the project aims to make po files translatable in an iommi admin, correct? Are there any other goals?

---

<div class="post-metadata">

**Author:** ![boxed](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/boxed/32/11975_2.png) [@boxed](https://forum.djangoproject.com/u/boxed)\
**Post date:** [March 11, 2023, 5:40pm UTC](https://forum.djangoproject.com/t/okrand-an-internationalization-translation-tool-for-django/18910/3 "2023-03-11T17:40:02Z")

</div>

My first goal was to have tooling that I could work with. My first feature addition was to collect model field names and translate them without the need to add gettext\_lazy for every field that is the same as the field name. Never send a man to do a machine’s job 🙂

I am very open to adding json support. This would be very easy because the code of Okrand is very small, well tested, and easy to reason about.

There are other features one could add like getting the field names for forms so you don’t need to write explicit gettext calls for them either.

---

<div class="post-metadata">

**Author:** ![stribny](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/stribny/32/5592_2.png) [@stribny](https://forum.djangoproject.com/u/stribny)\
**Post date:** [March 12, 2023, 7:44pm UTC](https://forum.djangoproject.com/t/okrand-an-internationalization-translation-tool-for-django/18910/4 "2023-03-12T19:44:56Z")

</div>

I see! I am unsure whether it is worth replacing po and mo files, on the project at work we use a separate SPA frontend with translations stored in JSON and it is good for manual edits. But we also need to add entries manually. So perhaps the Django translations is good when working with po files is abstracted, and it ultimately doesn’t matter what format it is stored in.

---

<div class="post-metadata">

**Author:** ![boxed](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/boxed/32/11975_2.png) [@boxed](https://forum.djangoproject.com/u/boxed)\
**Post date:** [March 12, 2023, 8:23pm UTC](https://forum.djangoproject.com/t/okrand-an-internationalization-translation-tool-for-django/18910/5 "2023-03-12T20:23:12Z")

</div>

Yea, if it’s PO files or not seems not really very significant. You can check out the Okrand source code. The po-file handling is quite trivial. I use polib in a simple way (vendored because reasons). It could easily write to and from json files if you want.

Btw, I forgot that I also had lots of trouble with the javascript catalog thing in Django so that was also a factor in me getting angry enough to write Okrand 😛

---

<div class="post-metadata">

**Author:** ![etamponi](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/etamponi/32/23800_2.png) [@etamponi](https://forum.djangoproject.com/u/etamponi)\
**Post date:** [September 9, 2024, 4:50pm UTC](https://forum.djangoproject.com/t/okrand-an-internationalization-translation-tool-for-django/18910/6 "2024-09-09T16:50:48Z")

</div>

Hi boxed!

When using Okrand, should I still call manage.py makemessages and compilemessages, or is the workflow different? Should I change in some way how I handle translation for templates? Finally, is the UI only for translating messages, or does it do also other things?

Thank you!

---

<div class="post-metadata">

**Author:** ![boxed](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/boxed/32/11975_2.png) [@boxed](https://forum.djangoproject.com/u/boxed)\
**Post date:** [September 9, 2024, 5:47pm UTC](https://forum.djangoproject.com/t/okrand-an-internationalization-translation-tool-for-django/18910/7 "2024-09-09T17:47:09Z")

</div>

The UI will do the collect and on save will write the compiled file. So you just need that UI. You will still need to run `collectmessages` on deploy.

---

<div class="post-metadata">

**Author:** ![etamponi](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/etamponi/32/23800_2.png) [@etamponi](https://forum.djangoproject.com/u/etamponi)\
**Post date:** [September 9, 2024, 5:52pm UTC](https://forum.djangoproject.com/t/okrand-an-internationalization-translation-tool-for-django/18910/8 "2024-09-09T17:52:26Z")

</div>

Amazing! I’ll give it a try, the idea of not needing extra boilerplate in my models is intriguing!
