A common requirement when building a site is the ability to pass various parameters via the URL of a page in order to display specific or different content, e.g. via a front end module. The most basic form of parameter is the query parameter which can easily be retrieved from Symfony’s request object. However, you will often want to include such parameters in the URL’s path in order to make them easily readable for example.
When building a Symfony controller or a Contao page controller, these path parameters can be defined in the route’s configuration.
However, it is also possible to pass such path parameters for legacy page types - like Contao’s regular
page. If we
inspect Symfony’s routing table for such a page we might see the following (abbreviated):
$ vendor/bin/contao-console debug:router tl_page.2
+--------------+------------------------------------------------------------------+
| Property | Value |
+--------------+------------------------------------------------------------------+
| Route Name | tl_page.2 |
| Path | /news{!parameters} |
| Requirements | parameters: (/.+?)? |
+--------------+------------------------------------------------------------------+
In this case it is a page with the alias news
- but after its alias there is an optional parameter called
{parameters}
. So Contao by default allows all these routes to have arbitrary parameters after the page’s alias (and
before the URL suffix).
Internally, Contao will then check if these parameters have a certain structure - and if they are retrieved through the
legacy Input::get()
method. Otherwise a PageNotFoundException
will be thrown and the front end will thus render the
404 page.
Generally Contao will analyze the URL fragments (i.e. the parts of the URL separated by a forward slash) coming after the page’s alias. The following describes what kind of parameters we can pass to such regular pages and how to retrieve them.
If the number of fragments after the page alias is odd, then the first of these fragments will be regarded as the so
called “auto item” (auto_item
). Let’s look at an example:
news/detail
.https://example.com/news/detail
.https://example.com/news/detail/some-news
, then
some-news
will become the value of the auto_item
parameter (assuming no actual page with the alias
news/detail/some-news
exists and has a higher routing priority).As mentioned before, this auto_item
parameter can be retrieved via the legacy Input
class of Contao:
use Contao\Input;
// Will contain 'some-news'
$autoItem = Input::get('auto_item');
Executing this code somewhere (e.g. in a news reader module) will thus mark the auto_item
as used and no 404 page
will be generated.
Careful: do not use Input::get('auto_item')
in any part of your code that is executed on every request, e.g. in a
module that is included in the layout of a page, or a hook that is executed on every page. This will cause all URLs
with such “auto items” to not show a 404 page, even though they ought to, depending on each instance. You can instead
enable the $blnKeepUnused
parameter for such cases:
$autoItem = Input::get('auto_item', blnKeepUnused: true);
If the number of fragments after the page alias is even, then the fragments will be considered key & value pairs.
If the number of fragments after the page alias is odd - but equal or greater than 3, then the first fragment is
considered the auto_item
(see above) while the rest are again key & value pairs. Let’s look at an example:
foo/bar
.https://example.com/foo/bar
.https://example.com/foo/bar/lorem/ipsum/dolor/sit
.lorem=ipsum
, dolor=sit
.As mentioned before, these parameters can then be retrieved via the legacy Input
class of Contao:
use Contao\Input;
// Will contain 'ipsum'
$lorem = Input::get('lorem');
// Will contain 'sit'
$dolor = Input::get('dolor');
foo/bar
.https://example.com/foo/bar
.https://example.com/foo/bar/some-news/lorem/ipsum/dolor/sit
.auto_item
and the key & value pairs lorem=ipsum
, dolor=sit
.use Contao\Input;
// Will contain 'some-news'
$lorem = Input::get('auto_item');
// Will contain 'ipsum'
$lorem = Input::get('lorem');
// Will contain 'sit'
$dolor = Input::get('dolor');