Summary
Refactor route parameter dispatch so controller actions no longer need explicit unused $lang arguments just to preserve parameter ordering when multilingual URL segments are enabled.
The framework should continue to support configurable language detection through lang.url_segment, and $lang should remain available when an action explicitly requests it, but controller and generated template action signatures should no longer be forced to include it as positional boilerplate.
Why
The project already supports configurable language detection from the URL through lang.url_segment, for example:
return [
'enabled' => true,
'supported' => ['en', 'es'],
'default' => 'en',
'url_segment' => 1,
];
Current language detection is already handled at the framework level through the request/route flow and LangFactory.
However, many DemoWeb and DemoApi controller actions still need to declare unused parameters such as:
public function post(Request $request, ?string $lang, string $postUuid): Response
or:
public function delete(?string $lang, string $uuid): Response
This is not because the action needs direct access to the current language. It happens because:
- multilingual routes prepend an optional URL segment such as
[:alpha:2]?
- unnamed route segments are compiled into positional route params such as
_segment0
- scalar action arguments are currently resolved positionally during dispatch
- later real route parameters such as
uuid are therefore shifted unless the action reserves a placeholder argument for the language segment
As a result, the current multilingual route setup leaks framework routing mechanics into controller method signatures.
Goal
Preserve configurable multilingual URL segment handling while removing the need for fake/unused $lang parameters in controller actions and generated templates.
At the same time, if an action explicitly requests $lang, it should still be available intentionally rather than disappearing completely from action injection.
Proposed Direction
Refactor routing/dispatch behavior so the configured language URL segment is treated as framework-owned route context rather than a normal positional controller argument.
The implementation should preserve:
lang.url_segment
- current language detection behavior
current_lang() usage
- existing multilingual URL behavior
But it should stop forcing controller actions to declare unused $lang parameters solely to keep later route parameters aligned.
If an action explicitly declares string $lang or ?string $lang, the current language should still be available through intentional injection rather than positional leakage.
Examples
Current undesired pattern:
public function post(Request $request, ?string $lang, string $postUuid): Response
{
// $lang is unused
}
Desired common behavior:
public function post(Request $request, string $postUuid): Response
{
}
Desired explicit access when needed:
public function post(Request $request, ?string $lang, string $postUuid): Response
{
// $lang is intentionally requested here
}
Current language access should also continue to work through framework state such as:
Acceptance Criteria
- configurable
lang.url_segment behavior remains supported
- current language detection from URL segments continues to work
- controller actions no longer need unused
$lang arguments solely because of multilingual route parameter ordering
- if an action explicitly requests
$lang, it remains available intentionally
- generated DemoWeb and DemoApi controller signatures can be simplified accordingly
- the routing/dispatch change does not break ordinary non-language route parameters such as
uuid, token, or code
- tests cover multilingual route matching and controller argument resolution with configured language URL segments
Notes
Relevant code:
src/Router/PatternCompiler.php
src/Router/RouteDispatcher.php
src/Di/DiContainer.php
src/Lang/Factories/LangFactory.php
src/Module/Templates/DemoWeb/src/routes/routes.php.tpl
src/Module/Templates/DemoApi/src/routes/routes.php.tpl
- DemoWeb and DemoApi controller templates containing unused
$lang arguments
Summary
Refactor route parameter dispatch so controller actions no longer need explicit unused
$langarguments just to preserve parameter ordering when multilingual URL segments are enabled.The framework should continue to support configurable language detection through
lang.url_segment, and$langshould remain available when an action explicitly requests it, but controller and generated template action signatures should no longer be forced to include it as positional boilerplate.Why
The project already supports configurable language detection from the URL through
lang.url_segment, for example:Current language detection is already handled at the framework level through the request/route flow and
LangFactory.However, many DemoWeb and DemoApi controller actions still need to declare unused parameters such as:
or:
This is not because the action needs direct access to the current language. It happens because:
[:alpha:2]?_segment0uuidare therefore shifted unless the action reserves a placeholder argument for the language segmentAs a result, the current multilingual route setup leaks framework routing mechanics into controller method signatures.
Goal
Preserve configurable multilingual URL segment handling while removing the need for fake/unused
$langparameters in controller actions and generated templates.At the same time, if an action explicitly requests
$lang, it should still be available intentionally rather than disappearing completely from action injection.Proposed Direction
Refactor routing/dispatch behavior so the configured language URL segment is treated as framework-owned route context rather than a normal positional controller argument.
The implementation should preserve:
lang.url_segmentcurrent_lang()usageBut it should stop forcing controller actions to declare unused
$langparameters solely to keep later route parameters aligned.If an action explicitly declares
string $langor?string $lang, the current language should still be available through intentional injection rather than positional leakage.Examples
Current undesired pattern:
Desired common behavior:
Desired explicit access when needed:
Current language access should also continue to work through framework state such as:
current_lang()Acceptance Criteria
lang.url_segmentbehavior remains supported$langarguments solely because of multilingual route parameter ordering$lang, it remains available intentionallyuuid,token, orcodeNotes
Relevant code:
src/Router/PatternCompiler.phpsrc/Router/RouteDispatcher.phpsrc/Di/DiContainer.phpsrc/Lang/Factories/LangFactory.phpsrc/Module/Templates/DemoWeb/src/routes/routes.php.tplsrc/Module/Templates/DemoApi/src/routes/routes.php.tpl$langarguments