Skip to content

Updating localisations

Eitot edited this page Apr 25, 2025 · 4 revisions

Vienna's localisable strings are at the following locations:

  • Vienna/Interfaces/mul.lproj/*.xcstrings
  • Vienna/Resources/*.xcstrings
  • Vienna/Resources/Base.lproj/Predicate.strings
  • Vienna/SharedSupport/Plugins/*.viennaplugin/en.lproj/InfoPlist.strings
  • Vienna Help/Resources/en.lproj/*.html
  • Vienna Help/Resources/InfoPlist.xcstrings

Adding, changing or removing strings for localisation

  1. Make the changes to the source strings
    • NSLocalizedString in *.m or *.swift
    • Labels or titles in Interface Builder
    • InfoPlist.strings (en.lproj only)
    • Predicate.strings (Base.lproj only)
    • *.html in Vienna Help (en.lproj only)
    • InfoPlist.xcstrings
  2. Build the project to update the *.xcstrings files
  3. Commit the changes and submit a pull request
  4. If changes were made to Predicate.strings files, select the Vienna project in Xcode and go to File → Packages → ExpandPredicateLocalizations
  5. Upload the updated source strings to Crowdin, using

Important

Do not forget to use ExpandPredicateLocalizations if you are uploading Predicate.strings files.

Importing localised strings from Crowdin

  1. Build and download from Crowdin, using
  2. Select the Vienna project in Xcode and go to File → Packages → CombinePredicateLocalizations
  3. Build the project
  4. Commit the changes and submit a pull request

Important

Do not forget to use CombinePredicateLocalizations before committing the changes to Predicate.strings files

Maintaining Predicate.strings files

Predicate.strings contains localisable formatting strings that are generated and used by NSPredicateEditor. If any changes are made to SmartFolder's NSPredicateEditor templates (‑[SmartFolder prepareTemplates]) then you probably have to generate new localisable strings. NSPredicateEditor can generate these strings for you. You can access these when you go to the smart-folder editor in a development build of Vienna. There you select Development Options → Log Formatting Strings to generate new localisable strings for all predicates.

The format of these localisable strings is more sophisticated than other formatting strings. The formatting strings will affect how the user interface will look in the smart-folder editor.

For example: "%[Read]@ is %[Yes]@" = "%1$[Is read]@ %2$[Yes]@";

will look like this: image

and: "%[Subject]@ %[contains]@ %@" = "%1$[Subject]@ %2$[contains]@ %3$@";

will look like this: image

Text between %[ ]@ is displayed as a pop-up button or a label; text outside will always be displayed as a label. Arguments without square brackets (%@) are replaced by a different control, such as a text field. The arguments on the right side are numbered, e.g. %1$[ ]@, %2$[ ]@, %3$@. NSPredicateEditor might create a row of user-interface components for each string, but will merge arguments where possible into pop-up buttons. Text can be put inside or outside of the square brackets so that it is shown as a pop-up button or a label. The numbered arguments can also be repositioned. NSPredicateEditor will ultimately combine all formatting strings and group similar items together, going from left to right. For this reason it is important to follow some rules:

  • Make sure that the first numbered variable is not repositioned
  • Try to adhere to a hierarchy, going from left to right, from general to specific
  • Format strings that belong together in the same way to make the user interface as simple as possible

Vienna has three Swift Package plug-ins available to help with Predicate.strings:

  • CombinePredicateLocalizations: This will merge formatting strings together and makes it easier to see how complex the user interface might be.
  • ExpandPredicateLocalizations: This will undo CombinePredicateLocalizations and show each each formatting string as its own localised strings.
  • ComparePredicateLocalizations: This will compare the Predicate.strings of Base.lproj to localised Predicate.strings and check for inconsistencies.

Crowdin CLI

Crowdin CLI can be installed via Homebrew (% brew install crowdin). It uses the crowdin.yml file in the project root to find files that should be uploaded and determine the paths of downloaded translated files. Crowdin CLI will ask for authorisation first and generate an API token for you. This token should be saved in the environment variable CROWDIN_PERSONAL_TOKEN.

Important

Make sure that crowdin.yml is correctly configured, especially the files list, before you attempt to upload or download files.

Common commands:

  • % crowdin config sources (lists all source files in the project that match the files list in crowdin.yml)
  • % crowdin config translations (lists all translated files on Crowdin that match the files list in crowdin.yml)
  • % crowdin config lint (validates crowdin.yml)
  • % crowdin upload sources (uploads source files that match the files list in crowdin.yml)
  • % crowdin download translations (downloads translated files that match the files list in crowdin.yml, you might have to add --skip-untranslated-files and/or --skip-untranslated-strings arguments)
Clone this wiki locally