Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Drupal8 for Symfony developers

Drupal8 for Symfony developers

Drupal8 modernization (new object-oriented base) and adoption of many Symfony components is a huge step in connecting these two amazing communities and amazing projects. Drupal8 is not powered by full-stack Symfony and there is still many differences between these two relatives, but still, Symfony developers should master it easily. This talk is for Symfony developers who don't have experience with Drupal8. It will guide you through routing, controllers, hooks, events, Drupal Console, DI and many other interesting elements that power Drupal8 under the hood. It will also show how to build custom modules Symfony way.

Antonio Peric-Mazar

July 01, 2017

More Decks by Antonio Peric-Mazar

Other Decks in Programming


  1. Drupal8 for Symfony Developers Antonio Perić-Mažar
 01.07.2017 @ #dpc

  2. @antonioperic About me • Antonio Perić-Mažar, mag. ing. comp. •

    CEO, Co-Founder @ Locastic • Co-Founder @ Shift Conference • Software developer, Symfony2 • Open Source Contributor • SFUGCRO
 • www.locastic.com • antonio@locastic.com • @antonioperic
  3. @antonioperic Locastic • We help clients create amazing web and

    mobile apps (since 2011) • design and development agency • mobile development • web development • UX/UI • Training and Consulting • Shift Conference, Symfony Croatia • www.locastic.com • @locastic
  4. @antonioperic Fun Facts

  5. @antonioperic

  6. @antonioperic

  7. @antonioperic 31 years = 978 264 705 seconds

  8. @antonioperic Questions? • Any Drupal experts/developers here? • Symfony developers?

    • Symfony developers without Drupal knowledge
  9. @antonioperic Drupal 101 for SF developers

  10. @antonioperic Before we start, small disclaimer

  11. @antonioperic My world is Symfony

  12. @antonioperic —

  13. @antonioperic

  14. @antonioperic What this means • Drupal8 doesn’t use full stack

    Symfony, it uses components (maybe in future) • Moving Drupal to modern stack • Building powerful CMS on top of Symfony components • More learning for Drupal developers (OOP, Symfony, new concepts) • Connecting two big communities
  15. None
  16. @antonioperic Who is it for? • Content strategist • Site

    Administrators • Content editors • “Build stuff without writing code” • v8.3.2 • Professional developers • Bespoke applications • “Make writing code easier”
  17. @antonioperic In Drupal 8 there's three different types of knowledge

    that you're going to be using in order to work with it effectively.
  18. @antonioperic

  19. @antonioperic

  20. @antonioperic

  21. @antonioperic

  22. @antonioperic Symfony2 Framework Bundle Symfony2 Bundles Symfony2 CMF Bundles Symfony2

    Components Partnered Libs (twig, etc.) CMF Components Symfony fullstack Drupal 8 Distribution Drupal Core Modules Drupal Contrib Modules Drupal Core Libraries Symfony2 Components Partnered Libs (twig, etc.) Drupal Components
  23. @antonioperic Symfony Components • ClassLoader • Console • CssSelector •

    DependencyInjection • EventDispatcher • HttpFoundation • HttpKernel • Process • Routing • Serializer • Translation • Validator • Yaml
  24. @antonioperic • HTTP Kernel • Request / Response • Controllers

    • Event Dispatching • Listeners / Subscribers Dependency injection container
  25. @antonioperic Development environment

  26. None
  27. None
  28. @antonioperic Or just use your Symfony development environment • PHP

    built-in server • Vagrant • Docker • …
  29. @antonioperic Tools

  30. @antonioperic Drush • update core and contrib • download modules

    • enable modules • clear cache • update db • run cron • import config • export config • create user • change password • one time login • backup drupal • restore drupal • compile twig templates *Type “drush” to get full list - www.drushcommands.com
  31. None
  32. None
  33. None
  34. None
  35. None
  36. @antonioperic Drupal Console • update core and contrib • download

    modules • enable modules • clear cache • update db • run cron • import config • export config • generate console command • generate entity • generate content type • generate modules • run unit test *Type “drupal list” to get full list - drupalconsole.com/docs
  37. None
  38. None
  39. drupal list

  40. None
  41. None
  42. @antonioperic Installation

  43. @antonioperic How to install Drupal8 • Drush • drush dl

    drupal • Composer • Download zip file
  44. @antonioperic Lets use composer • drupal/drupal. • This uses Drupal

    itself as a template for the new site. It is the simplest solution but lacks additional configuration that can be helpful.
 • drupal-composer/drupal-project. • This open source project acts as a kickstarter for Composer-based Drupal sites. It provides default configuration that otherwise needs to be added manually.
  45. @antonioperic Let’s use composer

  46. @antonioperic Let’s use composer composer create-project drupal/drupal

  47. None
  48. None
  49. @antonioperic Let’s use composer composer require drupal/<modulename> for example: composer

    require drupal/token
  50. @antonioperic Let’s use composer composer require drupal/<modulename> for example: composer

    require drupal/token drupal module:install token
  51. @antonioperic Run in browser

  52. None
  53. None
  54. None
  55. None
  56. None
  57. None
  58. @antonioperic Add some content

  59. None
  60. drupal create:nodes

  61. drupal create:nodes

  62. @antonioperic We have content but something is missing

  63. None
  64. @antonioperic WebProfiler

  65. @antonioperic Module/Devel

  66. @antonioperic composer require drupal/devel drupal module:install devel

  67. None
  68. None
  69. None
  70. drush pm-enable devel

  71. None
  72. None
  73. None
  74. None
  75. None
  76. None
  77. None
  78. @antonioperic Under the Hood

  79. None
  80. None
  81. None
  82. None
  83. None
  84. None
  85. @antonioperic Request -> Response

  86. None
  87. @antonioperic What happens when request enters Drupal 1. Bootstrap configuration:

    ◦ Read the settings.php file, generate some other settings dynamically, and store them both in global variables and the Drupal\Component\Utility\Settings singleton object. ◦ Start the class loader, that takes care of loading classes. ◦ Set the Drupal error handler. ◦ Detect if Drupal is actually installed. If it is not, redirect to the installer script. 2. Create the Drupal kernel. 3. Initialize the service container (either from cache or from rebuild). 4. Add the container to the Drupal static class. 5. Attempt to serve page from static page cache (just like Drupal 7). 6. Load all variables (variable_get).
  88. @antonioperic What happens when request enters Drupal 7. Load other

    necessary (procedural) include files. 8. Register stream wrappers (public://, private://, temp:// and custom wrappers). 9. Create the HTTP Request object (using the Symfony HttpFoundation component). 10. Let the DrupalKernel handle it and return a response. 11. Send the response. 12. Terminate the request (modules can act upon this event).
  89. Deeper in Drupal End of Request

  90. None
  91. @antonioperic Pipeline 1. After the controller returned a render array,

    the VIEW will be triggered by the HttpKernel, because the controller result is not a Response, but a render array. 2. MainContentViewSubscriber is subscribed to the VIEW event. It checks whether the controller result is an array, and if so, it guarantees to generate a Response. 3. Next, MainContentViewSubscriber checks whether the negotiated request format is supported: 1. Any format for which a main content renderer service exists (an implementation of MainContentRendererInterface is supported. 2. If the negotiated request format is not supported, a 406 JSON response is generated, which lists the supported formats in a machine-readable way (as per RFC 2616, section 10.4.7). 4. Otherwise, when the negotiated request format is supported, the corresponding main content renderer service is initialized. A response is generated by calling MainContentRendererInterface::renderResponse() on the service. That's it
  92. @antonioperic Main Content Renderes • HTML: HtmlRenderer (text/html) • AJAX:

    AjaxRenderer (application/vnd.drupal-ajax) • Dialog: DialogRenderer (application/vnd.drupal-dialog) • Modal: ModalRenderer (application/vnd.drupal-modal
  93. None
  94. None
  95. None
  96. @antonioperic

  97. @antonioperic

  98. @antonioperic

  99. @antonioperic

  100. @antonioperic Routing

  101. None
  102. @antonioperic Available “defaults” keys • _controller
 The specified method is

    simply called with the specified route parameters, and is expected to return a response. • _content
 If specified, the _controller is set based on the request's mime type, and fills the content of the response with the result of the specified method (usually a string or render array). • _form
 If specified, the _controller is set to HtmlFormController::content, which responds with the specified form. This form must be a fully qualified class name (or service id) that implements FormInterface and usually extends FormBase. Indeed, form building has also become object oriented! • _entity_form
 If specified, the _controller is set to HtmlEntityFormController::content, which responds with the specified entity form (specified as {entity_type}.{add|edit|delete}).
  103. @antonioperic Available “requirements” keys • _permission
 The current user must

    have the specified permission. • _role
 The current user must have the specified role. • _method
 The allowed HTTP methods (GET, POST, etc). • _scheme
 Set to https or http. The request scheme must be the same as the specified scheme. This property is also taken into account when generating urls (Drupal::url(..)) rather than routing. If set, urls will have this scheme set fixed. • _node_add_access
 A custom access check for adding new nodes of some node type. • _entity_access
 A generic access checker for entities. • _format
 Mime type formats
  104. @antonioperic Controllers

  105. None
  106. None
  107. None
  108. None
  109. None
  110. None
  111. @antonioperic Services

  112. None
  113. None
  114. @antonioperic Events / Listeners

  115. @antonioperic

  116. @antonioperic Registering event subscribers Here are the steps to register

    an event subscriber: • Define a service in your module, tagged with 'event_subscriber' (see the Services topic for instructions). • Define a class for your subscriber service that implements \Symfony\Component\EventDispatcher\EventSubscriberInterface • In your class, the getSubscribedEvents method returns a list of the events this class is subscribed to, and which methods on the class should be called for each one. Example:
  117. None
  118. None
  119. @antonioperic Building Custom Module

  120. @antonioperic Creating custom model Steps: • Register your module (module_name.info.yml)

    • Add routing (*.routing.yml) • Add controller • Clear cache • Test if page is rendering well
  121. @antonioperic hello_symfony.info.yml

  122. None
  123. None
  124. @antonioperic

  125. @antonioperic

  126. @antonioperic hello_symfony.routing.yml

  127. None
  128. @antonioperic

  129. @antonioperic

  130. @antonioperic hello_symfony.links.menu.yml

  131. None
  132. @antonioperic

  133. @antonioperic PageExampleController

  134. None
  135. @antonioperic

  136. None
  137. @antonioperic

  138. None
  139. @antonioperic

  140. None
  141. @antonioperic

  142. None
  143. @antonioperic

  144. None
  145. None
  146. None
  147. @antonioperic

  148. None
  149. None
  150. @antonioperic

  151. @antonioperic Recap • Symfony components are main building tool for

    D8 • DIC is backbone of Drupal • DI for controllers is very easy • Events are replacing hooks • Building custom module is easy • Hardest thing is to start • This is just beginning there is a lot to learn about and from D8 • Documentation is not the best, read examples and code
  152. @antonioperic Thank you! antonio@locastic.com @antonioperic www.locastic.com Please rate my talk