# How to mark some strings as translatable?

**URL:** <https://discourse.slicer.org/t/how-to-mark-some-strings-as-translatable/34008>\
**Category:** Development\
**Created:** [January 28, 2024, 8:22am UTC](https://discourse.slicer.org/t/how-to-mark-some-strings-as-translatable/34008 "2024-01-28T08:22:21Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![chir.set](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/chir.set/32/66982_2.png) [@chir.set](https://discourse.slicer.org/u/chir.set)\
**Post date:** [January 28, 2024, 8:22am UTC](https://discourse.slicer.org/t/how-to-mark-some-strings-as-translatable/34008/1 "2024-01-28T08:22:21Z")

</div>

Hi,

Python modules generated by the extension wizard are using the ‘\_()’ function for strings to be translated.

The simple use case is obvious: \_(“T e x t”).

How do we mark formatted strings with runtime place holders?

> f"Diameter ({lengthUnit})"

By the way, what about strings in the widget managed by designer? Are they marked as translatable by default? Does the dev need to perform some special steps?

Thank you.

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [January 28, 2024, 9:55am UTC](https://discourse.slicer.org/t/how-to-mark-some-strings-as-translatable/34008/2 "2024-01-28T09:55:07Z")

</div>

Hi @chir.set -

This document explains the process for internationalizing an extension:

[https://github.com/Slicer/SlicerLanguagePacks/blob/main/DevelopersManual.md](https://github.com/Slicer/SlicerLanguagePacks/blob/main/DevelopersManual.md)

The .ui files should be fine in general with a few caveats described in the document.

For python, we need to avoid the `f` string interpolation method for translatable strings because the part in `{}` is executable python code, and we don’t want people to be able to use that to inject incorrect behaviour via the translation files. Instead we need to use the named placeholder method of formatting.

---

<div class="post-metadata">

**Author:** ![chir.set](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/chir.set/32/66982_2.png) [@chir.set](https://discourse.slicer.org/u/chir.set)\
**Post date:** [January 28, 2024, 11:04am UTC](https://discourse.slicer.org/t/how-to-mark-some-strings-as-translatable/34008/3 "2024-01-28T11:04:59Z")

</div>

> [@pieper](#):
>
> we need to avoid the `f` string interpolation method

Thank you for your reply.

So, to continue on the above example, we should use :

```auto
lengthUnitValue = <result of some processing>
_("Diameter ({lengthUnit})").format(lengthUnit = lengthUnitValue)

```

according to the link above.

Is that right?

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [January 28, 2024, 2:03pm UTC](https://discourse.slicer.org/t/how-to-mark-some-strings-as-translatable/34008/4 "2024-01-28T14:03:53Z")

</div>

Yes, that looks correct.

Also people providing translations should be aware that these placeholders inside the `{}` blocks need to be left alone or the code can break. Maybe weblate or something warns about this, I’m not sure.

Small nitpick, python style usually omits the spaces around the `=` sign so you may get style warnings about it.

---

<div class="post-metadata">

**Author:** ![chir.set](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/chir.set/32/66982_2.png) [@chir.set](https://discourse.slicer.org/u/chir.set)\
**Post date:** [January 28, 2024, 3:05pm UTC](https://discourse.slicer.org/t/how-to-mark-some-strings-as-translatable/34008/5 "2024-01-28T15:05:26Z")

</div>

> [@pieper](#):
>
> python style usually omits the spaces around the `=` sign

Oops, funny, or not funny, I changed to ’ = ’ on purpose in many places for readability 🙂 😃 I’ll deal with that in a future maintenance session. Thanks.

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [January 28, 2024, 3:40pm UTC](https://discourse.slicer.org/t/how-to-mark-some-strings-as-translatable/34008/6 "2024-01-28T15:40:16Z")

</div>

Haha, yes, I do find it funny!

The style guide clearly says “[A Foolish Consistency is the Hobgoblin of Little Minds](https://peps.python.org/pep-0008/#a-foolish-consistency-is-the-hobgoblin-of-little-minds)” and yet we kind of insist on it anyway : D

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [January 29, 2024, 12:38am UTC](https://discourse.slicer.org/t/how-to-mark-some-strings-as-translatable/34008/7 "2024-01-29T00:38:41Z")

</div>

@chir.set if the document did not answer any of your questions or not clear enough then please submit a pull request to add/change the text. If needed then of course you can ask due clarification here.

---

<div class="post-metadata">

**Author:** ![chir.set](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/chir.set/32/66982_2.png) [@chir.set](https://discourse.slicer.org/u/chir.set)\
**Post date:** [January 29, 2024, 10:05am UTC](https://discourse.slicer.org/t/how-to-mark-some-strings-as-translatable/34008/8 "2024-01-29T10:05:40Z")

</div>

> [@lassoan](#):
>
> submit a pull request to add/change the text

@lassoan

I’m not sure that we have a similar understanding of the problem; I’ll push a branch in SlicerVMTK with changes I have made regarding translation and we’ll discuss in a PR over there.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [January 29, 2024, 2:37pm UTC](https://discourse.slicer.org/t/how-to-mark-some-strings-as-translatable/34008/9 "2024-01-29T14:37:04Z")

</div>

Yes, please send a pull request to SlicerVMTK extension. I’ll have a look and merge it and then I will create the translation component on Weblate.

---

<div class="post-metadata">

**Author:** ![chir.set](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/chir.set/32/66982_2.png) [@chir.set](https://discourse.slicer.org/u/chir.set)\
**Post date:** [January 29, 2024, 2:50pm UTC](https://discourse.slicer.org/t/how-to-mark-some-strings-as-translatable/34008/10 "2024-01-29T14:50:02Z")

</div>

> [@lassoan](#):
>
> please send a pull request to SlicerVMTK extension

[Here](https://github.com/vmtk/SlicerExtension-VMTK/pull/108) it is, please consider that the translation commits are based on [#107](https://github.com/vmtk/SlicerExtension-VMTK/pull/107).

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [February 25, 2024, 2:13pm UTC](https://discourse.slicer.org/t/how-to-mark-some-strings-as-translatable/34008/11 "2024-02-25T14:13:35Z")

</div>

You can now add translations for VMTK extension here:

> **[3D Slicer/SlicerVMTK](https://hosted.weblate.org/projects/3d-slicer/slicervmtk/)**
>
> 3D Slicer is being translated into 58 languages using Weblate. Join the translation or start translating your own project.

---

<div class="post-metadata">

**Author:** ![chir.set](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/chir.set/32/66982_2.png) [@chir.set](https://discourse.slicer.org/u/chir.set)\
**Post date:** [February 28, 2024, 8:47pm UTC](https://discourse.slicer.org/t/how-to-mark-some-strings-as-translatable/34008/12 "2024-02-28T20:47:52Z")

</div>

> [@lassoan](#):
>
> You can now add translations for VMTK extension here:

After translating SlicerVMTK to French, I merged [#111](https://github.com/vmtk/SlicerExtension-VMTK/pull/111) to fix some inconsistencies.

Weblate does not seem to pickup updates from the code base on its own. How do the translatable strings get updated in weblate? Is it automated on Slicer’s side? Is it done manually on a scheduled basis?

Thanks for any info.
