Skip to content

Fix URL parameter type for filter rules without frontend filter widget - #1585

Open
zonky2 wants to merge 1 commit into
hotfix/2.4.25from
hotfix/fix_slugget_parameter_detail_page
Open

Fix URL parameter type for filter rules without frontend filter widget#1585
zonky2 wants to merge 1 commit into
hotfix/2.4.25from
hotfix/fix_slugget_parameter_detail_page

Conversation

@zonky2

@zonky2 zonky2 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

The URL parameter type ("URL type for the parameter") introduced with #1558 and fixed up in #1563 was only honoured for filter rules that render a frontend filter widget. ListControllerTrait::getFilterParameters() obtained the type from getParameterFilterWidgets(), which returns nothing for rules without widget - the usual detail page rules. Those parameters fell back to "slugNget" and were accepted as slug as well as GET, no matter what was configured.

The type is now obtained from the filter settings themselves:

  • Simple::getParameterTypes() reports the configured param_type for all parameters of a setting, WithChildren and ExpressionRule merge the types of their children and Collection::getParameterTypes() aggregates all settings of the collection.
  • ParameterTypes::fromSetting() provides the backwards compatibility layer for filter settings not implementing getParameterTypes(). They are treated as "slugNget" and trigger a deprecation. The method becomes part of ISimple in MetaModels 3.0 - adding it now would break implementations not extending Simple.

Render\Setting\Collection::buildJumpToUrlFor() builds the jumpTo URL of the detail page as slug or as GET according to the configured type - it always used slug before, so a rule configured as GET produced links that did not match its own configuration.

A parameter passed via another type than the configured one now results in a 404 instead of silently rendering the unfiltered list under an URL that looks like it is filtered. This is limited to rules without frontend filter widget; for widgets the frontend filter handles the URL (see #1563) and a value of the wrong type stays unused as before.

As a side effect the expensive getParameterFilterWidgets() call is gone from the regular rendering path. It is only performed when a mismatch was detected, that is on the path ending in a 404 anyway.

The URL parameter type ("URL type for the parameter") introduced with #1558 and
fixed up in #1563 was only honoured for filter rules that render a frontend filter
widget. ListControllerTrait::getFilterParameters() obtained the type from
getParameterFilterWidgets(), which returns nothing for rules without widget - the
usual detail page rules. Those parameters fell back to "slugNget" and were accepted
as slug as well as GET, no matter what was configured.

The type is now obtained from the filter settings themselves:

* Simple::getParameterTypes() reports the configured param_type for all parameters
  of a setting, WithChildren and ExpressionRule merge the types of their children
  and Collection::getParameterTypes() aggregates all settings of the collection.
* ParameterTypes::fromSetting() provides the backwards compatibility layer for
  filter settings not implementing getParameterTypes(). They are treated as
  "slugNget" and trigger a deprecation. The method becomes part of ISimple in
  MetaModels 3.0 - adding it now would break implementations not extending Simple.

Render\Setting\Collection::buildJumpToUrlFor() builds the jumpTo URL of the detail
page as slug or as GET according to the configured type - it always used slug
before, so a rule configured as GET produced links that did not match its own
configuration.

A parameter passed via another type than the configured one now results in a 404
instead of silently rendering the unfiltered list under an URL that looks like it
is filtered. This is limited to rules without frontend filter widget; for widgets
the frontend filter handles the URL (see #1563) and a value of the wrong type stays
unused as before.

As a side effect the expensive getParameterFilterWidgets() call is gone from the
regular rendering path. It is only performed when a mismatch was detected, that is
on the path ending in a 404 anyway.
@zonky2
zonky2 requested a review from discordier August 4, 2026 17:58
@zonky2 zonky2 self-assigned this Aug 4, 2026
@zonky2 zonky2 added this to the 2.4.x milestone Aug 4, 2026
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.

1 participant