Successfully reported this slideshow.

The History and Future of Drupal Theming.

1,499 views

Published on

Okay. Once upon a time there was a content management system that needed to render markup. So this Content Managment System returned strings of HTML. Well that really wasn't that great because there were these people out in the world called Front End Developers and it just so happens that Front End Developers actually care about what the HTML looks like. Oh, by the way, this Content Management System is named Drupal.

Read more: https://prague2013.drupal.org/session/history-future-drupal-theming

Published in: Technology, Business
  • Be the first to comment

  • Be the first to like this

The History and Future of Drupal Theming.

  1. 1. The History and Future of Drupal Theming by Carl Wiedemann (c4rl) Wednesday 2013-09-25 • 14:15
  2. 2. Hi! c4rl Carl Wiedemann
  3. 3. Where have we been? Where are we going? Discussion and planning :)
  4. 4. 2000 OO-based(!) theming, somewhat overridable.
  5. 5. 2001 Default markup in core provides more scalability.
  6. 6. 2002 The well-known theme() function appears.
  7. 7. 2003 Template-based theming (xtemplate) to avoid string concatenation (in some cases).
  8. 8. 2005 PHPTemplate arrives. Template variable overrides exist. FormAPI and altering arrives in concept.
  9. 9. 2007 Theme registry. Preprocess functions, .tpl.php file overrides.
  10. 10. 2007 hook_elements() appears. "Structured" vs "rendered" data bring together modern RenderAPI.
  11. 11. ALTER ALL OF THE THINGS ALTER ALL OF THE THINGS
  12. 12. http://drupal.org/node/134478#comment-538674 Posted by bjaspan on October 15, 2007 at 1:39pm "menu callbacks ought to return structured data, not rendered data"
  13. 13. <?php // OLD return theme('foo', $bar); <?php // NEW return array( '#theme' => 'foo', '#bar' => $bar, );
  14. 14. hook_page_alter() template_preprocess_foo() template_preprocess() template_process_foo() template_process() Templates can be overridden... Preprocessors can be overridden... Processors can be overridden... Theme functions still exist... hook_theme_registry_alter()...
  15. 15. by 2009 Many APIs. Theme system is brittle, inconsistent, difficult to grok.
  16. 16. Based on what we’ve built… What do we need?
  17. 17. What do we need? (1) Template-based markup that can be extended and overridden. hook_theme(), template_preprocess(), hook suggestions, theme registry, Twig (PHPTemplate).
  18. 18. What do we need? (2) Abstracted, alterable structure. Render arrays, hook_node_view(), hook_page_alter()
  19. 19. What do we need? (3) Sensible, accessible, API. theme(), drupal_render(), render() /hide()/show().
  20. 20. 2012 DrupalCon Denver Core Convo, Twig initiative, yay!
  21. 21. 2012-2013 Twig conversion, Portland Sprints, killed process layer, markup cleanup, yay.
  22. 22. So where are we going?
  23. 23. 8.x Kill concatenation 1757550 Theme system architecture 2004872 Theme registry service 1886448 theme() deprecation 2006152
  24. 24. PRESENT 1. I believe the biggest issue with Theming is a brittle RenderAPI.
  25. 25. PRESENT 2. I believe Render API must move to an OOP design.
  26. 26. 9.x Refactor RenderAPI to be OO 1843798 http://lb.cm/arrays-of-doom
  27. 27. What does might OO RenderAPI look like?
  28. 28. Influential design patterns Builder Decorator
  29. 29. Builder
  30. 30. Builder pattern Object creation is delegated to a series of steps, then finally invoked. This fulfills the data storage component of a Renderable.
  31. 31. <?php $car_builder = new CarBuilder(); $car_builder->setDoors(4); $car_builder->setColor('red'); $car_builder->setMake('ford'); $car = $car_builder->createCar();
  32. 32. Builder pattern Builder-esque Drupalisms hook_node_view() hook_page_alter()
  33. 33. Decorator
  34. 34. Decorator pattern Behavior added to object dynamically at runtime without affecting other objects of the same class. This fulfills runtime variable preparation.
  35. 35. <?php class Coffee() { function say() { return 'I am coffee'; } }
  36. 36. <?php class CoffeeDecorator() extends Coffee { function __construct($coffee) { $this->coffee = $coffee; } function say() { return $this->coffee->say(); } }
  37. 37. <?php class Coffee_Cream() extends CoffeeDecorator { function say() { return parent::say . ' with cream'; } } class Coffee_Sugar() extends CoffeeDecorator { function say() { return parent::say . ' with sugar'; } } $c = new Coffee_Cream(new Coffee_Sugar(new Coffee()));
  38. 38. Decorator pattern Decorator-esque Drupalisms comment_preprocess_node() mytheme_preprocess_node()
  39. 39. Getting markup 1. Get data. -- START RENDER PROCESS -- 2. Define renderable. 3. Alter renderable. 4. Render renderable. A. Call theme callbacks. i. Call preprocessors. ii. Invoke template. -- END RENDER PROCESS -- 5. Send markup to client.
  40. 40. Disclaimer: Let’s not get hung-up on implementation :)
  41. 41. Renderable definition <?php // D7/D8 return array( '#theme' => 'node', '#node' => $node, ); <?php // D9? return new RenderableBuilder('ThemeNode', array( 'node' => $node, ));
  42. 42. Altering <?php // D7/D8 function mymodule_node_view(&$node) { $node->content['image']['#theme'] = 'foo'; } <?php // D9? function mymodule_node_view_alter($builder) { $builder->get('image')->setBuildClass('ThemeFoo'); }
  43. 43. Variable prepare (1) <?php // D7/D8 function template_preprocess_foo(&$vars) { $new_title = $vars['title'] . ' overridden by foo'; $vars['title'] = $new_title; }
  44. 44. Variable prepare (2) <?php // D9 /** * @file Theme class for foo.tpl.php. */ class ThemeFoo extends Renderable { function prepare() { $new_title = $this->get('node')->get('title') . ' overridden by foo; $this->set('title', $new_title); } }
  45. 45. MOAR http://github.com/c4rl/renderapi
  46. 46. Discussion and planning :)
  47. 47. THANK YOU! WHAT DID YOU THINK? Locate this session at the DrupalCon Prague website: http://prague2013.drupal.org/node/1863 Click the “Take the survey” link

×