• Like
Drupal 8 in action, the route to the method
Upcoming SlideShare
Loading in...5

Thanks for flagging this SlideShare!

Oops! An error has occurred.

Drupal 8 in action, the route to the method



Published in Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads


Total Views
On SlideShare
From Embeds
Number of Embeds



Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

    No notes for slide


  • 1. Drupal 8 in action, the route to the method @juanolalla #DrupalCampEs
  • 2. about.me/juanolalla Juan Olalla web developer focused on drupal at @ideup (@gowex) Motivation I’ve recently been contributing to Drupal 8 core and I want to share with you what I've learned
  • 3. Wellcome to Drupal 8 Routing
  • 4. Goodbye to hook_menu()
  • 5. Goodbye to hook_menu() for routing and for everything else... Routing Routes defined in routing.yml and controllers Menu links Defined in hook_default_menu_links() Local actions Plugins defined in local_actions.yml Local tasks Plugins defined in local_tasks.yml Contextual links Plugins defined in contextual_links.yml Breadcrumbs Implementing BreadcrumbBuilder plugins Links can be related regardless of the path, managed by machine names.
  • 6. Drupal 8 uses Symfony2 Routing component And also uses Symfony CMF RoutingBundle for dynamic routing
  • 7. What is a route?
  • 8. A route is an object defined by 1. Path 2. Default values 3. Requirements 4. Options 5. Host 6. Schemes 7. Methods
  • 9. ueSmoyCmoetRuigRue s yfnopnnotnot; $ot =nwRue rue e ot( 'acie{ot},/ pt /rhv/mnh' / ah ary'otolr = 'hwrhv',/ dfutvle ra(cnrle' > soAcie) / eal aus ary ra( 'ot'= '09{}[-]2' mnh > [-]4-09{}, 'udmi'= 'w|' sboan > wwm, ) / rqieet , / eurmns ary) / otos ra(, / pin 'sboan.xml.o' / hs {udmi}eapecm, / ot ary) / shms ra(, / cee ary)/ mtos ra( / ehd ) ;
  • 10. The Routing component gets routes from • PHP code: • a RouteCollection object • closures • class annotations • External files: • YAML • XML • PHP
  • 11. Drupal 8 uses YAML to define routes foacie o.rhv: pt:'acie{ot} ah /rhv/mnh' dfut: eals _otn: cnet 'DuaootolrFootolr:hwrhv' rplfoCnrleoCnrle:soAcie rqieet: eurmns mnh '09{}[-]2' ot: [-]4-09{} sboan 'w|' udmi: wwm hs:'sboan.xml.o' ot {udmi}eapecm
  • 12. Let’s start with a plain “hello world” using a /hello-world path
  • 13. Defining the route in YAML /modules/foo/foo.routing.yml fohlowrd o.el_ol: pt:'hlowrd ah /el-ol' dfut: eals _otolr cnrle: 'DuaootolrFootolr:elWrd rplfoCnrleoCnrle:hlool' rqieet: eurmns _ces 'RE acs: TU'
  • 14. Creating the controller /modules/foo/lib/Controller/FooController.php nmsaeDuaootolr aepc rplfoCnrle; ueSmoyCmoetHtFudtoepne s yfnopnntponainRsos; casFootolr{ ls oCnrle pbi fnto hlool( { ulc ucin elWrd) $epne=nwRsos(HloWrd'; rsos e epne'el ol!) $epne>edr-st'otn-ye,'etpan) rsos-haes>e(CnetTp' tx/li'; rtr $epne eun rsos; } }
  • 15. HloWrd el ol!
  • 16. Drupal 8 will use PSR-4 for module classes instead of PSR-0 /modules/foo/lib/Controller/FooController.php instead of /modules/foo/lib/Drupal/foo/Controller/FooController.php drupal.org issue: https://drupal.org/node/1971198
  • 17. Returning a JSON response nmsaeDuaootolr aepc rplfoCnrle; ueSmoyCmoetHtFudtosnepne s yfnopnntponainJoRsos casFootolr{ ls oCnrle pbi fnto hlool( { ulc ucin elWrd) rtr nwJoRsos( eun e snepne ary'reig = 'el Wrd' ra(getn' > Hlo ol!) ) ; } }
  • 18. {getn""el Wrd" "reig:Hlo ol!}
  • 19. Returning "hello world" inside Drupal content using a /hello-world path
  • 20. Defining the route in YAML fohlowrd o.el_ol: pt:'hlowrd ah /el-ol' dfut: eals _otn: cnet 'DuaootolrFootolr:elWrd rplfoCnrleoCnrle:hlool' _il:'reig tte Getn' rqieet: eurmns _emsin 'cescnet priso: acs otn'
  • 21. Returning a render array nmsaeDuaootolr aepc rplfoCnrle; ueDuaoeCnrleotolrae s rplCrotolrCnrleBs; casFootolretnsCnrleBs { ls oCnrle xed otolrae pbi fnto hlool( { ulc ucin elWrd) $ul =ary) bid ra(; $ul[#akp]=$hs>(HloWrd'; bid'mru' ti-t'el ol!) rtr $ul; eun bid } }
  • 22. What about dynamic page titles? drupal_set_title() is being removed Use _title_callback in the route defaults dfut: eals _il_alak tteclbc: 'DuaootolrFootolr:eTte rplfoCnrleoCnrle:gtil' Or return it as part of the main render array $ul[#il' =.. bid'tte] .
  • 23. Returning a "hello world" greeting configuration form at /admin/config/people/greeting
  • 24. Defining the route in YAML foamngetn: o.di_reig pt:'amncni/epegetn' ah /di/ofgpol/reig dfut: eals _om 'DuaoomFoom fr: rplfoFroFr' rqieet: eurmns _emsin 'diitrgetn' priso: amnse reig
  • 25. ueDuaoeFrofgomae s rplCromCniFrBs; casFoometnsCniFrBs { ls oFr xed ofgomae pbi fnto gtomd){rtr 'o_om;} ulc ucin eFrI( eun fofr' pbi fnto bidomary$om ary&fr_tt){ ulc ucin ulFr(ra fr, ra $omsae $om'o_reig]=ary fr[fogetn' ra( 'tp'= 'etil' #ye > txfed, 'tte = $hs>(Getn', #il' > ti-t'reig) 'dfutvle = 'elwWrd' #eal_au' > Hlo ol!, ) ; rtr prn:bidom$om $omsae; eun aet:ulFr(fr, fr_tt) } }
  • 26. FormBase implements FormInterface nmsaeDuaoeFr; aepc rplCrom itraeFrItrae{ nefc omnefc pbi fnto gtomd) ulc ucin eFrI(; pbi fnto bidomary$om ary&fr_tt) ulc ucin ulFr(ra fr, ra $omsae; pbi fnto vldtFr(ra &fr,ary&fr_tt) ulc ucin aiaeomary $om ra $omsae; pbi fnto sbiFr(ra &fr,ary&fr_tt) ulc ucin umtomary $om ra $omsae; }
  • 27. Advanced Routing
  • 28. dfut: eals #Cnrltefl rsos aatfo Dua etacnet oto h ul epne pr rm rpl xr otn _otolr 'DuaokCnrleokotolr:okxot cnrle: rplbootolrBoCnrle:boEpr' #Ptcneti temi rgo adltDua d ters u otn n h an ein n e rpl o h et _otn:'DuaokCnrleokotolr:okedr cnet rplbootolrBoCnrle:boRne' #Gttebidommto o acasetnigaDua Fr e h ulFr ehd f ls xedn rpl om _om 'DuaokFroketnsom fr: rplboomBoStigFr'
  • 29. Entity defaults dfut: eals #Cl bidomfrteato ett adoeainFr al ulFr o h cin niy d prto om _niyfr:'cinad ett_om ato.d' #Dslyals o txnm_oauayett ojcs ipa it f aooyvcblr niy bet _niyls:'aooyvcblr' ett_it txnm_oauay #So tefl ve md o aue ett ojc hw h ul iw oe f sr niy bet _niyve:'srfl' ett_iw ue.ul
  • 30. Passing parameters to the controller method #Prmtrdfndi tept aaee eie n h ah pt:'cmet{omn}apoe ah /omn/cmet/prv' #Dfutprmtr eal aaee pt:'amnsrcuetps ah /di/tutr/ye' dfut: eals ett_ye 'oetp' niytp: nd_ye #Otoa (ohi tept adwt adfutvle pinl bt n h ah n ih eal au) pt:'amncni/erhpt/ky} ah /di/ofgsac/ah{es' dfut: eals ky:NL es UL
  • 31. nd.vriwtps oeoeve_ye: pt:'amnsrcuetps ah /di/tutr/ye' dfut: eals _otn: cnet 'DuaoeEttotolrEttLsCnrle:lsig rplCrniyCnrleniyitotolr:itn' ett_ye 'oetp' niytp: nd_ye _il:'otn tps tte Cnet ye' casEttLsCnrle etnsCnrleBs { ls niyitotolr xed otolrae pbi fnto lsig$niytp){ ulc ucin itn(ett_ye rtr $hs>niyaae( eun ti-ettMngr) -gtitotolr$niytp) >eLsCnrle(ett_ye -rne(; >edr) } }
  • 32. Parameters are upcasted to entities by entity type id cnatproa_ae otc.esnlpg pt:'ue/ue}cnat ah /sr{sr/otc' cnatst_aectgr: otc.iepg_aeoy pt:'cnat{otc_aeoy' ah /otc/cnatctgr} casCnatotolr{ ls otcCnrle pbi fnto cnatesnlaeUeItrae$sr {.} ulc ucin otcProaPg(srnefc ue) .. pbi fnto cnatieae ulc ucin otcStPg( CtgrItrae$otc_aeoy=NL){.} aeoynefc cnatctgr UL .. }
  • 33. Explicitly converting parameters into entities fohloue: o.el_sr pt:'{o_sr/el/ue} ah /foue}hlo{sr' #eg //el/ .. 1hlo2 dfut: eals _otn:'..Footolr:elUe' cnet .oCnrle:hlosr otos pin: prmtr: aaees foue: o_sr tp:'niyue' ye ett:sr #{o_sr wl as b pse a aue ett foue} il lo e asd s sr niy
  • 34. Regular expressions requirements for parameters #{p prmtrcnol b 'nbe o 'ial' o} aaee a ny e eal' r dsbe vesu.prto: iw_ioeain pt:'amnsrcuevesve/ve}{p' ah /di/tutr/iw/iw{iw/o} rqieet: eurmns o:'nbedsbe p eal|ial' #{sr prmtrcnol b anme ue} aaee a ny e ubr ue.iw srve: pt:'ue/ue} ah /sr{sr' rqieet: eurmns ue:+ sr d
  • 35. Access Check _o_hl_o_as TU yusalntps: RE
  • 36. Drupal 8 doesn't implement Symfony2 Security component, and manages access from routing Symfony uses a separate Security component for controlling route access that is too complex to integrate in Drupal 8. Drupal 8 implements access checkers services, which will ignore, allow or deny the access based on a requirement on the route.
  • 37. Checking Permissions nd.vriwtps oeoeve_ye: pt:'amnsrcuetps ah /di/tutr/ye' dfut: eals _otn: cnet 'DuaoeEttotolrEttLsCnrle:lsig rplCrniyCnrleniyitotolr:itn' ett_ye 'oetp' niytp: nd_ye _il:'otn tps tte Cnet ye' rqieet: eurmns _emsin 'diitrcnettps priso: amnse otn ye'
  • 38. Still setting permissions in hook_permission() fnto nd_emsin){ ucin oepriso( rtr ary eun ra( 'diitrcnettps = ary amnse otn ye' > ra( 'il'= t'diitrcnettps) tte > (Amnse otn ye', 'etitacs'= TU, rsrc ces > RE ) , ) ; } I asked for hook_permission() in IRC #drupal-contribute <timplunkett> juanolalla: no plans to replace that AFAIK
  • 39. Common access checkers provided by Drupal core #Awy ps,o 'AS't awy fi adbokacs las as r FLE o las al n lc ces rqieet: eurmns _ces 'RE acs: TU' #Rl Issprtdb ""(n rl)o ""(l rls oe D eaae y , ay oe r + al oe) rqieet: eurmns _oe 'uhniae,di' rl: atetctdamn #Pse i teue i lge i ass f h sr s ogd n rqieet: eurmns _sri_ogdi:'RE ue_slge_n TU'
  • 40. Other useful access checkers provided #Cek i ayal(/)teseiidmdlsaeeald hcs f n/l ,+ h pcfe oue r nbe rqieet: eurmns _ouedpnece:'oe+sac' mdl_eednis nd erh #Cek acs t teseiidett_yeoeain hcs ces o h pcfe niytp.prto rqieet: eurmns _niyacs:'oeei' ett_ces nd.dt #Cek acs t teseiidett_yeett_ude hcs ces o h pcfe niytp:niybnl rqieet: eurmns _niycet_ces 'aooytr:txnm_oauay' ett_raeacs: txnm_em{aooyvcblr}
  • 41. Declaring your own custom access checker Declare your requirement checker in .routing.yml rqieet: eurmns _o_hl_o_as 'RE yusalntps: TU' Register an access checker class as a service (in .services.yml) srie: evcs acs_hc.o.adl: cescekfognaf cas DuaocesGnafceshc ls: rplfoAcsadlAcsCek tg: as -{nm:acs_hc } ae cescek
  • 42. Writting your own custom access checker class casGnafceshc ipeet SaiAcsCeknefc { ls adlAcsCek mlmns ttcceshcItrae pbi fnto apiso){ ulc ucin pleT( rtr ary'yusalntps'; eun ra(_o_hl_o_as) } pbi fnto acs(ot $ot,Rqet$eus){ ulc ucin cesRue rue eus rqet $eurmn =$ot-gteurmn(_o_hl_o_as) rqieet rue>eRqieet'yusalntps'; i (i_ra(hts,$ot-gtcee() f !nary'tp' rue>eShms) & $eurmn = 'RE){ & rqieet = TU' rtr sai:DN;/ o rtr sai:ALW eun ttc:EY / r eun ttc:LO }/ N rtr masohrcekr wl dcd / o eun en te hces il eie } }
  • 43. Access mode options, checking any or all requirements nd.d_ae oeadpg: pt:'nd/d' ah /oead dfut: eals _il:'d pg' tte Ad ae _otn:'DuaoeCnrleoeotolr:dPg' cnet rplndotolrNdCnrle:adae otos pin: _cesmd:'N' acs_oe AY rqieet: eurmns _emsin 'diitrcnettps priso: amnse otn ye' _oeadacs:'oe nd_d_ces nd'
  • 44. Building Dynamic Routes Implement a route subscriber class
  • 45. /core/modules/system/Routing/RouteSubscriber.php nmsaeDuaytmRuig aepc rplsseotn; ueDuaoeRuigRueusrbrae s rplCrotnotSbcieBs; ueSmoyCmoetRuigRue s yfnopnnotnot; ueSmoyCmoetRuigRueolcin s yfnopnnotnotCleto; /* * *Poie dnmcrue frteeamnsrto. rvds yai ots o hm diitain * / casRueusrbretnsRueusrbrae{ ls otSbcie xed otSbcieBs poetdfnto rue(otCleto $olcin {.} rtce ucin otsRueolcin cleto) .. }
  • 46. poetdfnto rue(otCleto $olcin { rtce ucin otsRueolcin cleto) frah(ittee( a $hm){ oec ls_hms) s tee $ot =nwRue rue e ot( 'di/pernestig/ .$hm-nm, amnapaac/etns' tee>ae ary ra( 'fr'= 'DuaytmFrhmStigFr' _om > rplsseomTeeetnsom, 'hm_ae = $hm-nm teenm' > tee>ae ) , ary'priso'= 'diitrtee', ra(_emsin > amnse hms) ) ; $olcin>d( cleto-ad 'ytmteestig_ .$hm-nm,$ot) sse.hm_etns' tee>ae rue; } }
  • 47. Dependency injection Keep your controllers clean and thin
  • 48. Our classes shouldn't have hard-coded dependencies casSnCnrle { ls ogotolr pbi fnto gtadmog){ ulc ucin eRnoSn( / d_ur( i ahr-oe dpnec / bqey) s adcdd eedny $og =d_ur(SLC nm FO {og})>ecCl) sns bqey'EET ae RM sns'-ftho(; $og=$og[ad0 cut$og)-1] sn snsrn(, on(sns ); rtr nwJoRsos( eun e snepne ary'og = $og ra(sn' > sn) ) ; } }
  • 49. Decoupling the dependency poetd$aaae / DuaoeDtbsoncin rtce dtbs; / rplCraaaeCneto; pbi fnto gtadmog){ ulc ucin eRnoSn( $og =$hs>aaae sns ti-dtbs -qey'EETnm FO {og})>ecCl) >ur(SLC ae RM sns'-ftho(; rtr $og[ad0 cut$og)-1] eun snsrn(, on(sns ); }
  • 50. Getting the dependency injected ueDuaoeDtbsoncin s rplCraaaeCneto; ueDuaoeDpnecIjcinCnanrnetoItrae s rplCreednynetootieIjcinnefc; ueSmoyCmoetDpnecIjcinCnanrnefc; s yfnopnneednynetootieItrae casSnCnrle ipeet CnanrnetoItrae{ ls ogotolr mlmns otieIjcinnefc poetd$aaae rtce dtbs; pbi fnto _cntutCneto $aaae { ulc ucin _osrc(oncin dtbs) $hs>aaae=$aaae ti-dtbs dtbs; } pbi sai fnto cet(otieItrae$otie){ ulc ttc ucin raeCnanrnefc cnanr / Isataetecnrle wt adtbs ojc / ntnit h otolr ih aaae bet rtr nwsai(cnanr>e(dtbs') eun e ttc$otie-gt'aaae); }
  • 51. Want to see more coming? /on#rplcnrbt ji dua-otiue
  • 52. Thank you!