Skip to content
English
  • There are no suggestions because the search field is empty.

05.06 Language and Localization

SimpleRisk supports 39+ languages via Crowdin-managed translation files. Set the system default language for the install, let each user pick their preferred language, and configure date format display. Translations are pulled from Crowdin into the codebase periodically; this article covers what's supported in-product and what to do when a translation gap matters.

Why this matters

For a multi-language organization (a global program, a multinational with non-English-speaking business units, a regulated industry where the regulator's language differs from the business's working language), having the application present in the user's own language matters. Users who can read the form labels and field descriptions submit better risks; users who can read the report labels review reports more carefully. The friction of "translate the screen in my head every time" produces worse outcomes than the cost of translation suggests.

SimpleRisk's localization is built on the standard PHP gettext pattern wrapped by a _lang($key, $params, $escape) helper. The translation files live in simplerisk/languages/ /lang. .php ; each is a PHP file returning a large associative array $lang['Key' => 'Translation']. The English source file (simplerisk/languages/en/lang.en.php) is the canonical key list; every other locale's file is maintained on Crowdin (https://crowdin.com) with translations contributed by the SimpleRisk community and by SimpleRisk customers.

The honest scope to know up front: language coverage varies by locale. The English source has thousands of keys; some locales have nearly complete coverage, others lag substantially. A user picking a less-translated locale sees mixed English-and-localized output where keys haven't been translated yet (the helper falls back to English when the localized value is missing). For programs that depend on full translation fidelity, the path is to contribute to Crowdin for the missing keys; you can't substitute translations directly in the codebase without losing them on the next Crowdin pull.

The other thing worth knowing: translation updates ship with releases. Crowdin translations are pulled into the SimpleRisk repository periodically (the recurring crowdin_testing PRs in the GitHub history). Each numbered release includes the translations available at the time of the release cut. To get newly-translated keys into your install, upgrade SimpleRisk; you don't pull from Crowdin yourself.

The third thing: only UI text is localized. User-entered content (risk descriptions, mitigation plans, audit findings) is stored as the user typed it. SimpleRisk doesn't auto-translate user content. A French user submitting a risk in French and an English user reviewing the risk see the same French description in both their views. For multi-language programs, settle on a working language for user-entered content (typically English for international consistency, sometimes the regional language for regional teams).

Before you start

Have these in hand:

  • Admin access to Configure → Settings for the system default language and date format.
  • A list of the languages your user base speaks and an awareness of which of those languages have substantial Crowdin coverage (the SimpleRisk community can confirm; or check the size of lang. .php relative to lang.en.php as a rough proxy).
  • A communication plan for users if you change the system default language. Existing users who haven't set a per-user preference will see the new default; tell them how to switch back if they want.
  • An understanding that the user-entered content language is a separate decision from the UI language. The two don't have to match (a French-speaking user can have UI in French and write risk descriptions in English), but you may want a program convention.

Step-by-step

1. Identify which languages you actually need

The full list of locales SimpleRisk ships with is in simplerisk/languages/. As of the current release, that includes (incomplete list, illustrative):

  • en — English (the source)
  • es — Spanish
  • fr — French
  • de — German
  • it — Italian
  • pt — Portuguese
  • nl — Dutch
  • ja — Japanese
  • ko — Korean
  • zh — Chinese
  • ru — Russian
  • ar — Arabic
  • … and 25+ more.

Check which of these your user base needs. There's no reason to enable everything; the per-user picker shows the locales installed in simplerisk/languages/, but most programs only need 2–5 locales actively.

2. Set the system default language

Sidebar: Configure → Settings. Find Default Language (default_language in the settings table). Pick the locale code (e.g., en, fr, de).

The system default applies when:

  • A user hasn't set a per-user language preference.
  • A new user is created and their language isn't specified at creation.
  • The login page is rendered (no user is logged in yet).

For most installs, the system default matches the working language of the headquarters. International deployments often leave it at en and rely on per-user preferences for non-English speakers.

3. Let users pick their per-user language

Each user has a language field on their user record. Users set their own:

  • My Account → Profile → Language dropdown.
  • The picker shows every locale present in simplerisk/languages/.
  • Save; the change takes effect on the next page load.

For new users, an admin can set the language at user creation via Configure → User Management → Add User → Language. For users who don't pick a preference, the system default applies.

4. Configure the date format

Date display in SimpleRisk is independent of language. Configure once per install via the date format setting (default_date_format in the settings table). The format string follows the project's date-format helper (get_default_date_format() converts the stored string to PHP's date() format and to JavaScript's date-display equivalents).

Common choices:

  • YYYY-MM-DD — ISO 8601, unambiguous internationally; preferred for any global program.
  • MM/DD/YYYY — US convention.
  • DD/MM/YYYY — European convention.
  • DD.MM.YYYY — German / Central European.

Pick one and stick with it. Mixed date formats across the install (some screens MDY, some DMY) produce confusion in any audit or report review.

5. Test the configuration with non-default users

Verify the per-user picker works:

  1. Create a test user with the language preference set to a non-English locale.
  2. Log in as that user.
  3. Confirm UI strings (form labels, dashboard tile labels, sidebar items) appear in the chosen locale.
  4. Note any strings that appear in English — these are missing translations in that locale's lang. .php file.

If translation coverage is unacceptable for your locale, contribute to Crowdin (see step 7).

6. Plan for translation gaps

Locales with incomplete translations show a mix of localized and English UI. Common gaps:

  • Recently-added features (the keys are new; translations haven't caught up yet).
  • Specialized terminology (some technical terms are kept in English even in localized contexts).
  • Long-form content (descriptions, help text) that's harder to translate well.

For high-impact gaps that block your users, the path is:

  • Crowdin: contribute the missing translations through https://crowdin.com (the SimpleRisk Crowdin project is publicly accessible; sign up and add translations).
  • After your translations are accepted into the Crowdin source, they ship in the next SimpleRisk release.
  • For urgent in-flight needs (you can't wait for the next release), you can edit simplerisk/languages/ /lang. .php directly — but this change is overwritten the next time SimpleRisk pulls from Crowdin (typically on each release). Treat the edit as a temporary patch with a planned permanent fix via Crowdin.

7. Contributing to Crowdin

The SimpleRisk Crowdin project accepts community contributions. To contribute:

  1. Create a Crowdin account.
  2. Find the SimpleRisk project (search Crowdin or use the link from SimpleRisk's translation documentation).
  3. Pick the locale you can contribute to.
  4. Translate the missing keys.
  5. Submit; SimpleRisk's release process pulls accepted translations into the codebase.

For organizations using SimpleRisk in a less-translated locale, organizing a one-time translation effort (an internal team contributing for a week) materially improves the locale for everyone using it. SimpleRisk's open-source posture invites this kind of contribution.

8. Avoid hardcoding English in customizations

Custom field names, custom risk-catalog entries, custom dropdown values (anything you add to the install) appear in the user's language only if pulled through _lang() and present in the lang.en.php source. Custom-field names you add via the Customization Extra are stored as you typed them; they're the same in every locale.

For programs deploying to multiple locales:

  • Pick custom-field names that are clear in your primary language; accept they won't auto-translate.
  • For custom field labels that absolutely need to be localized, manage two sets of fields (one per locale) — clunky but accurate.
  • For most programs, English custom-field names are an acceptable compromise (the field name is one element among many localized strings; the rest of the form is localized).

Common pitfalls

A handful of patterns recur with localization.

  • Editing lang. .php directly without contributing back to Crowdin. Your edits get overwritten on the next SimpleRisk release. Always contribute to Crowdin; treat direct edits as temporary patches.

  • Picking a locale with poor coverage and being surprised at the mixed UI. Check coverage before deploying for a user base that depends on a particular locale. A program rolling out in Hungarian when Hungarian coverage is at 40% will get user complaints.

  • Setting the date format inconsistently (one place uses YYYY-MM-DD, another uses MM/DD/YYYY). The default_date_format setting controls the system-wide display; don't override it in a way that produces inconsistency.

  • Assuming user-entered content is translated. Users entering risk descriptions in their own language produce records that other-language users see verbatim. Plan a working-language convention for user content if your program is multi-language.

  • Forgetting that the login page uses the system default language. If your system default is English and your users are mostly French, the login page is in English even though the in-app UI is French (per user preference). Match the system default to the dominant locale of unauthenticated visitors.

  • Treating language as the same as locale. A user's language setting affects UI strings; the default_date_format is independent. Some installs use English UI but European date formats; some use French UI with US date formats. Configure both deliberately.

  • Adding hardcoded English strings in custom integrations or scripts. Any UI text generated by a custom integration is in whatever language the integration produced it in. If your integration writes a comment to a risk that says "Updated by automated process," that's English regardless of the user's locale. Plan accordingly.

  • Not testing the UI in non-default locales after upgrades. A SimpleRisk upgrade may add new UI keys; locales with lagging translations may suddenly show more English. Spot-check after upgrades.

  • Confusing the language setting with regulatory documentation language. Some industries require regulatory documents in specific languages. SimpleRisk's UI language doesn't determine the language of generated PDF reports for regulators — those reports are generated from user-entered content (in whatever language the user typed) plus templates (in the locale's language). For regulator-facing reports, control the language of the user-entered content directly.

  • Removing locales from the codebase to reduce footprint. Don't. The locale files are small; removing them prevents users from picking those locales but doesn't free meaningful resources. If a locale isn't being used, leave it alone; if a future user needs it, it's already there.

Related

Reference

  • Permission required: check_admin for the system default language and date format settings. Per-user language is settable by the user themselves via My Account → Profile.
  • API endpoint(s): None specific to localization configuration.
  • Implementing files: simplerisk/includes/functions.php (_lang($key, $params=[], $escape=true) ~line 18514 — the central translation helper; update_language($uid, $language) — the per-user setter; get_default_date_format() — date format normalization).
  • Database tables: user (language column for per-user preference).
  • config_settings keys: default_language (system default locale code, e.g., en); default_date_format (system date format pattern).
  • Translation files: simplerisk/languages/ /lang. .php — one file per locale; managed via Crowdin (https://crowdin.com).
  • External dependencies: None at runtime; Crowdin for translation contributions.