Uh oh!
There was an error while loading. Please reload this page.
Support arity-2 dynamic_children callback with locale - #506
Merged
Conversation
The admin sidebar's `dynamic_children` callback previously received only the current scope, forcing modules that render locale-aware child tabs (translated labels, locale-specific entities) to fall back on `Gettext.get_locale/1` at render time. That works but is implicit state and has to be re-derived whenever the locale changes. Add an arity-2 variant that receives `(scope, locale)` and dispatch on `Function.info/2` arity in `expand_dynamic_children/3`: - `dynamic_children_fn` type now accepts either `(scope -> [tab])` or `(scope, locale -> [tab])`. Both forms are valid; existing 1-arity implementations keep working unchanged. - `admin_sidebar/1` threads its `:locale` attr through to the helper. - `invoke_dynamic_children/3` picks the correct arity via `is_function/2` guards. This is a backward-compatible extension — every existing module that registers a 1-arity callback continues to be dispatched with the scope only, so no consumer changes are required. Modules that want locale can now opt in by adding a 2-arity clause. Motivation: `phoenix_kit_entities` currently reads `Gettext.get_locale(PhoenixKitWeb.Gettext)` inside its sidebar children function to render translated plural labels. Passing locale explicitly makes the contract clearer and decouples the sidebar from Gettext process state — useful for any plugin that needs locale-aware navigation. Tests assert the `dynamic_children_fn` type accepts both arities via `Tab.new!/1`. Verified: - `mix format` clean - `mix credo --strict` clean - Affected sidebar/language tests pass
5 tasks
ddon pushed a commit
that referenced
this pull request
Apr 24, 2026
- Per-user notifications driven by Activity.log fan-out; V104 migration, bell LiveView, Render, Types, Prefs, PruneWorker, UserSettings toggles (PR #505) - Admin sidebar dynamic_children_fn now accepts (scope, locale) in addition to (scope), backwards-compatible arity dispatch (PR #506) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ddon pushed a commit
that referenced
this pull request
Apr 24, 2026
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
timujinne added a commit
to timujinne/phoenix_kit
that referenced
this pull request
Apr 28, 2026
Brings in: - phoenix_kit_favicon component (PR BeamLabEU#504) - Per-user notifications module (V104) - dynamic_children/2 with locale (PR BeamLabEU#506) - arity-2 dynamic_children callbacks (PR BeamLabEU#505) - Bump to 1.7.101 - Claude review docs for PRs BeamLabEU#505/506
mdon added a commit
to mdon/phoenix_kit
that referenced
this pull request
May 2, 2026
PR BeamLabEU#506 (Support arity-2 dynamic_children callback with locale, merged 2026-04-24) was APPROVED with two NITPICKs. Both closed: ## Test coverage was half-tautological The previous `"invoke_dynamic_children/3 dispatch"` describe block defined two anonymous functions, invoked them with `.(%{})` and `.(%{}, "en-US")`, and asserted the counters incremented. As Claude's review pointed out, that tested Elixir's function-call semantics rather than the sidebar's actual dispatch logic. Added a `@doc false` test-only delegate `AdminSidebar.__invoke_dynamic_children_for_test__/3` that calls the private `invoke_dynamic_children/3`, then rewrote the describe block with four assertion-pinned tests: - arity-1 callback receives only the scope - arity-2 callback receives both scope and locale - arity-2 callback handles a nil locale gracefully - return value is propagated unchanged The delegate carries an explicit `@doc false` so it's not part of the runtime surface — it exists solely to let the unit suite reach the private dispatcher without coupling to LV rendering. ## @TypeDoc on dynamic_children_fn The inline `#` comment above `@type dynamic_children_fn` wasn't picked up by ExDoc / `h Tab`. Replaced with a `@typedoc` block that documents both arities, the explicit-locale rationale, and the `nil` semantic. `mix test` for the test file: 6 tests, 0 failures (2 original + 4 new). `mix format`, `mix credo --strict` clean, `mix compile --warnings-as-errors` clean. PR-folder FOLLOW_UP.md filed under `dev_docs/pull_requests/2026/506-dynamic-children-locale/`.
7 tasks
mdon added a commit
to mdon/phoenix_kit
that referenced
this pull request
May 2, 2026
PR BeamLabEU#506 (Support arity-2 dynamic_children callback with locale, merged 2026-04-24) was APPROVED with two NITPICKs. Both closed: ## Test coverage was half-tautological The previous `"invoke_dynamic_children/3 dispatch"` describe block defined two anonymous functions, invoked them with `.(%{})` and `.(%{}, "en-US")`, and asserted the counters incremented. As Claude's review pointed out, that tested Elixir's function-call semantics rather than the sidebar's actual dispatch logic. Added a `@doc false` test-only delegate `AdminSidebar.__invoke_dynamic_children_for_test__/3` that calls the private `invoke_dynamic_children/3`, then rewrote the describe block with four assertion-pinned tests: - arity-1 callback receives only the scope - arity-2 callback receives both scope and locale - arity-2 callback handles a nil locale gracefully - return value is propagated unchanged The delegate carries an explicit `@doc false` so it's not part of the runtime surface — it exists solely to let the unit suite reach the private dispatcher without coupling to LV rendering. ## @TypeDoc on dynamic_children_fn The inline `#` comment above `@type dynamic_children_fn` wasn't picked up by ExDoc / `h Tab`. Replaced with a `@typedoc` block that documents both arities, the explicit-locale rationale, and the `nil` semantic. `mix test` for the test file: 6 tests, 0 failures (2 original + 4 new). `mix format`, `mix credo --strict` clean, `mix compile --warnings-as-errors` clean. PR-folder FOLLOW_UP.md filed under `dev_docs/pull_requests/2026/506-dynamic-children-locale/`.
ddon added a commit
that referenced
this pull request
May 2, 2026
Add V108 + drag-and-drop core + PR #506 review follow-up
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 freeto 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
Extends
Tab.dynamic_children_fnto support a 2-arity variant that receives(scope, locale)so admin sidebar modules can render locale-aware child tabs without falling back onGettext.get_locale/1at render time.Why
phoenix_kit_entitiesalready supports per-locale sidebar tabs for its dynamic child list — translateddisplay_name_plurallabels on/es/admin/entities, etc. With only the 1-arity callback available, the module has to readGettext.get_locale(PhoenixKitWeb.Gettext)at render time. That works, but it's implicit state and couples the plugin to Gettext process state instead of the explicit contract.This change gives plugins an explicit locale argument. It's a pure extension — every existing 1-arity callback keeps working unchanged.
Changes
lib/phoenix_kit/dashboard/tab.ex:dynamic_children_fntype now accepts(scope -> [t])or(scope, locale -> [t]).lib/phoenix_kit_web/components/dashboard/admin_sidebar.ex:expand_dynamic_children/3threadsassigns[:locale]through;invoke_dynamic_children/3dispatches onis_function/2/is_function/3. TheEnum.split_withguard accepts both arities.Backward compatibility
No breaking change. Every module currently registering a 1-arity callback will continue to be dispatched with scope only. Modules can opt in to the 2-arity variant independently —
phoenix_kit_entitiesis the first consumer (see companion PR on that repo).Test plan
mix formatcleanmix credo --strictclean (no new issues, 7391 mods/funs, 0 issues)test/phoenix_kit_web/components/admin_sidebar_dynamic_children_test.exs— asserts both arities are validdynamic_children_fnvalues viaTab.new!/1/:locale/admin/entitiesafterphoenix_kit_entitiesis upgraded to a 2-arity callback — translated plural labels should appear in the sidebar without a Gettext fallback