Drupal 8 in action, the route to the method

662 views
586 views

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
662
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
7
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Drupal 8 in action, the route to the method

  1. 1. Drupal 8 in action, the route to the method @juanolalla #DrupalCampEs
  2. 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. 3. Wellcome to Drupal 8 Routing
  4. 4. Goodbye to hook_menu()
  5. 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. 6. Drupal 8 uses Symfony2 Routing component And also uses Symfony CMF RoutingBundle for dynamic routing
  7. 7. What is a route?
  8. 8. A route is an object defined by 1. Path 2. Default values 3. Requirements 4. Options 5. Host 6. Schemes 7. Methods
  9. 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. 10. The Routing component gets routes from • PHP code: • a RouteCollection object • closures • class annotations • External files: • YAML • XML • PHP
  11. 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. 12. Let’s start with a plain “hello world” using a /hello-world path
  13. 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. 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. 15. HloWrd el ol!
  16. 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. 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. 18. {getn""el Wrd" "reig:Hlo ol!}
  19. 19. Returning "hello world" inside Drupal content using a /hello-world path
  20. 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. 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. 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. 23. Returning a "hello world" greeting configuration form at /admin/config/people/greeting
  24. 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. 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. 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. 27. Advanced Routing
  28. 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. 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. 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. 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. 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. 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. 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. 35. Access Check _o_hl_o_as TU yusalntps: RE
  36. 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. 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. 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. 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. 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. 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. 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. 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. 44. Building Dynamic Routes Implement a route subscriber class
  45. 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. 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. 47. Dependency injection Keep your controllers clean and thin
  48. 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. 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. 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. 51. Want to see more coming? /on#rplcnrbt ji dua-otiue
  52. 52. Thank you!

×