SlideShare ist ein Scribd-Unternehmen logo
1 von 55
Routing in Drupal 8 
November 13, 2014
Nice to Meet You! 
Kalpana Goel 
Developer 
Drupal.org - kgoel 
Twitter - @kalpanagoel 
William Hurley 
Manager, Technical 
Development
What is a route? 
Routes are the mappings between URL paths and 
their corresponding page and access callbacks.
What’s Changed
hook_menu defines the 
routing in Drupal 7 
1:1 mapping of path to route
hook_menu is dead in 8.0.x 
There is no hook_menu in Drupal 8! 
MODULENAME.routing.yml 
One path may map to multiple routes
Why the Change?
D7 hook_menu 
● Routing (page and access callbacks) 
● Menu links 
● Local actions 
● Local tasks 
● Breadcrumbs 
● Contextual links 
● Title 
● Weight
*.links.actin.ml *.links.contexual.yml
Basic Example
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; 
}
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(); 
}
D8: Routing 
user.routing.yml 
user.logout: 
path: '/user/logout' 
defaults: 
_controller: 'DrupaluserControllerUserController::logout' 
requirements: 
_user_is_logged_in: 'TRUE'
D8: Controller 
namespace DrupaluserController; 
class UserController extends ControllerBase { 
public function logout() { 
user_logout(); 
return $this->redirect('<front>'); 
}
Path Variables
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 placeholder and 
is available as $display_id in the controller method.
D8: dynamic path example 
views_ui.form_display: 
path: '/admin/structure/views/{js}/display/{view}/{display_id}/{type}' 
defaults: 
_content: 'Drupalviews_uiFormAjaxDisplay::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); 
}
D8: Optional Attributes 
user.cancel_confirm: 
path: '/user/{user}/cancel/confirm/{timestamp}/{hashed_pass}' 
defaults: 
_title: 'Confirm account cancellation' 
_content: 'DrupaluserControllerUserController::confirmCancel' 
timestamp: 0 
hashed_pass: ''
D8: Page Title 
user.view: 
path: '/user/{user}' 
defaults: 
_entity_view: 'user.full' 
_title_callback: 'DrupaluserControllerUserController::userTitle' 
requirements: 
_entity_access: 'user.view'
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
Access Restrictions
D8: Access checking 
user.admin_account: 
path: '/admin/people' 
defaults: 
_entity_list: 'user' 
_title: 'People' 
requirements: 
_permission: 'administer users'
D8: Access checkers 
Based upon roles, permissions: 
_permission - A permission string (e.g. - _permission: ‘access 
content’) 
_role : A specific user role (e.g.- administrator)
D8: Access checkers 
Based upon access to Entities (view, update, delete) 
_entity_access: In case where an entity is part of route, can check 
a certain access level before granting access (e.g. node.view) 
Example: 
_entity_access: node.view
D8: Access check 
Custom Access 
_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 
_custom_access: DrupalshortcutFormSwitchShortcutSet::checkAccess 
public function checkAccess(UserInterface $user = NULL) { 
return shortcut_set_switch_access($user); 
}
D8: Access check 
Access check for everyone 
grant access to everyone 
_access: TRUE
D8: Access check 
Multiple access check - 
node.add_page: 
path: '/node/add' 
defaults: 
_title: 'Add content' 
_content: 
'DrupalnodeControllerNodeController::addPage' 
options: 
_access_mode: 'ANY' 
_node_operation_route: TRUE 
requirements: 
_permission: 'administer content types' 
_node_add_access: 'node'
Forms
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', 
);
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)
D8: Form Router 
Forms are classes 
There is no method in forms as forms are presented as one class 
Use _form instead of _content or _controller 
user.pass: 
path: '/user/password' 
defaults: 
_form: 'DrupaluserFormUserPasswordForm' 
_title: 'Request new password' 
requirements: 
_access: 'TRUE' 
options: 
_maintenance_access: TRUE
D8: Form Interface 
namespace DrupalCoreForm; 
interface FormInterface { 
public function getFormId() { 
return 'user_pass'; 
}
D8: Form Interface 
public function buildForm(array $form, FormStateInterface $form_state) { 
$form['name'] = array( 
'#type' => 'textfield', 
'#title' => $this->t('Username or email address'), 
'#size' => 60, 
'#maxlength' => max(USERNAME_MAX_LENGTH, 
Email::EMAIL_MAX_LENGTH), 
'#required' => TRUE, 
'#attributes' => array( 
'autocorrect' => 'off', 
'autocapitalize' => 'off', 
'spellcheck' => 'false', 
'autofocus' => 'autofocus', 
), 
);
pubDlic8 fu:n Fctioonr mvali dIantetFeorrmfa(acrreay &$form, FormStateInterface $form_state) { 
$name = trim($form_state->getValue('name')); 
$users = $this->userStorage->loadByProperties(array('mail' => $name, 'status' => 
'1')); 
if (empty($users)) { 
$users = $this->userStorage->loadByProperties(array('name' => $name, 'status' 
=> '1')); 
} 
if ($account && $account->id()) { 
$form_state->setValueForElement(array('#parents' => array('account')), 
$account); 
} 
else { 
$form_state->setErrorByName('name', $this->t('Sorry, %name is not recognized 
as a username or an email address.', array('%name' => $name))); 
$account = reset($users); 
}
public function submitForm(array &$form, FormStateInterface $form_state) { 
$langcode = $this->languageManager->getCurrentLanguage()->getId(); 
$account = $form_state->getValue('account'); 
// Mail one time login URL and instructions using current language. 
$mail = _user_mail_notify('password_reset', $account, $langcode); 
if (!empty($mail)) { 
$this->logger('user')->notice('Password reset instructions mailed to %name 
at %email.', array('%name' => $account->getUsername(), '%email' => 
$account->getEmail())); 
drupal_set_message($this->t('Further instructions have been sent to your 
email address.')); 
} 
$form_state->setRedirect('user.page'); 
}
D8: Form Base class 
** generic base class - this includes string translation, link generator 
DrupalCoreFormFormBase 
for example - 
class UserLoginForm extends FormBase 
* * Base class for implementing system configuration forms. 
DrupalcoreformConfigFormBase 
for example - 
class MenuSettingsForm extends ConfigFormBase 
** base class for a confirmation form. 
DrupalCoreFormConfirmFormBase 
for example - 
class UserMultipleCancelConfirm extends ConfirmFormBase
Other functionality 
from hook_menu
local task
local task
local task
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', 
);
D8: menu local tasks 
user.links.task.yml 
user.page: 
route_name: user.page 
base_route: user.page 
title: 'Log in' 
weight: -10 
user.pass: 
route_name: user.pass 
base_route: user.page 
title: 'Request new password'
local action
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', 
);
D8: Local action 
node.links.action.yml 
node.add_page: 
route_name: node.add_page 
title: 'Add content' 
appears_on: 
- system.admin_content
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' 
class: 
Drupalblock_contentPluginMenuLocalActionBlockContentAddLocalAction 
appears_on: 
- block.admin_display 
- block.admin_display_theme 
- block_content.list
D8: Contextual 
links
D7: Contextual 
links $items['admin/structure/block/manage/%/%/configure'] = array( 
'title' => 'Configure block', 
'type' => MENU_DEFAULT_LOCAL_TASK, 
'context' => MENU_CONTEXT_INLINE, 
);
D8: Contextual 
links 
block.links.contextual.yml 
block_configure: 
title: 'Configure block' 
route_name: 'entity.block.edit_form' 
group: 'block'
D8: Path based breadcrumb 
breadcrumb is path based in Drupal 8 
/node/add/content 
/node/add 
/node 
/ 
https://www.drupal.org/node/2098323
Useful Tips
Options 
_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 
Useful Tips
Useful links 
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
THANK YOU! 
Kalpana Goel 
William Hurley

Weitere ähnliche Inhalte

Was ist angesagt?

Ajax nested form and ajax upload in rails
Ajax nested form and ajax upload in railsAjax nested form and ajax upload in rails
Ajax nested form and ajax upload in railsTse-Ching Ho
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From IusethisMarcus Ramberg
 
First Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentFirst Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentNuvole
 
Drupal is Stupid (But I Love It Anyway)
Drupal is Stupid (But I Love It Anyway)Drupal is Stupid (But I Love It Anyway)
Drupal is Stupid (But I Love It Anyway)brockboland
 
Анатолий Поляков - Drupal.ajax framework from a to z
Анатолий Поляков - Drupal.ajax framework from a to zАнатолий Поляков - Drupal.ajax framework from a to z
Анатолий Поляков - Drupal.ajax framework from a to zLEDC 2016
 
Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Luka Zakrajšek
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ EtsyNishan Subedi
 
Opencast Admin UI - Introduction to developing using AngularJS
Opencast Admin UI - Introduction to developing using AngularJSOpencast Admin UI - Introduction to developing using AngularJS
Opencast Admin UI - Introduction to developing using AngularJSbuttyx
 
Drupal 8: Forms
Drupal 8: FormsDrupal 8: Forms
Drupal 8: Formsdrubb
 
Introduction to ZendX jQuery
Introduction to ZendX jQueryIntroduction to ZendX jQuery
Introduction to ZendX jQuerydennisdc
 
jQuery UI Widgets, Drag and Drop, Drupal 7 Javascript
jQuery UI Widgets, Drag and Drop, Drupal 7 JavascriptjQuery UI Widgets, Drag and Drop, Drupal 7 Javascript
jQuery UI Widgets, Drag and Drop, Drupal 7 JavascriptDarren Mothersele
 
Drupal 7 Theming - Behind the scenes
Drupal 7 Theming - Behind the scenes Drupal 7 Theming - Behind the scenes
Drupal 7 Theming - Behind the scenes ramakesavan
 
Twitter bootstrap
Twitter bootstrapTwitter bootstrap
Twitter bootstrapdennisdc
 
Drupal csu-open atriumname
Drupal csu-open atriumnameDrupal csu-open atriumname
Drupal csu-open atriumnameEmanuele Quinto
 
Introduction to Zend_Pdf
Introduction to Zend_PdfIntroduction to Zend_Pdf
Introduction to Zend_Pdfdennisdc
 
Php tour 2018 un autre regard sur la validation (1)
Php tour 2018   un autre regard sur la validation (1)Php tour 2018   un autre regard sur la validation (1)
Php tour 2018 un autre regard sur la validation (1)Quentin Pautrat
 
Zend Framework and the Doctrine2 MongoDB ODM (ZF1)
Zend Framework and the Doctrine2 MongoDB ODM (ZF1)Zend Framework and the Doctrine2 MongoDB ODM (ZF1)
Zend Framework and the Doctrine2 MongoDB ODM (ZF1)Ryan Mauger
 

Was ist angesagt? (20)

Ajax nested form and ajax upload in rails
Ajax nested form and ajax upload in railsAjax nested form and ajax upload in rails
Ajax nested form and ajax upload in rails
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
 
First Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentFirst Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven Development
 
BEAR DI
BEAR DIBEAR DI
BEAR DI
 
Drupal is Stupid (But I Love It Anyway)
Drupal is Stupid (But I Love It Anyway)Drupal is Stupid (But I Love It Anyway)
Drupal is Stupid (But I Love It Anyway)
 
Анатолий Поляков - Drupal.ajax framework from a to z
Анатолий Поляков - Drupal.ajax framework from a to zАнатолий Поляков - Drupal.ajax framework from a to z
Анатолий Поляков - Drupal.ajax framework from a to z
 
Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your Code
 
Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
Opencast Admin UI - Introduction to developing using AngularJS
Opencast Admin UI - Introduction to developing using AngularJSOpencast Admin UI - Introduction to developing using AngularJS
Opencast Admin UI - Introduction to developing using AngularJS
 
Drupal 8: Forms
Drupal 8: FormsDrupal 8: Forms
Drupal 8: Forms
 
Introduction to ZendX jQuery
Introduction to ZendX jQueryIntroduction to ZendX jQuery
Introduction to ZendX jQuery
 
jQuery UI Widgets, Drag and Drop, Drupal 7 Javascript
jQuery UI Widgets, Drag and Drop, Drupal 7 JavascriptjQuery UI Widgets, Drag and Drop, Drupal 7 Javascript
jQuery UI Widgets, Drag and Drop, Drupal 7 Javascript
 
Drupal 7 Theming - Behind the scenes
Drupal 7 Theming - Behind the scenes Drupal 7 Theming - Behind the scenes
Drupal 7 Theming - Behind the scenes
 
Twitter bootstrap
Twitter bootstrapTwitter bootstrap
Twitter bootstrap
 
Jsf
JsfJsf
Jsf
 
Drupal csu-open atriumname
Drupal csu-open atriumnameDrupal csu-open atriumname
Drupal csu-open atriumname
 
Introduction to Zend_Pdf
Introduction to Zend_PdfIntroduction to Zend_Pdf
Introduction to Zend_Pdf
 
Php tour 2018 un autre regard sur la validation (1)
Php tour 2018   un autre regard sur la validation (1)Php tour 2018   un autre regard sur la validation (1)
Php tour 2018 un autre regard sur la validation (1)
 
Zend Framework and the Doctrine2 MongoDB ODM (ZF1)
Zend Framework and the Doctrine2 MongoDB ODM (ZF1)Zend Framework and the Doctrine2 MongoDB ODM (ZF1)
Zend Framework and the Doctrine2 MongoDB ODM (ZF1)
 

Ähnlich wie Routing in Drupal 8

Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Fabien Potencier
 
Debugging in drupal 8
Debugging in drupal 8Debugging in drupal 8
Debugging in drupal 8Allie Jones
 
Learning the basics of the Drupal API
Learning the basics of the Drupal APILearning the basics of the Drupal API
Learning the basics of the Drupal APIAlexandru Badiu
 
Михаил Крайнюк - Form API + Drupal 8: Form and AJAX
Михаил Крайнюк - Form API + Drupal 8: Form and AJAXМихаил Крайнюк - Form API + Drupal 8: Form and AJAX
Михаил Крайнюк - Form API + Drupal 8: Form and AJAXDrupalSib
 
laravel tricks in 50minutes
laravel tricks in 50minuteslaravel tricks in 50minutes
laravel tricks in 50minutesBarang CK
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 MinutesAzim Kurt
 
ZF2 for the ZF1 Developer
ZF2 for the ZF1 DeveloperZF2 for the ZF1 Developer
ZF2 for the ZF1 DeveloperGary Hockin
 
Binary Studio Academy 2016: Laravel Controllers
Binary Studio Academy 2016: Laravel ControllersBinary Studio Academy 2016: Laravel Controllers
Binary Studio Academy 2016: Laravel ControllersBinary Studio
 
Drupal 8 Services And Dependency Injection
Drupal 8 Services And Dependency InjectionDrupal 8 Services And Dependency Injection
Drupal 8 Services And Dependency InjectionPhilip Norton
 
Drupal sins 2016 10-06
Drupal sins 2016 10-06Drupal sins 2016 10-06
Drupal sins 2016 10-06Aaron Crosman
 
Drupalcon 2023 - How Drupal builds your pages.pdf
Drupalcon 2023 - How Drupal builds your pages.pdfDrupalcon 2023 - How Drupal builds your pages.pdf
Drupalcon 2023 - How Drupal builds your pages.pdfLuca Lusso
 
2023 - Drupalcon - How Drupal builds your pages
2023 - Drupalcon - How Drupal builds your pages2023 - Drupalcon - How Drupal builds your pages
2023 - Drupalcon - How Drupal builds your pagessparkfabrik
 
Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your CodeDrupalDay
 

Ähnlich wie Routing in Drupal 8 (20)

Drupal 8 Services
Drupal 8 ServicesDrupal 8 Services
Drupal 8 Services
 
Drupal 8 migrate!
Drupal 8 migrate!Drupal 8 migrate!
Drupal 8 migrate!
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)
 
Debugging in drupal 8
Debugging in drupal 8Debugging in drupal 8
Debugging in drupal 8
 
Django Vs Rails
Django Vs RailsDjango Vs Rails
Django Vs Rails
 
Learning the basics of the Drupal API
Learning the basics of the Drupal APILearning the basics of the Drupal API
Learning the basics of the Drupal API
 
Михаил Крайнюк - Form API + Drupal 8: Form and AJAX
Михаил Крайнюк - Form API + Drupal 8: Form and AJAXМихаил Крайнюк - Form API + Drupal 8: Form and AJAX
Михаил Крайнюк - Form API + Drupal 8: Form and AJAX
 
laravel tricks in 50minutes
laravel tricks in 50minuteslaravel tricks in 50minutes
laravel tricks in 50minutes
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
 
ZF2 for the ZF1 Developer
ZF2 for the ZF1 DeveloperZF2 for the ZF1 Developer
ZF2 for the ZF1 Developer
 
Binary Studio Academy 2016: Laravel Controllers
Binary Studio Academy 2016: Laravel ControllersBinary Studio Academy 2016: Laravel Controllers
Binary Studio Academy 2016: Laravel Controllers
 
Drupal 8 Services And Dependency Injection
Drupal 8 Services And Dependency InjectionDrupal 8 Services And Dependency Injection
Drupal 8 Services And Dependency Injection
 
Drupal 8 Hooks
Drupal 8 HooksDrupal 8 Hooks
Drupal 8 Hooks
 
Get AngularJS Started!
Get AngularJS Started!Get AngularJS Started!
Get AngularJS Started!
 
Drupal sins 2016 10-06
Drupal sins 2016 10-06Drupal sins 2016 10-06
Drupal sins 2016 10-06
 
Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2
 
Drupalcon 2023 - How Drupal builds your pages.pdf
Drupalcon 2023 - How Drupal builds your pages.pdfDrupalcon 2023 - How Drupal builds your pages.pdf
Drupalcon 2023 - How Drupal builds your pages.pdf
 
2023 - Drupalcon - How Drupal builds your pages
2023 - Drupalcon - How Drupal builds your pages2023 - Drupalcon - How Drupal builds your pages
2023 - Drupalcon - How Drupal builds your pages
 
Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your Code
 

Kürzlich hochgeladen

EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 

Kürzlich hochgeladen (20)

EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 

Routing in Drupal 8

  • 1. Routing in Drupal 8 November 13, 2014
  • 2. Nice to Meet You! Kalpana Goel Developer Drupal.org - kgoel Twitter - @kalpanagoel William Hurley Manager, Technical Development
  • 3. What is a route? Routes are the mappings between URL paths and their corresponding page and access callbacks.
  • 5. hook_menu defines the routing in Drupal 7 1:1 mapping of path to route
  • 6. hook_menu is dead in 8.0.x There is no hook_menu in Drupal 8! MODULENAME.routing.yml One path may map to multiple routes
  • 7.
  • 9. D7 hook_menu ● Routing (page and access callbacks) ● Menu links ● Local actions ● Local tasks ● Breadcrumbs ● Contextual links ● Title ● Weight
  • 12. 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; }
  • 13. 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(); }
  • 14. D8: Routing user.routing.yml user.logout: path: '/user/logout' defaults: _controller: 'DrupaluserControllerUserController::logout' requirements: _user_is_logged_in: 'TRUE'
  • 15. D8: Controller namespace DrupaluserController; class UserController extends ControllerBase { public function logout() { user_logout(); return $this->redirect('<front>'); }
  • 17. 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 placeholder and is available as $display_id in the controller method.
  • 18. D8: dynamic path example views_ui.form_display: path: '/admin/structure/views/{js}/display/{view}/{display_id}/{type}' defaults: _content: 'Drupalviews_uiFormAjaxDisplay::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); }
  • 19. D8: Optional Attributes user.cancel_confirm: path: '/user/{user}/cancel/confirm/{timestamp}/{hashed_pass}' defaults: _title: 'Confirm account cancellation' _content: 'DrupaluserControllerUserController::confirmCancel' timestamp: 0 hashed_pass: ''
  • 20. D8: Page Title user.view: path: '/user/{user}' defaults: _entity_view: 'user.full' _title_callback: 'DrupaluserControllerUserController::userTitle' requirements: _entity_access: 'user.view'
  • 21. 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
  • 23. D8: Access checking user.admin_account: path: '/admin/people' defaults: _entity_list: 'user' _title: 'People' requirements: _permission: 'administer users'
  • 24. D8: Access checkers Based upon roles, permissions: _permission - A permission string (e.g. - _permission: ‘access content’) _role : A specific user role (e.g.- administrator)
  • 25. D8: Access checkers Based upon access to Entities (view, update, delete) _entity_access: In case where an entity is part of route, can check a certain access level before granting access (e.g. node.view) Example: _entity_access: node.view
  • 26. D8: Access check Custom Access _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 _custom_access: DrupalshortcutFormSwitchShortcutSet::checkAccess public function checkAccess(UserInterface $user = NULL) { return shortcut_set_switch_access($user); }
  • 27. D8: Access check Access check for everyone grant access to everyone _access: TRUE
  • 28. D8: Access check Multiple access check - node.add_page: path: '/node/add' defaults: _title: 'Add content' _content: 'DrupalnodeControllerNodeController::addPage' options: _access_mode: 'ANY' _node_operation_route: TRUE requirements: _permission: 'administer content types' _node_add_access: 'node'
  • 29. Forms
  • 30. 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', );
  • 31. 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)
  • 32. D8: Form Router Forms are classes There is no method in forms as forms are presented as one class Use _form instead of _content or _controller user.pass: path: '/user/password' defaults: _form: 'DrupaluserFormUserPasswordForm' _title: 'Request new password' requirements: _access: 'TRUE' options: _maintenance_access: TRUE
  • 33. D8: Form Interface namespace DrupalCoreForm; interface FormInterface { public function getFormId() { return 'user_pass'; }
  • 34. D8: Form Interface public function buildForm(array $form, FormStateInterface $form_state) { $form['name'] = array( '#type' => 'textfield', '#title' => $this->t('Username or email address'), '#size' => 60, '#maxlength' => max(USERNAME_MAX_LENGTH, Email::EMAIL_MAX_LENGTH), '#required' => TRUE, '#attributes' => array( 'autocorrect' => 'off', 'autocapitalize' => 'off', 'spellcheck' => 'false', 'autofocus' => 'autofocus', ), );
  • 35. pubDlic8 fu:n Fctioonr mvali dIantetFeorrmfa(acrreay &$form, FormStateInterface $form_state) { $name = trim($form_state->getValue('name')); $users = $this->userStorage->loadByProperties(array('mail' => $name, 'status' => '1')); if (empty($users)) { $users = $this->userStorage->loadByProperties(array('name' => $name, 'status' => '1')); } if ($account && $account->id()) { $form_state->setValueForElement(array('#parents' => array('account')), $account); } else { $form_state->setErrorByName('name', $this->t('Sorry, %name is not recognized as a username or an email address.', array('%name' => $name))); $account = reset($users); }
  • 36. public function submitForm(array &$form, FormStateInterface $form_state) { $langcode = $this->languageManager->getCurrentLanguage()->getId(); $account = $form_state->getValue('account'); // Mail one time login URL and instructions using current language. $mail = _user_mail_notify('password_reset', $account, $langcode); if (!empty($mail)) { $this->logger('user')->notice('Password reset instructions mailed to %name at %email.', array('%name' => $account->getUsername(), '%email' => $account->getEmail())); drupal_set_message($this->t('Further instructions have been sent to your email address.')); } $form_state->setRedirect('user.page'); }
  • 37. D8: Form Base class ** generic base class - this includes string translation, link generator DrupalCoreFormFormBase for example - class UserLoginForm extends FormBase * * Base class for implementing system configuration forms. DrupalcoreformConfigFormBase for example - class MenuSettingsForm extends ConfigFormBase ** base class for a confirmation form. DrupalCoreFormConfirmFormBase for example - class UserMultipleCancelConfirm extends ConfirmFormBase
  • 42. 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', );
  • 43. D8: menu local tasks user.links.task.yml user.page: route_name: user.page base_route: user.page title: 'Log in' weight: -10 user.pass: route_name: user.pass base_route: user.page title: 'Request new password'
  • 45. 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', );
  • 46. D8: Local action node.links.action.yml node.add_page: route_name: node.add_page title: 'Add content' appears_on: - system.admin_content
  • 47. 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' class: Drupalblock_contentPluginMenuLocalActionBlockContentAddLocalAction appears_on: - block.admin_display - block.admin_display_theme - block_content.list
  • 49. D7: Contextual links $items['admin/structure/block/manage/%/%/configure'] = array( 'title' => 'Configure block', 'type' => MENU_DEFAULT_LOCAL_TASK, 'context' => MENU_CONTEXT_INLINE, );
  • 50. D8: Contextual links block.links.contextual.yml block_configure: title: 'Configure block' route_name: 'entity.block.edit_form' group: 'block'
  • 51. D8: Path based breadcrumb breadcrumb is path based in Drupal 8 /node/add/content /node/add /node / https://www.drupal.org/node/2098323
  • 53. Options _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 Useful Tips
  • 54. Useful links 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
  • 55. THANK YOU! Kalpana Goel William Hurley

Hinweis der Redaktion

  1. This is a general overview of how routing works. So request comes in via your mobile devices or browser and you get a response in the format of JSON or HTML, an image, a redirect or a 404 return. Drupal routing works with Symfony HTTP Kernel, but you don’t need to know the details how it works. In Symfony there is an object which converts request into response which is called HTTP kernel. router matches the incoming URl to a specific route and returns information about the route including controller that should be executed. Symfony kernel executes the controller, which returns a response object.
  2. hook_menu did too much in Drupal 7 and it was very complicated to understand what it was doing or it was very difficult to do any advanced task with it.
  3. This example is from user module from Drupal 7. As you can see it has path - user/logout, title as change log out, access callback, page callback, weight, menu-name, and this callback happens to be in separate file - user.pages.inc
  4. This is a page callback in Drupal 7. All it does is logs out the user, closes the session and takes user to the homepage.
  5. So this part takes over the routing aspect from drupal 7. This is routing yml for Drupal 8. modulename.routing.yml There is a machine name - user.logout of the route(modulname.something), path is - user/logout, it is same as what used to be in the key array items. There is two other section - defaults and requirements. The new thing is the controller part here which is following PSR-4 standard here but I am not covering here but this is the controller we are using here = Drupal\user\Controller\UserController instead of old page callback. Controller has a class name - \Drupal\user\Controller\UserController and logout is method name. For the requirement, it is same as access callback in hook_menu in Drupal 7, here we have if user is logged in as requirement instead of access argument.
  6. This is Drupal 8 version, In d8 everything is in objects and classes. so here we have a namespace. In Drupal 8, we are using psr -4 (to know where files are). we have a method here which is for logout. All it does is logs out the current user and redirect user to homepage. So the general concept is that instead of having a function in a one file you have it in in method in a class.
  7. Path is required in Drupal 8.
  8. If you are using node IDs in the URL, the ID can be automatically be converted to a node object by ParamConverter system so it loads an entity from an existing entity ID. In this example above, its using id as one of the parameter, you can see order doesn’t matter here. so we have a entity type view here and in the method, it loads the complete views object.
  9. In some cases, you can provide default value under defaults. By default drupal passes some parameter. if you go to user/somenumber/cancel/confirm page then something will be displayed and if you don’t provide default value for timestamp and hashed_pass then it will return 404 page.
  10. So we do have title_callback here, if you go to user/specific user page then you want to display user name as the title so we are using title_callback here. same syntax as controller.
  11. 5 available defaults in Drupal 8. it is required in drupal 8 Controller is for non-HTML, JSON or only for partial HTML but no theming or block will be output. entity_view - value is entity_type.view_mode. for example node.teaser will return render array of the node in teaser mode. entity_form - for example _entity_form: node.default will display the default node form. entity_list : - for example view_mode returns the list of view modes. (Value is the entity type/view mode to show)
  12. requirements - determines what conditions must be met in order to grant access to the route. role - since this can be different for sites so its recommended to use permission based on access restriction. _format:json - so it only matches requests when the accept header is json _module -
  13. requirements - determines what conditions must be met in order to grant access to the route. role - since this can be different for sites so its recommended to use permission based on access restriction. _format:json - so it only matches requests when the accept header is json _module
  14. requirements - determines what conditions must be met in order to grant access to the route. role - since this can be different for sites so its recommended to use permission based on access restriction. _format:json - so it only matches requests when the accept header is json _module
  15. requirements - determines what conditions must be met in order to grant access to the route. role - since this can be different for sites so its recommended to use permission based on access restriction. _format:json - so it only matches requests when the accept header is json _module
  16. In Drupal 8, routing is very powerful. So now you need to check access on the page like does the user has certain role or permission so symfony provides requirements. So here is _permission and also there is role so you can specify if user has permission to access the content based on role and permission. There is also _entity_access permission. So if user go to node.edit so if user has permission to edit the node
  17. In Drupal 8, you can also have multiple access checks. In the above route, there are two access check. options “any” means if either of the requirements is true then user will be able to access the page. If there is _access_mode: All then both requirements need to meet in order to access the page. This is more powerful than Drupal 7. Default is “ALL” A very interesting thing here - _node_operation_route:TRUE - You can configure in node module that all node related routes show the admin theme so this is a flag which flags the route here.
  18. In Drupal 8, we are using form api such as user login page. In the previous example we saw _controller, _content and so on. in Drupal 8 forms are classes. use _form . there is no method so one form is presented as one class. here in this example, we have a user login form
  19. In Drupal 8, here is user login form, it has a getFormId function, buildform function, and submit function, validateAuthentication, validateName and validateFiinal function. build form lets you build the form structure. submit method is executed when form is submitted. validateName function is for -- Sets an error if supplied username has been blocked. validateAuthentication function is for checking supplied username/password against local users table. validateFinal function is for checking if user was not authenticated, or if too many logins were attempted, Code was too long to paste here so just wanted to show you an example of form in Drupal 8.
  20. In Drupal 8, we are using form api such as user login page. In the previous example we saw _controller, _content and so on. in Drupal 8 forms are classes. use _form . there is no method so one form is presented as one class. here in this example, we have a user login form
  21. In Drupal 8, here is user login form, it has a getFormId function, buildform function, validateForm, and submit function. build form lets you build the form structure. validateForm is for flagging errors in submitted data. submit method is executed when form is submitted and has passed validation. Code was too long to paste here so just wanted to show you an example of form in Drupal 8.
  22. In Drupal 8, here is user login form, it has a getFormId function, buildform function, validateForm, and submit function. build form lets you build the form structure. validateForm is for flagging errors in submitted data. submit method is executed when form is submitted and has passed validation. Code was too long to paste here so just wanted to show you an example of form in Drupal 8.
  23. In Drupal 8, here is user login form, it has a getFormId function, buildform function, validateForm, and submit function. build form lets you build the form structure. validateForm is for flagging errors in submitted data. submit method is executed when form is submitted and has passed validation. Code was too long to paste here so just wanted to show you an example of form in Drupal 8.
  24. In Drupal 8, here is user login form, it has a getFormId function, buildform function, and submit function, validateFinal function is for checking if user was not authenticated, or if too many logins were attempted,
  25. There are some helper classes for form . ConfigFormBase - Provides an generic base class for a confirmation form. FormBase - generic base class - includes string translation, link generator, ConfirmFormBase -
  26. in Drupal 8 you have menu local tasks in its own file so here we have user.links.task.yml file.
  27. in Drupal 8 you have menu local tasks in its own file so here we have user.links.task.yml file.
  28. in Drupal 8 you have menu local tasks in its own file so here we have user.links.task.yml file.
  29. in Drupal 8 you have menu local tasks in its own file so here we have user.links.task.yml file. here we don’t path anymore but we have route_name, base_route, title, and weight. base_route so tabs appear on same page.
  30. in Drupal 8 you have menu local tasks in its own file so here we have user.links.task.yml file. here we don’t path anymore but we have route_name, base_route, title, and weight. base_route so tabs appear on same page.
  31. in Drupal 8 we have local action which is add content here in this image. so you can easily create some content.
  32. in Drupal 8, you can define local action in node.links.action.yml. you have machine name, route name, title. important thing to notice is “appears on” where this local action should appear.
  33. in Drupal 8, you can define local action in node.links.action.yml. you have machine name, route name, title. important thing to notice is “appears on” where this local action should appear.
  34. in Drupal 8, if you hover over any block then you get this “configure block” icon so in drupal 8 you can configure block where should it appear and you can do that in contextual yml file.
  35. in Drupal 8, you can configure block where should it appear and you can do that in contextual yml file for example - block.links.contextual.yml. again machine name, title, group, and route name. everything which is related to block contextual link should appear under block group
  36. in Drupal 8, you can configure block where should it appear and you can do that in contextual yml file for example - block.links.contextual.yml. again machine name, title, group, and route name. everything which is related to block contextual link should appear under block group Check BlockViewBuilder - group block is defined there in the render array
  37. in Drupal 8, you can configure block where should it appear and you can do that in contextual yml file for example - user.links.contextual.yml. again machine name, title, group, weight, and route name so its like i want to display delete role on user.role_delete route.
  38. hook_menu did too much in Drupal 7 and it was very complicated to understand what it was doing or to do anything very advanced tasks.
  39. hook_menu did too much in Drupal 7 and it was very complicated to understand what it was doing or to do anything very advanced tasks.