Repository navigation
[2.x] feat(gambits): localization alias support — English keywords always work regardless of locale - #4570
Merged
Conversation
1 of 12 tasks
…ork regardless of locale Adds `canonicalKey()` and `canonicalPattern()` to `BooleanGambit` and `KeyValueGambit`. `GambitManager.match()` now tries the canonical English pattern as an alias when the translated pattern doesn't match, so English keywords like `is:hidden` or `author:behz` are always accepted even when the site locale has translated them. Fixes `SubscriptionFilter` accepting raw locale strings from the frontend; it now only accepts the stable canonical values `follow`/`ignore`. `SubscriptionGambit.toFilter()` maps matched keywords to canonical values before sending them to the API. Closes #4566
…on types
Adds a Flarum\Subscriptions\Extend\Subscription extender so third-party
extensions can register custom subscription types (e.g. 'lurk') with their
accepted filter aliases:
(new Extend\Subscription())
->addSubscriptionType('lurk', ['lurk', 'lurking', 'lurked'])
SubscriptionFilter now resolves values through a container-bound registry
('flarum-subscriptions.subscription_types') rather than a hardcoded match
expression. The built-in 'follow' and 'ignore' types are seeded by the
subscriptions extension's own extend.php via the same extender.
…tures - Add canonicalPattern() to the IGambit object literal in GambitsAutocomplete.tsx so it satisfies the updated interface (TS2345) - Add __esModule: true to the nanoid Jest mock so Jest's CJS/ESM interop resolves the named export correctly - Move lurk discussion/post/discussion_user fixtures into setUp() so the subscription_extender_registers_custom_type test can find them
Jest runs with --experimental-vm-modules which does real ESM linking, so CJS mock files cannot satisfy named ESM imports. Replace emptyModule.js and nanoid.js with proper .mjs equivalents using ESM export syntax. Fix SubscriptionFilterTest: seed the 'lurk-user' fixture under user 3 (not user 2) to avoid polluting the negation tests' result sets; switch negation assertions from assertEqualsCanonicalizing to assertContains/assertNotContains so they remain correct regardless of how many discussions exist. Replace the lurk custom-type test (which required seeding an invalid enum value) with a test that registers an additional alias for the existing 'follow' type, which is a valid use of the extender and exercises the same code path.
- Add canonicalKey() to the translated core and bundled gambits, so English keywords work in every locale, as the alias was meant to. - Keep the gambit's own group key (is/has/allows) in canonicalPattern(). - Make IGambit::canonicalPattern() optional, so gambits that implement the interface directly keep working. - Match subscription keywords without regard to case, in the gambit and in SubscriptionFilter, as the previous pattern did. - Write the subscription gambit back with the translated group key, and treat a legacy following/ignoring filter value correctly. - Drop the jest moduleNameMapper override and its mocks: it replaced @flarum/jest-config's own mappings and is no longer needed.
imorland
force-pushed
the
im/gambit-localization-alias
branch
from
October 19, 2026 18:22
1234807 to
870b30d
Compare
imorland
marked this pull request as draft
October 19, 2026 18:27
… of an extender Remove the Subscription extender. discussion_user.subscription only stores follow or ignore, so an extension could not store a new type it registered. SubscriptionFilter now maps its accepted values to those two directly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #4566
Changes proposed in this pull request:
Translating a gambit keyword broke search: subscriptions sent the translated word to an API filter that only understood English, and in a translated forum the English keywords stopped matching. Gambits now have a
canonicalKey()(defaulting tokey()), andGambitManagerfalls back to the English pattern when the translated one doesn't match. Every core and bundled gambit with a translated keyword returns its English keyword there. The subscription gambit always sendsfolloworignore, andSubscriptionFilteraccepts a fixed list of values in any case, returning no results for an unknown value instead of a 500.Reviewers should focus on:
canonicalPattern()is optional onIGambit, and a gambit that doesn't overridecanonicalKey()behaves as before, just without the English fallback.filter[subscription]=following(the following page, Deck) still works;follow/ignoreand any case are now accepted too.Screenshot
N/A
Necessity
Confirmed
yarn testinjs/).composer test).Required changes: