Skip to content

feat(i18n): add fr_CA translation and apply string context rule #minor - #19

Open
Revenantal wants to merge 12 commits into
mainfrom
feature/translations
Open

Revenantal wants to merge 12 commits into
mainfrom
feature/translations

Conversation

@Revenantal

@Revenantal Revenantal commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Context

Wicket: none
Related PRs: industrialdev/wicket-wp-base-plugin#63, industrialdev/wicket-wp-account-centre#58, industrialdev/wicket-wp-financial-fields#10

What

  • Adds languages/wicket-theme.pot and a Canadian French (fr_CA) translation (.po, .mo, .l10n.php) for all 788 strings, including ACF field strings and plurals.
  • Applies the short-string context rule across the theme and its ACF field strings.
  • Scopes ACF translation to the theme's own fields and merges split strings.

Why

Theme strings were missing context, some were glued together from fragments, and ACF translation used a site-wide filter that affected plugin and child-theme field groups. Wicket now ships fr_CA, following the Atlas translations convention (conv.stack.translations).

How

Contexts and strings

  • Every 1 to 3 word string gets a gettext context that names its kind. Full sentences drop their contexts.
  • "Published:", "Results for:", "Displaying:" and "Search Results for:" are merged with their values into whole strings. The publish date now uses the site date format, and the breadcrumb search term is escaped.
  • Search and listing result counts use real plurals.
  • Translator comments are added to ambiguous strings that already existed on main. Their msgids are unchanged, so the legacy wicket domain fallback still works.
  • The product button now reads "Log in to Purchase" (verb).

ACF

  • An acf/prepare_field filter replaces the site-wide acf/settings/l10n_textdomain filter. It translates only fields from the theme's acf-json.
  • composer i18n:acf generates languages/acf-strings.php for make-pot.

Fixes and tooling

  • Replaces the nonexistent esc_html_ex() with echo esc_html_x(). It would have fataled on the fallback index template and the pagination demo.
  • The .pot hook runs faster, supports .ci/pot-exclude, and excludes font-awesome/.

Impact on existing translations

Re-contexted strings no longer match existing site translations. We accepted this because client translation coverage is under 1% and fr_CA now ships with the theme. Site-level translations (Loco, wp-content/languages) still take precedence.

alex91ckua and others added 11 commits September 28, 2026 11:30
The theme's strings moved from the base plugin's 'wicket' domain to the
new 'wicket-theme' domain. Legacy sites already translated these strings
under 'wicket' in Loco (.mo files) or WPML (database). After the move,
those translations no longer match, so the text would show in English.

The shim filters the 'wicket-theme' gettext calls (plain, context, and
plural). When a string has no 'wicket-theme' translation, it looks it up
under 'wicket' again. 'wicket-theme' stays the default and wins when it
has a translation. New sites translate under 'wicket-theme' only.

Remove the shim when legacy sites move their translations to
'wicket-theme'.
- Title color -> Title colour (Featured Posts)
- Blur Color -> Blur Colour (Drop Shadows instructions)
- Center -> Centre (Banner text alignment label; value stays "center")
- Add .ci/hooks/update-pot, which regenerates languages/<text-domain>.pot
  from the staged files. `composer setup-hooks` installs it as the
  pre-commit hook. It uses `wp` on PATH, or downloads a pinned,
  checksum-verified WP-CLI into the user cache. It never blocks a commit.
- Add a PR check that fails when the committed .pot is out of date.
- Read extra comma-separated exclude paths from .ci/pot-exclude.
- Leave excluded paths out of the staged snapshot, so large folders
  are not copied.

- Exclude font-awesome/ from the theme's .pot scan.
…t strings

- Replace the site-wide acf/settings/l10n_textdomain filter with an
  acf/prepare_field filter that translates only fields from the theme's
  acf-json, so plugin and child-theme ACF groups keep their own domains.
- Add .ci/acf-i18n-strings.php (composer i18n:acf) to generate
  languages/acf-strings.php, which lets make-pot extract ACF field strings.
- Give strings added on this branch an _x()/_nx() context and use proper
  plurals for search and listing result counts.
- Merge "Published:", "Results for:", "Displaying:" and "Search Results for:"
  with their values into whole strings. The publish date now uses the site
  date format and the search term in the breadcrumb is escaped.
- Add translator comments to ambiguous strings that existed on main; their
  msgids are unchanged so the legacy 'wicket' domain fallback keeps working.
- Use "Log in to Purchase" (verb) for the product button.
- Add languages/fr_CA.po covering all 788 strings in wicket-theme.pot,
  including ACF field strings and plurals, with Canadian French terminology
  and typography.
- Add the compiled .mo and WordPress 6.5+ .l10n.php files.

Site-level translations (Loco, wp-content/languages) still take precedence.
esc_html_ex() is not a WordPress function; the two calls added in 88b603b
would fatal on the fallback index template and the pagination demo.
- Give every string of 1 to 3 words a gettext context and drop contexts from
  full sentences, following the Atlas translations convention.
- Contexts name the kind of string (label, button label, status, message,
  accessibility label, ...), not where it shows, so identical strings with the
  same meaning share one translation entry. Specific contexts are kept only
  where the same text has a different meaning (role name, relationship type).
- ACF field strings follow the same rule in the runtime translator and the
  languages/acf-strings.php generator.

Changes msgids' contexts, so existing site translations of these keys stop
matching; accepted because client coverage is under 1% and Wicket ships fr_CA.

@EstebanForge EstebanForge left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approved. Third PR, same bar, and it holds. What I verified:

  • msgfmt --check passes on the fr_CA catalog (771 messages), the shipped .mo matches, .l10n.php and acf-strings.php (516 ACF strings) are valid, and the CI pot check is green.
  • style.css only gains the Text Domain and Domain Path headers. No manual version bump, the release bot stays in charge.
  • load_theme_textdomain runs inside wicket_setup() on after_setup_theme, and the fr_CA.mo naming matches the theme convention. The legacy wicket fallback filters follow the same four-variant pattern as the base plugin, registered before init. Cross-package behavior is consistent.
  • The ACF translator is key-guarded to this theme's own acf-json, and the generator is the same one as account-centre with the theme paths swapped.
  • post-types.php fixes the old untranslatable patterns: _x($singular) variable msgids and 'Add New ' . $singular fragments are now proper %s templates. Raw slugs stay untranslated on purpose, with a comment saying why. Good.
  • The dead hide-wp-admin-notifications textdomain loader is gone (its path never existed), and those strings moved to wicket-theme.

Two notes, nothing to fix:

  1. The listing sort labels came from a third dead domain, industrial, not wicket. The fallback only covers wicket, so any client that translated those four strings through an industrial textdomain loses them. Same accepted risk class as the other PRs, just a different corpse.
  2. One ACF instruction string ("Use this to add custom fonts from CDN...") contains a literal \r\n in the source, and the fr translation mirrors it, so msgfmt emits a warning. Harmless, but cleaning the source string someday would silence it.

Thanks Adrian, the set is consistent across the three packages.

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.

3 participants