Skip to content

TMS-1237: Add a custom Google Translate functionality to navigation#560

Open
eebbi wants to merge 13 commits intomasterfrom
TMS-1237
Open

TMS-1237: Add a custom Google Translate functionality to navigation#560
eebbi wants to merge 13 commits intomasterfrom
TMS-1237

Conversation

@eebbi
Copy link
Copy Markdown
Contributor

@eebbi eebbi commented Mar 13, 2026

Project: Tampereen kaupunki, konsernihallinto / Tietohallintoyksikkö:
Project task: Tampereen kaupunki, konsernihallinto / Tietohallintoyksikkö Continuous development

Task: https://hiondigital.atlassian.net/browse/TMS-1237
Task title: Google translatorin ilmainen WP-lisäosa käyttöön

Description

Add a custom Google Translate functionality to navigation:

  • Custom js code for Google Translate script functionality
  • Dropdown-element in headers partial
  • Toggle-field for showing the translate dropdown in site settings

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

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 an optional Google Translate dropdown to the site header navigation, controlled via Site Settings, with supporting frontend controller, styles, icons, and localization updates.

Changes:

  • Adds a header dropdown UI for Google Translate plus a JS controller that loads the Google Translate API with Cookiebot-consent gating.
  • Introduces a Site Settings (ACF) toggle to enable/disable the translate dropdown.
  • Updates strings/translations and adds styling + icon assets for the new dropdown.

Reviewed changes

Copilot reviewed 16 out of 19 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
partials/ui/menu/language-nav.dust Adds notranslate to prevent Google Translate from translating language nav UI.
partials/ui/menu/language-nav-dropdown.dust Adds notranslate to prevent Google Translate from translating language nav UI.
partials/ui/menu/gtranslate-dropdown.dust New translate dropdown markup in the header.
partials/shared/header-inner.dust Renders the new dropdown when enabled via header model data.
models/strings.php Adds a new header string for the translate trigger label.
models/shared/header.php Adds gtranslate_menu() providing dropdown texts and current language + settings gate.
lib/ACF/Fields/Settings/HeaderSettingsTab.php Adds an ACF Site Settings toggle (enable_gtranslate_menu).
lang/tms-theme-base.pot Updates POT catalog; now includes new strings (and other extracted entries).
lang/sv_SE.po Updates Swedish translations for new strings.
lang/sv_SE.mo Adds/updates compiled Swedish MO.
lang/fi.po Updates Finnish translations for new strings.
lang/fi.mo Adds/updates compiled Finnish MO.
assets/styles/ui-components/index.scss Includes the new gtranslate dropdown stylesheet.
assets/styles/ui-components/header/_gtranslate-dropdown.scss Adds styling for the dropdown and Cookiebot messaging.
assets/scripts/theme.js Registers the new global controller.
assets/scripts/gtranslate-dropdown.js New controller: dropdown behavior + Cookiebot consent flow + API loading/init.
assets/icons/index.js Registers the new translate icon in the sprite build.
assets/icons/icon-translate.svg Adds the translate icon SVG asset.
CHANGELOG.MD Documents the new feature under Unreleased.

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

Comment on lines +187 to +200
const script = document.createElement( 'script' );
script.src = 'https://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit';
script.setAttribute( 'data-cookieconsent', 'preferences' );
script.async = true;
document.head.appendChild( script );
this.isGoogleLoaded = true;

// Define the callback function globally
window.googleTranslateElementInit = this.initGoogleTranslate.bind( this );

// Check if the script loaded successfully after a short delay
setTimeout( () => {
this.checkGoogleTranslateLoaded();
}, this.gtranslateCheckDelay );
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

The Google Translate callback (window.googleTranslateElementInit) is assigned after the script tag is appended. Because the API script calls the cb= function as soon as it executes, there’s a race where the callback may be undefined. Define the global callback before appending the script (or set script.onload and initialize from there).

Copilot uses AI. Check for mistakes.
}

$current_lang = DPT_PLL_ACTIVE ? \pll_current_language() : \get_locale();

Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

current_language is populated from get_locale() when Polylang is inactive; WordPress locales can include region (e.g. sv_SE), but Google Translate’s pageLanguage typically expects a language code (e.g. sv). Consider normalizing the locale (split on _/- and use the language part) so the widget initializes reliably across locales.

Suggested change
// When Polylang is inactive, get_locale() may return a locale with region (e.g. "sv_SE").
// Normalize this to a language code (e.g. "sv") for Google Translate compatibility.
if ( ! DPT_PLL_ACTIVE && is_string( $current_lang ) ) {
$parts = preg_split( '/[_-]/', $current_lang );
if ( ! empty( $parts ) && is_string( $parts[0] ) && $parts[0] !== '' ) {
$current_lang = $parts[0];
}
}

Copilot uses AI. Check for mistakes.
Comment on lines +2 to +4
.is-open {
display: block !important;
}
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

.is-open inside .gtranslate-wrapper is not used by the JS controller (it toggles is-hidden). This looks like dead/mismatched styling and the !important makes it harder to reason about. Either align the JS to toggle an is-open modifier or remove this rule and rely on the existing is-hidden toggling.

Suggested change
.is-open {
display: block !important;
}

Copilot uses AI. Check for mistakes.
Comment on lines +2 to +8
<button class="gtranslate-trigger p-0 has-border-radius-small" aria-expanded="false" aria-haspopup="true" aria-controls="js-gtranslate-dropdown">
<span class="is-sr-only">{Strings.s.header.translate|html}</span>
{>"ui/icon" icon="icon-translate" class="icon--xlarge" /}
</button>

<div id="js-gtranslate-dropdown" class="gtranslate-dropdown p-4 is-hidden is-absolute" role="menu" aria-labelledby="gtranslate-trigger">
<div class="gtranslate-dropdown__content">
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

aria-labelledby="gtranslate-trigger" points to an element id that doesn't exist (the trigger button has no id). This breaks the ARIA relationship for assistive tech; add an id to the button and make aria-labelledby reference it (or remove/adjust the attribute if you don’t want a label-by relationship). Also consider whether role="menu" is appropriate here—if kept, the content should follow menu semantics; otherwise use a more suitable role or no explicit role.

Copilot uses AI. Check for mistakes.
Comment on lines +22 to +24
<a href="javascript:Cookiebot.renew()" class="button is-primary">
{Header.gtranslate_menu.accept_cookies|html}
</a>
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

Avoid href="javascript:..." URIs. They can conflict with CSP/hardening and are generally discouraged; use a real button/link and attach the Cookiebot renew action via JS (and/or guard for missing window.Cookiebot).

Suggested change
<a href="javascript:Cookiebot.renew()" class="button is-primary">
{Header.gtranslate_menu.accept_cookies|html}
</a>
<button type="button" class="button is-primary js-cookiebot-renew">
{Header.gtranslate_menu.accept_cookies|html}
</button>

Copilot uses AI. Check for mistakes.
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.

2 participants