Get Started with Specify 7 Localization

Thank you for your interest in localizing Specify 7! Localization is a complex process, and our goal is to make it as easy as possible for anyone to contribute to the localization of Specify. This guide will outline the process on how to contribute to this goal! We are using Weblate as the translation platform for this endeavour.

Weblate is an open-source translation and localization management platform. It is designed to be easy to use and allows users to translate content and manage translation projects in over 150 languages. Weblate is used to manage translations for websites, apps, documentation and software. It includes features such as a powerful API, automated translation suggestion, quality check, and support for collaborative translation.

Localization is important because it allows all users to understand and interact with the software in a way that is specific to their language and culture. Localization allows for a more comprehensive user experience for different types of users by making the software more accessible, regardless of language or location. Additionally, localization can help to ensure accuracy, as it allows users to easily enter data in their native language, reducing the risk of errors.

We are excited to begin this effort with the community! If you would like to join the localization effort, please contact with your desired language and any questions!

Getting Started

:bulb: Important: Please read through the Weblate documentation on translating in general for more information about any section of this guide! Specify-specific components are available in the Syntax section of this tutorial.

You can start by navigating to our Hosted Weblate instance for Specify 7 translation.

  1. First, you need to Register a new account with Hosted Weblate.

  2. Now that you have an account, you can return to the Specify 7 project Languages page and begin work localizing Specify.

Select the language you are planning on localizing from the list. In this instance, we only have English (en_US) and Russian (rus_RU). As we expand our language options in the coming months, this list will expand!

If you are interested in getting another language added to the list of options, you can contact

  1. You can click on any component from the Components menu. Each component is a group of similar strings that belong to specific coponents within Specify.

  1. Once you have selected a component (in this instance, attachments) you can see the String status for that component in particular as well as a list of other components below.

    Having navigated to a component, a set of links lead to its actual translation. The translation is further divided into individual checks, like Untranslated strings or Unfinished strings. If the whole project is translated, without error, All strings is still available. Alternatively you can use the search field to find a specific string or term.

:bulb: Important: See Translating using Weblate for current up-to-date documentation on how to use the application.

  1. You can now translate the strings using the Weblate interface.

Phrase Definition Example
Context This contextual description provides related info about the current string. attachments
Language Language that is currently being localized. English (United States)
Needs Editing Warns Specify and other users localizing a language that the translation needs to be edited. TRUE or FALSE

You can use the Suggest feature to suggest a change to the development team at Specify or other translators.

If you are unsure on a translation or need some review for the syntax, this feature is a great way to save translations.

String Information

On the right side of the interface, you can see the string information to learn more before suggesting or making any changes.

Screenshot context

You can see the context in which the current string is being used. You can click on the screenshot to see a larger preview and expand the details, seeing all assigned source strings.


This contextual description provides related info about the current string.

Source string description

This describes where the string is being used in Specify. You can see all areas that the string will appear.


Users will not need to make any changes so there is no need to understand how these work.

ICU flags are flags that are used to configure the behavior of the International Components for Unicode (ICU) library. They are used to control various aspects of ICU’s functionality such as character set conversion, Unicode normalization, and collation.

The flags are comma-separated, the parameters are separated with colon.

Source string location

This is a list of all locations that use the current string in the Specify 7 code.

String age

This is how long the string has been available in the Weblate interface. Once a string is added to the production branch of Specify 7, it will appear in Weblate and this will be updated to the day added.

Translation Interface

You can navigate between strings by using the controls in the top left. These allow you to go to the first, previous, next, and end string in the list. You can search for a value in a string in the textbox, and you can change the order of the available strings by modifying the value of the dropbox to the right of the search box.

Matrix View

The matrix view, available on every component page under the Tools menu, is an effective way to compare different languages. First, select the desired languages and confirm your selection, then click on a translation to open and edit it. The matrix view is also useful for discovering missing translations in various languages and quickly adding them in one view.

Zen Mode

You can click the Zen button on the top right while translating a component. This simplifies the layout and removes additional UI elements such as Nearby strings or the Glossary.

You can select the Zen editor as your default editor using the Preferences tab on your User profile. Here you can also choose between having translations listed Top to bottom or Side by side depending on your personal preference.

This allows you to edit in bulk when going through each item for translation.

Keyboard Shortcuts

Visual Keyboard

Translation Context

Automatic Suggestions

Search and Replace


:gear: For technical users, you can learn more about the internationalization library used as the backbone for this project. You can check out typesafe-i18n’s documentation for further reference.

For translation-only users, you can see the following important notes to consider while translating.

Specify Examples

Context: pickListValueTooLong

Value (en_US):

value from picklist {pickList:string} longer than the max of {maxLength:number|formatted} for field

{pickList:string} represents the Pick List name.
{maxLength:number|formatted} shows the max length of the field as a number and applies a format to the number based on the region. In en_US, 2048 becomes 2,048.

Context: failedParsingPickList

Value (en_US):

{value:string} is not a legal value in this picklist field.
Click on the arrow to choose among available options.

{value:string} represents the value not present in the picklist.
This string has a “new line” character after field.. This acts as a break and should be maintained when localized.

Context: tabMoveDirectionDescription

Value (en_US):

You can move in the opposite direction by pressing <key>Shift</key>+<key>Enter</key>

<key></key> make the contents appear with special formatting to indicate to the user the contents are a key.

Context: mergeNodeMessage

Value (en_US):

All references to {treeName:string} node "{nodeName:string}"
will be replaced with "{parentName:string}", and all descendants
 of "{nodeName:string}" will be moved to "{parentName:string}" 
with any descendants matching in name and rank being 
themselves merged recursively.

{treeName:string} is the name of the current tree.
{nodeName:string} is the name of the node that was selected first during the merge in the tree.
{parentName:string} is the name of the node selected second during the merge. In this case, it will become the dominant node once the process is completed.

Syntax Notes

We don’t use the index arguments {0} anywhere as they are bug prone, we only use {keyedArguments:string}

Each argument has a type. Most commonly string or number.

Additionally, a formatter may be applied.


Formatting turns 1000 into 1,000.

Translators do not need to change any of these, but you need to be aware of the syntax so that you do not break it.

The syntax for plurals is more confusing:

{{ keyedArgument: no items | an item | ?? items }}

(described in-detail in this documentation)

This is currently being used in only one place right now, but we plan to use plurals more over time as the software develops.

We have written our own syntax for non-text arguments. Syntax is XML-like and should be familiar.

Non-text arguments include: links, line breaks, bold text, etc.

Examples of non-text arguments:

Specify Collections Consortium <br />
Biodiversity Institute <br />
University of Kansas <br />
1345 Jayhawk Blvd. <br />
Lawrence, KS 66045 USA

<br /> is uncommon as separate strings are used in most places instead of using <br />.

This is because translation may break syntax or string, or even automatic page translate could break the syntax.

Permission denied when accessing <url />

Sometimes, non-text arguments have a text child:

Users from <memberLink>member institutions</memberLink>
can search for answered questions and ask for help
on our <discourseLink>Community Forum</discourseLink>

Additional Syntax Notes:

  • You can change the order of arguments.

  • You cannot create your own arguments (i.e, if there is no <br /> in the English string, you can’t add it themself as the code is explicitly looking for specific arguments and only in strings where it expects them. Essentially, you can only use the text and non-text arguments that are present in the English string for all other languages.

  • Do not rename the arguments (the {keyedArgument}, or <url />,) BUT, do rename the child of a non-text argument:

    <dontRename>LOCALIZE ME</dontRename>.

    The syntax for plurals can be a bit confusing:

    {{ dontRename: RENAME_zero_case | RENAME_one_case | ?? RENAME_other_case }} where | is a divisor between different plurals and ?? is a placeholder for the number itself.

    You can move ?? to a different location or use it in multiple plurals.

  • If you need a reminder on what plural forms are available in your language, here is the list (the only difference you need to be aware of is that the “zero” plural form is available for all languages.):

A colleague share this website with me, you can search it in several languages, and then toggle to another when looking for terms :slight_smile:

1 Like

Hello, it’s possible to add swiss German (de_CH) to the Translation System, please?

Hi @dfernandez,

de_CH has been added as a language to be translated for Specify 7!

Great, thank you!

Hello, I have two main questions about the Specify-7 translation process.

First, I want to confirm that the translation of Specify-7 main components such as menus, buttons, and tool labeling is done through Weblate, a collaborative application. However, form translation is done manually by each Specify-7 portal administrator using the integrated Schema Configuration tool. Form translation is not shared with the Specify community. Is this correct? Can I share my form translations? Are the form translation saved when upgrading Specify

Second, I host my own instance of Specify-7 on our office servers. How can I apply the translation updates that I make on Weblate to my secured and internal-only Specify-7 portal?

Thank you.

Hi @Heryk,

That is correct, the translation of many of the components is done through weblate via a hosted instance. After the translations are made in Weblate, the bot then commits the translations to the code repo on GitHub (it is done quite regularly so shouldn’t be hard to come across, and then you can click on the commit to get a sense of where the bot is making the changes and what they look like).

For the forms, it does look like there is a localized field option, see 'Use localized field labels' checkbox in App Resource should be a button · Issue #4341 · specify/specify7 · GitHub. I am not super familiar with this, but someone from the team can likely elaborate.

For the second part of your question, the translations ultimately end up in the GitHub repository via the bot as mentioned earlier, so they should end up in your instance when you apply updates and build from either the source code or the docker container. If you were to make a translation through the hosted Weblate, you would not only be helping yourself by having the translation available in the next release, but also everyone else.

1 Like

Thank you for the reply. To further expand on your answer:

  1. The changes made in Weblate would end up in the following release (i.e. 7.9.3). If you want to get them faster, you can use the “edge” version of specify7-service in your docker-compose - this version gets built several times per day - so you get freshest changes quickly, but it may be less stable (of course, you can also build locally if you wish)
  2. For form labels localization, we want to have that integrated with Weblate too. Most of the work for that has already been done, but unfortunately, we didn’t have the time to finish it completely as other priorities took over.

Thanks Mark and Max. The process is much clearer to me now. :+1:

Yesterday, I made a minor correction on the French profile of Specify-7 using the Weblate portal.

This afternoon, I updated my server scripts to use the dockerized “edge” version of SP-7. However, I could not see my fix.

I went back to Weblate and noticed that my modification was not there anymore. Do you need a special authorization so that your language modifications get saved and pushed to Specify deployments?

PS. Good to know that form labels localization is coming too! :slight_smile:

We recently had an issue where concurrent changes to Weblate by both google translate automatic translation and code changes in specify 7 caused a conflict. Usually Weblate resolves conflict automatically but this time we had to do it manually. It is possible that your changes were lost during conflict resolution. If that is the case, I am sorry about it.

Could you please try to make an edit again?

For reference, weblate localizations are stored in the repository in here - specify7/specifyweb/frontend/js_src/lib/localization at production · specify/specify7 · GitHub. After making changes in Weblate, you should see changes in GitHub in 3 hours.

No special permission is required - any weblate user is free to make changes to localization (noone abused this free access, so we are not restricting it - anyone is free to contribute)

1 Like