Skip to content

[Routing] Tell about {foo:bar} mapping syntax #20956

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: 7.2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 11 additions & 20 deletions doctrine.rst
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ will automatically fetch them::
/**
* Perform a findOneBy() where the slug property matches {slug}.
*/
#[Route('/product/{slug}')]
#[Route('/product/{slug:product}')]
public function showBySlug(Product $product): Response
{
}
Expand All @@ -694,14 +694,17 @@ Automatic fetching works in these situations:
*all* of the wildcards in your route that are actually properties
on your entity (non-properties are ignored).

This behavior is enabled by default on all controllers. If you prefer, you can
restrict this feature to only work on route wildcards called ``id`` to look for
entities by primary key. To do so, set the option
``doctrine.orm.controller_resolver.auto_mapping`` to ``false``.
The ``{slug:product}`` syntax maps the route parameter named ``slug`` to the
controller argument named ``$product``. It also hints the resolver to lookup
by slug when loading the corresponding ``Product`` object from the database.

When ``auto_mapping`` is disabled, you can configure the mapping explicitly for
any controller argument with the ``MapEntity`` attribute. You can even control
the ``EntityValueResolver`` behavior by using the `MapEntity options`_ ::
.. versionadded:: 7.1

Route parameter mapping was introduced in Symfony 7.1.

You can also configure the mapping explicitly for any controller argument
with the ``MapEntity`` attribute. You can even control the
``EntityValueResolver`` behavior by using the `MapEntity options`_ ::

// src/Controller/ProductController.php
namespace App\Controller;
Expand Down Expand Up @@ -812,18 +815,6 @@ control behavior:
): Response {
}

``exclude``
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's no use case for exclude anymore IIUC, we could even deprecate it (but it's not strictly need either)

Configures the properties that should be used in the ``findOneBy()``
method by *excluding* one or more properties so that not *all* are used::

#[Route('/product/{slug}/{date}')]
public function show(
#[MapEntity(exclude: ['date'])]
Product $product,
\DateTime $date
): Response {
}

``stripNull``
If true, then when ``findOneBy()`` is used, any values that are
``null`` will not be used for the query.
Expand Down
43 changes: 32 additions & 11 deletions routing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

PHP attributes allow to define routes next to the code of the
:doc:`controllers </controller>` associated to those routes. Attributes are
native in PHP 8 and higher versions, so you can use them right away.
:doc:`controllers </controller>` associated to those routes.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PHP 8 is the past now, the removed sentence feels outdated


You need to add a bit of configuration to your project before using them. If your
project uses :ref:`Symfony Flex <symfony-flex>`, this file is already created for you.
Expand Down Expand Up @@ -707,12 +706,6 @@
matches any uppercase character in any language, ``\p{Greek}`` matches any
Greek characters, etc.

.. note::

When using regular expressions in route parameters, you can set the ``utf8``
route option to ``true`` to make any ``.`` character match any UTF-8
characters instead of just a single byte.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utf8 is enabled by default since a few years now


If you prefer, requirements can be inlined in each parameter using the syntax
``{parameter_name<requirements>}``. This feature makes configuration more
concise, but it can decrease route readability when requirements are complex:
Expand Down Expand Up @@ -998,7 +991,7 @@
{
// ...

#[Route('/blog/{slug}', name: 'blog_show')]
#[Route('/blog/{slug:post}', name: 'blog_show')]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the example is using deprecated implicit mapping that doesn't work anymore with the default recipes since 7.1

public function show(BlogPost $post): Response
{
// $post is the object whose slug matches the routing parameter
Expand All @@ -1012,9 +1005,37 @@
using the request parameters (``slug`` in this case). If no object is found,
Symfony generates a 404 response automatically.

The ``{slug:post}`` syntax maps the route parameter named ``slug`` to the controller
argument named ``$post``. It also hints the "param converter" to lookup by slug
when loading the corresponding ``BlogPost`` object from the database.

.. versionadded:: 7.1

Route parameter mapping was introduced in Symfony 7.1.

When more than one entity needs to be derived from route parameters, collisions can happen.
In the following example, the route tries to define two mappings: one to load an author by
name, two to load a category by name. But this is not allowed because from the side of the
route definition, this declares a parameter named "name" twice::

#[Route('/search-book/{name:author}/{name:category}')]

Such routes should instead be defined using the following syntax::

#[Route('/search-book/{authorName:author.name}/{categoryName:category.name}')]

Check failure on line 1026 in routing.rst

View workflow job for this annotation

GitHub Actions / Code Blocks

[PHP syntax] Syntax error, unexpected EOF, expecting T_TRAIT or T_INTERFACE or T_ENUM
This way, the route parameter names are unique (``authorName`` and ``categoryName``) and
the "param converter" can correctly map them to controller arguments (``$author`` and
``$category``), loading them both by their name.

.. versionadded:: 7.3

This more advanced style of route parameter mapping was introduced in Symfony 7.3.

More advanced mappings can be achieved using the ``#[MapEntity]`` attribute.
Check out the :ref:`Doctrine param conversion documentation <doctrine-entity-value-resolver>`
to learn about the ``#[MapEntity]`` attribute that can be used to customize the
database queries used to fetch the object from the route parameter.
to learn how to customize the database queries used to fetch the object from the route
parameter.

Backed Enum Parameters
~~~~~~~~~~~~~~~~~~~~~~
Expand Down
Loading