Top Banner
Routing in Drupal 8 July 31, 2014
52

Routing in Drupal 8

Jan 15, 2015

Download

Technology

kgoel1

Drupal 8, page callbacks are completely rewritten by utilizing Symfony Routing component. This session will explain many parts of routing, how to convert from Drupal 7 menu system to Drupal 8 routing system and it will cover how to define local tasks, local actions, and contextual links in Drupal 8.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Routing in Drupal 8

Routing in Drupal 8

July 31, 2014

Page 2: Routing in Drupal 8

Nice to Meet You!

SECTION TITLE

Kalpana GoelDeveloper

William HurleyManager, Technical

Development

Page 3: Routing in Drupal 8

Routes basically are the mappings between URL paths and their corresponding page and access callbacks.

What is a route?

Page 4: Routing in Drupal 8

What’s Changed

Page 5: Routing in Drupal 8

hook_menu defines the routing in Drupal 7

SECTION TITLE

1:1 mapping of path to route

Page 6: Routing in Drupal 8

hook_menu is dead in 8.0.x

SECTION TITLE

There is no hook_menu in Drupal 8!

MODULENAME.routing.yml

One path may map to multiple routes

Page 7: Routing in Drupal 8
Page 8: Routing in Drupal 8

Why the Change?

Page 9: Routing in Drupal 8

D7 hook_menu

SECTION TITLE

● Routing (page and access callbacks)● Menu links● Local actions● Local tasks● Breadcrumbs● Contextual links● Title● Weight

Page 10: Routing in Drupal 8

*.links.actin.ml *.links.contexual.yml

Page 11: Routing in Drupal 8

Basic Example

Page 12: Routing in Drupal 8

D7: hook_menu()

function user_menu() { $items['user/logout'] = array( 'title' => 'Log out', 'access callback' => 'user_is_logged_in', 'page callback' => 'user_logout', 'weight' => 10, 'menu_name' => 'user-menu', 'file' => 'user.pages.inc', );

return $items;}

Page 13: Routing in Drupal 8

D8: Routing

user.routing.yml

user.logout: path: '/user/logout' defaults: _controller: '\Drupal\user\Controller\UserController::logout' requirements: _user_is_logged_in: 'TRUE'

Page 14: Routing in Drupal 8

D7: page callback

/** * Menu callback; logs the current user out, and redirects to the home page. */function user_logout() { global $user;

watchdog('user', 'Session closed for %name.', array('%name' => $user->name));

module_invoke_all('user_logout', $user);

// Destroy the current session, and reset $user to the anonymous user. session_destroy();

drupal_goto();}

Page 15: Routing in Drupal 8

D8: Controller

namespace Drupal\user\Controller;

class UserController extends ControllerBase {

public function logout() { user_logout(); return $this->redirect('<front>'); }

Page 16: Routing in Drupal 8

Path Variables

Page 17: Routing in Drupal 8

D8: Path (required)

For dynamic properties, you can include them in curly braces. For example - ‘/admin/structure/views/{js}/display/{view}/{display_id}/{type}'The {display_id} element in the URL is called a slug and is available as $display_id in the controller method.

Page 18: Routing in Drupal 8

D8: dynamic path exampleviews_ui.form_display: path: '/admin/structure/views/{js}/display/{view}/{display_id}/{type}' defaults: _content: '\Drupal\views_ui\Form\Ajax\Display::getForm'

class Display extends ViewsFormBase { public function getForm(ViewStorageInterface $view, $display_id, $js, $type = NULL) { $this->setType($type); return parent::getForm($view, $display_id, $js); }

Page 19: Routing in Drupal 8

D8: Optional Attributes

user.cancel_confirm: path: '/user/{user}/cancel/confirm/{timestamp}/{hashed_pass}' defaults: _title: 'Confirm account cancellation' _content: '\Drupal\user\Controller\UserController::confirmCancel' timestamp: 0 hashed_pass: ''

Page 20: Routing in Drupal 8

D8: Page Title

user.view: path: '/user/{user}' defaults: _entity_view: 'user.full' _title_callback: 'Drupal\user\Controller\UserController::userTitle' requirements: _entity_access: 'user.view'

Page 21: Routing in Drupal 8

D8: Page Types

_content : -display content on a page _form : - display form on a page. _controller : - use to generate raw data like json output_entity_view : - for example - node.teaser_entity_form : - display a form for a entity_entity_list : - display list of entity like node

Page 22: Routing in Drupal 8

Access Restrictions

Page 23: Routing in Drupal 8

D8: Available Checks

_permission - A permission string (e.g. - _permission: ‘access content’)_role : A specific user role (e.g.- administrator)_entity_access: In case where an entity is part of route, can check a certain access level before granting access (e.g. node.view)_custom_access: You can also do custom access checking on route. Same as title callback (define as method on class)Read more - https://www.drupal.org/node/2122195

Page 24: Routing in Drupal 8

D8: Access checkuser.role_add: path: '/admin/people/roles/add' defaults: _entity_form: user_role.default _title: 'Add role' requirements: _permission: 'administer permissions'

Some permissions based on roles , permissions_permission: ‘administer nodes’_role: ‘administrator’

Based upon access to Entities _entity_access: $entity_type.$operation

check to see if everyone has access

_access: TRUE

Page 25: Routing in Drupal 8

D8: Access check

Multiple access check - node.add_page: path: '/node/add' defaults: _title: 'Add content' _content: '\Drupal\node\Controller\NodeController::addPage' options: _access_mode: 'ANY' _node_operation_route: TRUE requirements: _permission: 'administer content types' _node_add_access: 'node'

Page 26: Routing in Drupal 8

Forms

Page 27: Routing in Drupal 8

D7: Form Router$items['user/password'] = array( 'title' => 'Request new password', 'page callback' => 'drupal_get_form', 'page arguments' => array('user_pass'), 'access callback' => TRUE, 'type' => MENU_LOCAL_TASK, 'file' => 'user.pages.inc',);

Page 28: Routing in Drupal 8

D8: Form Router

Forms are classesThere is no method in forms as forms are presented as one classUse _form instead of _content or _controller

user.pass: path: '/user/password' defaults: _form: '\Drupal\user\Form\UserPasswordForm' _title: 'Request new password' requirements: _access: 'TRUE' options: _maintenance_access: TRUE

Page 29: Routing in Drupal 8

D7: User Password Form

function user_pass() { $form['name'] = array( '#type' => 'textfield', '#title' => t('Username or e-mail address'), '#size' => 60, '#maxlength' => max(USERNAME_MAX_LENGTH, EMAIL_MAX_LENGTH), '#required' => TRUE, '#default_value' => isset($_GET['name']) ? $_GET['name'] : '', ); [...]}

function user_pass_validate($form, &$form_state)function user_pass_submit($form, &$form_state)

Page 30: Routing in Drupal 8

D8: Form Interfacenamespace Drupal\Core\Form;* Provides an interface for a Form.interface FormInterface { * Returns a unique string identifying the form public function getFormId();

*Form constructor. public function buildForm(array $form, array &$form_state); * Form validation handler. public function validateForm(array &$form, array &$form_state);

* Form submission handler. public function submitForm(array &$form, array &$form_state);}

Page 31: Routing in Drupal 8

D8: User Password Formclass UserPasswordForm extends FormBase { public function getFormId() { return ‘user_pass’; } public function buildForm(array $form, array &$form_state) { $form['name'] = array( '#type' => 'textfield', '#title' => $this->t('Username or email address'), '#size' => 60, '#maxlength' => max(USERNAME_MAX_LENGTH, EMAIL_MAX_LENGTH), '#required' => TRUE, );

public function submitForm(array &$form, array &$form_state) {....}public function validateForm(array &$form, array &$form_state) {...}

Page 32: Routing in Drupal 8

D7: Form Validation

function user_pass_validate($form, &$form_state) { [...] form_set_error('name', t('Sorry, %name is not recognized as a user name or an e-mail address.', array('%name' => $name)));}

Page 33: Routing in Drupal 8

D8: Form Validation

public function validateForm(array &$form, array &$form_state) { [...] $this->setFormError('name', $form_state, $this->t('Sorry, %name is not recognized as a username or an email address.', array('%name' => $name))); }

Page 34: Routing in Drupal 8

D8: Form Base class* * Base class for implementing system configuration forms.Drupal\core\form\ConfigFormBase for example - class MenuSettingsForm extends ConfigFormBase

** generic base class - thisincludes string translation, link generatorDrupal\Core\Form\FormBase for example - class UserLoginForm extends FormBase

** base class for a confirmation form.Drupal\Core\Form\ConfirmFormBase for example - class LoggingForm extends ConfigFormBase

Page 35: Routing in Drupal 8

Other functionality from hook_menu

Page 36: Routing in Drupal 8

local task

Page 37: Routing in Drupal 8

local task

Page 38: Routing in Drupal 8

local task

Page 39: Routing in Drupal 8

D7: menu local tasks

$items['user/password'] = array( 'title' => 'Request new password', 'page callback' => 'drupal_get_form', 'page arguments' => array('user_pass'), 'access callback' => TRUE, 'type' => MENU_LOCAL_TASK, 'file' => 'user.pages.inc', );

Page 40: Routing in Drupal 8

D8: menu local tasksuser.links.task.yml

user.page: route_name: user.page base_route: user.page title: 'Log in' weight: -10user.pass: route_name: user.pass base_route: user.page title: 'Request new password'

Page 41: Routing in Drupal 8

local action

Page 42: Routing in Drupal 8

D7: Local action

$items['admin/structure/types/add'] = array( 'title' => 'Add content type', 'page callback' => 'drupal_get_form', 'page arguments' => array('node_type_form'), 'access arguments' => array('administer content types'), 'type' => MENU_LOCAL_ACTION, 'file' => 'content_types.inc', );

Page 43: Routing in Drupal 8

D8: Local action

node.links.action.yml

node.add_page: route_name: node.add_page title: 'Add content' appears_on: - system.admin_content

Page 44: Routing in Drupal 8

D8: Local action on multiple pages

block_content.links.action.yml

block_content_add_action: route_name: block_content.add_page title: 'Add custom block' appears_on: - block.admin_display - block.admin_display_theme - block_content.list

Page 45: Routing in Drupal 8

D8: Contextual links

Page 46: Routing in Drupal 8

D7: Contextual links

$items['admin/structure/block/manage/%/%/configure'] = array( 'title' => 'Configure block', 'type' => MENU_DEFAULT_LOCAL_TASK, 'context' => MENU_CONTEXT_INLINE, );

Page 47: Routing in Drupal 8

D8: Contextual links

block.links.contextual.yml

block_configure: title: 'Configure block' route_name: 'block.admin_edit' group: 'block'

Page 48: Routing in Drupal 8

D8: breadcrumb

breadcrumb is path based in Drupal 8

https://www.drupal.org/node/2098323

Page 49: Routing in Drupal 8

Useful Tips

Page 50: Routing in Drupal 8

Options

Useful Tips

_admin_route -- whether to use the admin theme for this route_maintenance_access -- whether route is publicly available when the site is in maintenance mode_access_mode -- whether requirements are ANY or ALL

Page 51: Routing in Drupal 8

Useful links

SECTION TITLE

https://www.drupal.org/node/1800686 - change record

https://www.drupal.org/node/2118147 - D7 to D8 upgrade tutorial

https://www.drupal.org/developing/api/8/routing - Routing system in D8

Page 52: Routing in Drupal 8

THANK YOU!Kalpana GoelWilliam Hurley