Skip to content

feat(map): display OpenHistoricalMap labels in user's preferred language#1056

Merged
DavidMStraub merged 6 commits intogramps-project:mainfrom
mahula:feature/ohm-language-labels
Apr 8, 2026
Merged

feat(map): display OpenHistoricalMap labels in user's preferred language#1056
DavidMStraub merged 6 commits intogramps-project:mainfrom
mahula:feature/ohm-language-labels

Conversation

@mahula
Copy link
Copy Markdown
Contributor

@mahula mahula commented Apr 8, 2026

Motivation

OpenHistoricalMap (OHM) displays map labels in the default local contemporary language by default. Users expect map labels to appear in their preferred language matching the application's frontend language setting, as requested in issue #493 and the related forum topic.

Since OHM serves vector tiles, it supports on-the-fly language switching via the ?language=<ISO-639-code> URL parameter (see openhistoricalmap-embed#8). This PR implements that mechanism.

Changes

Problem: Locale code mismatch

Frontend locales use regional variants (e.g., de_AT, en_GB, pt_BR) while OpenHistoricalMap only supports base ISO 639-1 codes (de, en, pt). Without normalization, users with de_AT locale would not get German labels as OHM wouldn't recognize the code.

Solution

  1. Added OHM_LOCALE_MAP in src/util.js — maps all frontend locales to their OHM-compatible base codes:

    • de_ATde, en_GBen, pt_BRpt, etc.
    • Base codes map to themselves unchanged
  2. Added normalizeOhmLocale() in src/util.js — converts frontend locale codes to OHM-compatible codes with explicit fallback chain:

    • Returns mapped value if found in OHM_LOCALE_MAP
    • Falls back to extracting base code (split('_')[0])
    • Falls back to 'en' for null/undefined/empty/unknown
  3. Modified _getStyleUrl() in src/components/GrampsjsMap.js:

    • When OHM layer is selected, appends ?language=<locale> to the style URL

How to Test

Manual Testing

  1. Set browser language to a specific locale (e.g., German de-AT in browser settings)
  2. Navigate to the Map view
  3. Select "Historical Map" layer from the layer switcher
    OpenHistoricalMap: requesting labels in locale "de" (frontend locale: "de_AT")
    
  4. Verify map labels appear in German (not the default local contemporary names)

Supported Locales

The feature works with all frontend locales. Key regional variants that normalize correctly:

  • de_AT, de_DE → German labels
  • en_GB, en_US → English labels
  • pt_BR, pt_PT → Portuguese labels
  • zh_CN, zh_HK, zh_TW → Chinese labels

Fallback Behavior

If a locale is not supported by OHM (e.g., a future locale not in the map), it falls back to the base code. If no base code is available, defaults to English.

Unit Tests

Run the new test suite:

npm test -- test/unit/mapOhmLocale.test.js

Tests cover:

  • Base language code mapping (dede)
  • Regional variant normalization (de_ATde)
  • Fallback for undefined, null, empty string
  • Unknown locale handling with base code extraction
  • Edge cases (multiple underscores, locales not in map)

Files Changed

  • src/components/GrampsjsMap.js — added language parameter to OHM style URL
  • src/util.js — added OHM_LOCALE_MAP and normalizeOhmLocale()
  • test/unit/mapOhmLocale.test.js — new comprehensive test suite

Related Issue

Fixes #493

mahula added 2 commits April 8, 2026 09:43
When the OpenHistoricalMap layer is selected, append the language
parameter (?language=<locale>) to the style URL so that map labels
are displayed in the user's preferred language matching the frontend
locale setting.

Fixes gramps-project#493
- Add OHM_LOCALE_MAP in util.js for mapping frontend locales (de_AT, en_GB,
  pt_BR, etc.) to OpenHistoricalMap-compatible ISO 639-1 codes (de, en, pt)
- Add normalizeOhmLocale() function with explicit fallback chain
- Add debug logging when OHM style is requested showing the locale mapping
- Add comprehensive unit tests covering:
  - Base language code mapping
  - Regional variant normalization
  - Fallback behavior for undefined/null/empty/unknown locales
  - OHM_LOCALE_MAP completeness validation

Fixes gramps-project#493
Comment thread src/components/GrampsjsMap.js Outdated
@DavidMStraub
Copy link
Copy Markdown
Member

Thanks for looking into this! Great if it's that simple 🙂

@DavidMStraub DavidMStraub self-requested a review April 8, 2026 09:16
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds OpenHistoricalMap (OHM) label-language selection so the historical map layer’s labels align with the app’s current frontend locale, addressing issue #493.

Changes:

  • Introduces OHM_LOCALE_MAP and normalizeOhmLocale() to normalize frontend locales (e.g., de_AT) to OHM-compatible base codes (e.g., de).
  • Updates GrampsjsMap to append ?language=<code> when selecting the OHM style.
  • Adds unit tests covering locale normalization and mapping completeness.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
src/components/GrampsjsMap.js Appends an OHM language query parameter based on current frontend language.
src/util.js Adds locale mapping constant and normalization helper for OHM language codes.
test/unit/mapOhmLocale.test.js Adds tests for locale normalization behavior and mapping coverage.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/components/GrampsjsMap.js Outdated
Comment thread src/components/GrampsjsMap.js
Comment thread src/util.js
Comment thread test/unit/mapOhmLocale.test.js Outdated
Comment thread src/components/GrampsjsMap.js
mahula added 3 commits April 8, 2026 11:53
Use URL.searchParams.set() instead of string interpolation to properly
handle OHM style URLs that may already contain query parameters.

Fixes potential issue noted in PR review.
…uplicating

Removes hardcoded frontendLanguages list from test file to avoid
maintenance duplication. Now imports from src/strings.js directly.
Clarify the actual fallback chain in the JSDoc comment:
1. Falsy locale → 'en'
2. In OHM_LOCALE_MAP → use mapped value
3. Unknown locale with base code → extract base code
4. No base code available → 'en'

Also add null to @param type since function handles it in practice.
@DavidMStraub
Copy link
Copy Markdown
Member

Can you please close the comments once you address them with a reply what you did about them, so I don't have to dig through everything myself once more, thanks

@mahula
Copy link
Copy Markdown
Contributor Author

mahula commented Apr 8, 2026

Can you please close the comments once you address them with a reply what you did about them, so I don't have to dig through everything myself once more, thanks

The Copilit comments are commented with the commit references.
Another proper way to re-review thhe pull request after changes made required by a reviewer, could be, asking Copilot to review the updated pull request again.

@DavidMStraub
Copy link
Copy Markdown
Member

Thanks!

asking Copilot to review the updated pull request again.

I know, but using this a lot recently (sometimes getting 3 or 4 copilot reviews on my own PRs) I know it's often quite random whether it picks up its previous commit and related changes or not. So better to have a human confirm it.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@DavidMStraub DavidMStraub merged commit 86f3402 into gramps-project:main Apr 8, 2026
5 checks passed
@mahula mahula deleted the feature/ohm-language-labels branch April 8, 2026 11:24
@1ec5
Copy link
Copy Markdown
Contributor

1ec5 commented Apr 8, 2026

Oh hey, I didn’t realize you were working on this, glad to see it. In case you’re interested, I’m working on a new Diplomat plugin for localizing any MapLibre style. It’s a lot more thorough than what either of us have implemented for OHM so far. OpenHistoricalMap/openhistoricalmap-embed#39 would migrate to that plugin. Unfortunately it’s held up by a pesky font issue in the stylesheet, but only because I was looking to use Diplomat’s dual language labeling feature. If you don’t enable that, then it works just fine.

@mahula
Copy link
Copy Markdown
Contributor Author

mahula commented Apr 8, 2026

In case you’re interested, I’m working on a new Diplomat plugin for localizing any MapLibre style. It’s a lot more thorough than what either of us have implemented for OHM so far. OpenHistoricalMap/openhistoricalmap-embed#39 would migrate to that plugin.

That sounds great.
What do you think about - when the plugin is ready - opening a pull request using it to replace the current solution?

Unfortunately it’s held up by a pesky font issue in the stylesheet, but only because I was looking to use Diplomat’s dual language labeling feature. If you don’t enable that, then it works just fine.

Even if off-topic here, if there is an issue about the font related blockage, I would offer support with reviewing end maybe helping to test or fix it.

@1ec5
Copy link
Copy Markdown
Contributor

1ec5 commented Apr 9, 2026

Diplomat is more or less ready to use. I’m just waiting for some feedback about the API design before releasing a v1.0.

The font issue is OpenHistoricalMap/issues#1258. The fix might just be to drop the remote fonts from the stylesheet altogether.

@DavidMStraub
Copy link
Copy Markdown
Member

That sounds great! I think it might be better then to directly implement this rather than the partial solution in this PR.

@DavidMStraub
Copy link
Copy Markdown
Member

That sounds great! I think it might be better then to directly implement this rather than the partial solution in this PR.

Forgot that I merged this already 😆 so let's ship the workaround and then switch to the better solution in the next release.

DavidMStraub added a commit that referenced this pull request Apr 10, 2026
@DavidMStraub
Copy link
Copy Markdown
Member

I had to revert the change because it had no effect whatsoever - the query argument is ignored by OHM.

@mahula did you test this locally?

@mahula
Copy link
Copy Markdown
Contributor Author

mahula commented Apr 10, 2026

I had to revert the change because it had no effect whatsoever - the query argument is ignored by OHM.

@mahula did you test this locally?

Not thoroughly enough.

The Diplomat plugin will be the proper solution for the issue #493

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OpenHistoricalMap labels should be in the preferred language

4 participants