[2.x] feat(gambits): localization alias support — English keywords always work regardless of locale#4570
Open
[2.x] feat(gambits): localization alias support — English keywords always work regardless of locale#4570
Conversation
…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
2 tasks
…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.
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.
Summary
Resolves #4566.
canonicalKey()andcanonicalPattern()toBooleanGambitandKeyValueGambit. Both default tokey(), so extensions that don't translate their keywords require no changes.GambitManager.match()now tries the canonical English pattern as a second-pass alias when the translated pattern doesn't match — English keywords (is:hidden,author:behz, etc.) are always accepted regardless of the active locale.SubscriptionFilterto accept only stable canonical values (follow/ignore) instead of raw locale strings leaking from the frontend.SubscriptionGambit.toFilter()now maps matched surface keywords to canonical values before sending them to the API.subscriptionfilter values now return an empty result set (WHERE 0 = 1) rather than crashing with aTypeErroror returning all discussions.Flarum\Subscriptions\Extend\Subscriptionextender so third-party extensions can register custom subscription types with their accepted filter aliases:Extension authors
If your gambit's
key()returns a translated string viaapp.translator.trans(), add acanonicalKey()override returning the hardcoded English keyword. That's the only change needed. See the companion docs PR flarum/docs#524 for full guidance.Test plan
SubscriptionFilterTest— covers canonical values, surface aliases, negation, unrecognised values, and theSubscriptionextender (custom type registration + unregistered alias still returns empty)IGambit.test.ts— regression tests for all built-in gambit classes + TDD tests forcanonicalKey()/canonicalPattern()GambitManager.test.ts— regression tests + localization alias describe block (translated vs canonical produce identical output, negation, unmatched keywords not consumed)