Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Building rednoseday.com on Drupal 8

Slides from my session at DrupalCamp London 2017, http://drupalcamp.london/session/building-reusable-websites-drupal-8-lessons-learned-transforming-rednosedaycom

  • Be the first to comment

  • Be the first to like this

Building rednoseday.com on Drupal 8

  1. 1. Building rednoseday.com on Drupal 8 Peter Vanhee
 Tech Lead at Comic Relief
 @pvhee DrupalCamp London 2017
  2. 2. • Comic Relief strives to create a just world free from poverty • We raise millions of pounds through two big fundraising campaigns – Red Nose Day and Sport Relief. • We spend that money in the best possible way to tackle the root causes of poverty and social injustice. • We use the power of our brand to raise awareness of the issues that we care most about.
  3. 3. Who am I? • Tech Lead at Comic Relief 
 https://technology.comicrelief.com • Founder of Marzee Labs, a tech shop from Barcelona @marzeelabs • Long-time Drupal contributor @pvhee
  4. 4. Drupal at Comic Relief • 2014: comicrelief.com • 2015: 2015.rednoseday.com • 2016: sportrelief.com
  5. 5. Drupal at Comic Relief • 2014: comicrelief.com • 2015: 2015.rednoseday.com • 2016: sportrelief.com • 2017: rednoseday.com
  6. 6. A fresh start? • Build a campaign website • Build a product that can build campaign websites • Build a product that allows editors to reorganise row components to build a website • Continuously iterate over our codebase
  7. 7. A product should… • support iterative development • have a clear versioning scheme • have tests to guarantee quality • provide a sensible default start for any campaign • allow for customisation
  8. 8. Technology Choice? Drupal 8, because of • embracing industry PHP standards • built on top of Symfony, use of Twig and Composer • editorial features “out of the box” • accessibility features • built-in REST capabilities • a development challenge
  9. 9. You can’t be that kid standing at the top of the waterslide, overthinking it. You have to go down the chute.
 Tina Fey
  10. 10. Ingredients to build our product • Focus on Editor Experience • Automate and streamline • Decoupled services
  11. 11. Editor Experience
  12. 12. Landing pages as the norm • First iteration: panels with panelizer • Second iteration: panels with panelizer and embedded paragraphs • Third iteration: paragraphs with block reference
  13. 13. Header with Menu Footer Paragraph 1 Paragraph 2 Paragraph 3 Paragraph n … library of blocks custom blocks 
 (like email signup) Editorial blocks Paragraph types “content wall”
 (rows + teasers are blocks) Cards blocks are reusable paragraphs are not reusable Quotes Embed Node Block reference
  14. 14. BLOCKS PARAGRAPHS reusable not reusable libraryquick edit contextual links only editable via node no quick-edit
 (see node …) content fields layout fields reference
  15. 15. Living Style Guide
  16. 16. Living Style Guide • Using KSS, “a documentation syntax for CSS” • Our new “incubation area” • Code and style guide are one — no need to update one or the other independently thus guaranteeing it stays fresh!
  17. 17. Style-guide driven development Component idea Style Guide
 (or Pattern Lab)
 
 HTML, SCSS, JS Review
 Multi-device QA Sign-off Drupal development
 
 Content model
 View modes
 Component module
 Twig / PHP

  18. 18. Improved editor experience Red Nose Day 2015
 (Drupal 7) Red Nose Day 2017
 (Drupal 8)
  19. 19. Automate & streamline everything
  20. 20. A build in one step • Package up our website product using an installation profile and using CMI, via config_devel • Default content in JSON • Use a build tool — we use Phing and run 
 phing build often
  21. 21. Config modules
  22. 22. Collaborative coding
  23. 23. No automation without tests • Code quality checks using CodeSniffer, phpmd, phpcpd • Configuration checks using config_devel • Distribution installation tests using phing build • Behavior tests on distribution using Behat • Drupal log checks (no errors, warnings generated by Behat) • Visual regression tests using BBC Wraith
  24. 24. Behat tests
  25. 25. Continuous Integration
  26. 26. Preview branches
  27. 27. Decoupled services
  28. 28. Slide from Chet Haase
  29. 29. Minimise custom code • we have around 2000 custom lines of PHP code (options callbacks, custom Display Suite fields, Solr tweaks) • “Non-glue code” is contributed back as standalone Drupal modules: rabbitmq, social_links
  30. 30. The Embed Pattern
  31. 31. The Queue Pattern Producer = Drupal Queue Consumer = 3rd party an example: email list subscription
 - Producer: Email Signup Form
 - Queue: holds email address, template ID, etc.
 - Consumer: PHP / nodejs app talking to MailChimp

  32. 32. Drupal Producer/** * Our signup form. */ class ExampleForm extends FormBase { public function buildForm(array $form, Form…face $form_state) { $form['email'] = [ '#type' => 'email', '#title' => $this->t(‘Your email address.'), ]; $form['show'] = [ '#type' => 'submit', '#value' => $this->t('Submit'), ]; return $form; } public function submitForm(array &$form, Form…face $form_state) { // Get the data you want to send to the queue. $data = $form_state->getValue('email'); // Get the queue config and send it to the data to the queue. $queue_name = 'queue1'; $queue_factory = Drupal::service('queue'); $queue = $queue_factory->get($queue_name); $queue->createItem($data); // Send some feedback. drupal_set_message( $this->t(‘Added data to queue @queue: @email', [ '@queue' => $queue_name, '@email' => $form_state->getValue('email'), ]) ); } } // Our rabbitmq.config.yml configuration exchanges: my_exchange: type: 'direct' passive: false durable: true auto_delete: false internal: false nowait: false queues: my_queue: passive: false durable: false exclusive: false auto_delete: true nowait: false routing_keys: - 'my_exchange.my_queue' // Add to settings.php $settings['queue_service_queue1'] = 
 'queue.rabbitmq'; rabbitmq module at 
 drupal.org/project/rabbitmq using Drupal 8 Queue API
  33. 33. RabbitMQ Queue
  34. 34. 3-rd party Consumer class QueueConsumer implements ConsumerInterface { /* @var stdClass */ private $processingService; /** * Parse message as JSON and send to processor * * @param AMQPMessage $msg * @return bool */ public function execute(AMQPMessage $msg) { if ($decodedMessage = json_decode($msg->body)) { try { return $this->processingService->process($decodedMessage); } catch (Exception $e) { $this->logger->alert(‘Queue process error:' . $e->getMessage()); } } else { $this->logger->info(sprintf('Unable to parse as JSON: "%s"', $msg->body)); } return false; } }
  35. 35. Towards micro-services • oEmbed / iFrame for integrating 3rd-party apps in the CMS • Message Queues for decoupling logic
  36. 36. What about rednoseday.com?
  37. 37. From product to website campaign 
 distribution
 - v1.1
 - … 
 - v1.36
 - … 
 - v2.x rednoseday.com
 comicrelief.com rednoseday.org (USA) sportrelief.com
  38. 38. From product to website campaign 
 distribution
 - v1.1
 - … 
 - v1.36
 - … 
 - v2.x rednoseday.com
 - campaign v1.36 as dependency - env vars (queue info, db info, …)
 - RND17 theme
 - YML site configuration sites/ default/config - composer / make - hook_update
 - drush config-devel-import comicrelief.com rednoseday.org (USA) sportrelief.com you?
  39. 39. Questions?
 @pvhee
 www.rednoseday.com Friday 24 March

×