Drupal 8's routing system came from Symfony's, and it can do everything that Symphony’s can, and more. It’s an overhaul from Drupal 7, as D7 used hook_menus while in D8 a module’s routes are defined in yml files and these trigger actions defined in module’s controller.
Watch the video to understand Drupal 8 routing system:
A route is a way to reach from a starting point to some destination. In Drupal, a route is a way defined that would return some sort of content.
Example: /node the default front page is a route.
/node/add that opens up a node add page is a route
/node/{nid}/edit
In Symfony we have
#app/config/routing.yml
blog_show:
path: /blog defaults: {_controller: ControllerName:method}
In Drupal 7 routing is handled by hook_menu(). Apart from just routing it had many other responsibilities as well:
It’s too much for a single function to handle and made some sort of a tight coupling. It looks a much of alien concept to developers coming from other MVC frameworks.
Drupal 8 has said Goodbye hook_menu() adopting its routing from Symfony.
Drupal does this with the help of Symfony. To have a look in Drupal code where this Symfony Kernel lies, go to
<drupal folder>/vendor/symfony/http-kernel/
Drupal System uses this HTTP Kernel, which gets the request and asks other systems to produce o/p what are these other systems lets see
Explanation: A request can come in from a mobile device or a laptop or any other device goes to the HTTP kernel which checks the access check and requirements on the accessing user and if the access is granted a 200 status code is returned else a 404 is returned.
Drupal System uses this HTTP Kernel which gets the request and asks other systems to produce output. These other systems are:
YML File: <modulename>.routing.yml
YML file tells Drupal how to behave when a particular path is encountered.
If you want to specify a default value, you put it into the defaults array. In the same yml array you specify the class and method connected with '::' to tell the system where to look up stuff.
Controllers: ExampleController.php - Inside src/Controller/
Controller is a piece of code that is responsible to generate the response object.
The key concept is the controller which gets some parameters from the system and converts them to the response.
So everything without an underscore is considered to be a parameter to the controller. Every other property has nothing to do with the controller parameters and so are considered to be internal and so have an underscore as prefix.
When two routes match the same URL, the first route that's loaded wins.
So if we have two routes defined as
1. drupalcamp.blogshow:
path: '/blog/{slug}'
defaults:
_controller: '\Drupal\drupalcamp\Controller\ExampleController::blogshow'
_title: 'Shows blog'
requirements:
_access: 'TRUE'
And
2. drupalcamp.eventshow:
path: '/blog/{event}'
defaults:
_controller: '\Drupal\drupalcamp\Controller\ExampleController::eventshow'
_title: 'Shows event'
requirements:
_access: 'TRUE'
Unfortunately, that means that /blog/test will match the blogshow and not eventshow.
No good!
To fix this, add a requirement wherein you can define the inputs that should be matched for a particular route to load.
So with requirements the code would look like
drupalcamp.blogshow:
path: '/blog/{slug}'
defaults:
_controller: '\Drupal\drupalcamp\Controller\ExampleController::blogshow'
_title: 'Shows blog'
requirements:
_access: 'TRUE'
slug: '\d+'
Loading blogshow in case of integers.
drupalcamp.eventshow:
path: '/blog/{event}'
defaults:
_controller: '\Drupal\drupalcamp\Controller\ExampleController::eventshow'
_title: 'Shows event'
requirements:
_access: 'TRUE'
event: en|fr
Loading eventshow in case of en OR fr being entered by accessing user.
You can also pass default values to a route by defining this value in defaults array.
If you want to get access to an entity type you can use named params in the url.$user is the name of an entity type.
If the userid does not exist drupal would give a 404.
Named parameters are not sanitized by default. This means that you really should sanitize all values prior to use.
You can somewhat decrease a code injection security concern by specifying regex requirements. Inside the controller you will have access to the complete user object
You don't want to take care about loading an entity, see /user/{user} as an example. For entities you basically just use the name of the entity type and it will execute an entity_load with the ID passed in the URL. Param converter manager
While working with routing If you update a routes file in Drupal 8 how do you clear the cache?
So instead of clearing caches you can rebuild the router table.
If you use drush, drush ev '\Drupal::service("router.builder")->rebuild();' to rebuild the routing information without clearing all the caches.
If you use drupal console: drupal router:rebuild
You can checkout this code here.