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.

[Bristol WordPress] Supercharging WordPress Development

182 views

Published on

Slide links:
- https://lumberjack.rareloop.com
- https://docs.lumberjack.rareloop.com
- https://github.com/Rareloop/lumberjack-bedrock-installer
- https://github.com/Rareloop/lumberjack
- https://github.com/Rareloop/lumberjack-validation
- https://github.com/Rareloop/hatchet

- https://lizkeogh.com/2017/08/31/reflecting-reality/amp
- https://www.upstatement.com/timber
- https://roots.io/bedrock
- https://scotch.io/bar-talk/s-o-l-i-d-the-first-five-principles-of-object-oriented-design
- https://github.com/zendframework/zend-diactoros
- https://www.php-fig.org
- http://php-di.org

---

Often WordPress themes are not easy to change, maintain or fun to work on. This can rule WordPress out as a viable option for bespoke, non-trivial websites.

In this talk we’ll dive into how this happens & look at how we can benefit from software engineering techniques to help make your code easier to change. I’ll also show how using Lumberjack, a powerful MVC framework built on Timber, can be used to power-up your themes.

Published in: Software
  • Be the first to comment

  • Be the first to like this

[Bristol WordPress] Supercharging WordPress Development

  1. 1. Supercharging 
 WordPress Development by Adam Tomat @adamtomat Slack
  2. 2. Digital Product Studio
  3. 3. Projects vs Products
  4. 4. Projects Cost of Introduction - Only adding new code (e.g. controllers, models etc)
  5. 5. Cost of Change - Making changes to existing code Cost of Ownership - Refactoring, writing tests etc Products
  6. 6. Konstantin Kudryashov - Laracon EU 2015
  7. 7. – Liz Keogh “You’re not really ‘done’ until the software has been retired and is no longer used at all”
  8. 8. Make your website
 easier to change.
  9. 9. I ❤ PHP I ❤ WordPress
  10. 10. “Not Waving But Drowning” - Stevie Smith
  11. 11. Starts with drips
  12. 12. Cognitive Behavioural Therapy
  13. 13. • Traffic on the way to work • Worrying about your body image • Not getting enough sleep • Financial difficulties • Worries about keeping a job • Being isolated Life: What can fill up your bathtub?
  14. 14. • Slow getting setup on project • Applying the same change/code across multiple files • Unstructured and undocumented setup • Introducing bugs or regressions • Painful deployments • Different conventions/style within the code (inconsistent) • Difficult to change • Unable to change the current situation WordPress: What fills your bathtub?
  15. 15. What does this code look like?
  16. 16. $the_query = new WP_Query([ 'posts_per_page' => 5, 'tag' => 'club' ]); if ($the_query->have_posts()) : ?> <h4>Recent Articles</h4> <ul> <?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?> <li class="article"> <h3><?php the_title(); ?></h3> <?php the_excerpt(10); ?> <a href="<?php the_permalink(); ?>">Read more</a> </li> <?php endwhile; ?> </ul> <?php endif; ?> t Mix of concerns: Presentation logic & Database queries " This file has multiple reasons to change index.php
  17. 17. $the_query = new WP_Query([ 'posts_per_page' => 5, 'tag' => 'club' ]); if ($the_query->have_posts()) : ?> <h4>Recent Articles</h4> <ul> <?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?> <li class="article"> <h3><?php the_title(); ?></h3> <?php the_excerpt(10); ?> <a href="<?php the_permalink(); ?>">Read more</a> </li> <?php endwhile; ?> </ul> <?php endif; ?> t Procedural " Procedural code is often not DRY or reusable.
 
 It’s difficult to change. Hard to read. index.php
  18. 18. odel C M V iew ontroller
  19. 19. https://www.rareloop.com/posts/comparing-modern-mvc-wordpress-frameworks/ WordPress MVC Frameworks
  20. 20. CONTENT SITE BESPOKE SYSTEM Project Spectrum
  21. 21. Timber!
  22. 22. <?php $context = Timber::get_context(); $context['posts'] = Timber::get_posts([ 'posts_per_page' => 5, 'tag' => 'club' ]); Timber::render('index.twig', $context); {% if posts is not empty %} <h4>Recent Articles</h4> <ul> {% for post in posts %} <li class="article"> <h3>{{ $post->title }}</h3> {{ $post->preview }} <a href="{{ $post->link }}">Read the full story</a> </li> {% endfor %} </ul> {% endif %} index.twig index.php
  23. 23. What are the problems with Timber controllers?
  24. 24. <?php $context = Timber::get_context(); $context['posts'] = Timber::get_posts([ 'posts_per_page' => 5, 'tag' => 'club' ]); Timber::render('index.twig', $context); index.php t Procedural " Procedural code is often not DRY or reusable.
 
 It’s difficult to change. Hard to read.
  25. 25. index.php class IndexController { } public function handle() { $context = Timber::get_context(); $context['posts'] = Timber::get_posts([ 'posts_per_page' => 5, 'tag' => 'club' ]); } extends BaseController return view('index.twig', $context);
  26. 26. index.php class IndexController extends BaseController { public function handle() { $context = Timber::get_context(); $context['posts'] = $this->getPosts(); return view('index.twig', $context); } private function getPosts() { return Timber::get_posts([ 'posts_per_page' => 5, 'tag' => 'club' ]); } }
  27. 27. Benefits • Write Object Orientated code rather than Procedural code • Separation of concerns • Easier to write DRY code • Can use inheritance to extend a base class for common functionality • Can encapsulate more complex routines in private functions
  28. 28. Setting up a project
 &
 Deploys
  29. 29. Traditional WordPress Theme WordPressTimber Yoast ACF
  30. 30. // ** MySQL settings - You can get this info from your web host ** // /** The name of the database for WordPress */ define('DB_NAME', 'wordpress'); /** MySQL database username */ define('DB_USER', 'root'); /** MySQL database password */ define('DB_PASSWORD', ‘letmein'); /** MySQL hostname */ define('DB_HOST', 'localhost'); /** Database Charset to use in creating database tables. */ define('DB_CHARSET', 'utf8'); /** The Database Collate type. Don't change this if in doubt. */ define('DB_COLLATE', ''); wp-config.php
  31. 31. Bedrock 🙌
  32. 32. Theme Bedrock Bedrock WordPress v5.2.* Timber v1.9.* Wordpress SEO v10.0.* ACF v5.8.2
  33. 33. How does Lumberjack fit into this?
  34. 34. Lumberjack Starter Theme Lumberjack + Bedrock = ❤ Bedrock Lumberjack Core v4.3.* WordPress v5.2.* Timber v1.9.* Wordpress SEO v10.0.* ACF v5.8.2
  35. 35. Take Lumberjack for a spin
  36. 36. Supercharged Config
  37. 37. Some PHP file $apiKey = config('app.google_maps_api_key'); config/app.php return [ 'google_maps_api_key' => getenv('GOOGLE_MAPS_API_KEY', 'dummy-api-key'), ];
  38. 38. return [ 'logs' => [ 'enabled' => true, 'location' => '/tmp', ], ]; config/app.php Some PHP file $location = config(‘app.logs.location'); // => '/tmp'
  39. 39. Benefits • Structured file system • Dependencies managed (install with 1 command) • Supercharged config • Easier & safer deploys
  40. 40. Querying Data
  41. 41. $args = [ 'post_type' => 'product', 'posts_per_page' => 10, 'orderby' => 'title', 'order' => 'ASC', 'meta_query' => [ 'relation' => 'AND', [ 'key' => 'available_from_date', 'value' => [$from_date, $to_date], 'compare' => 'BETWEEN', 'type' => 'DATE', ], [ 'key' => 'available_to_date', 'value' => [$from_date, $to_date], 'compare' => 'BETWEEN', 'type' => 'DATE', ], ] ]; $query = new WP_Query($args); $posts = $query->get_posts();
  42. 42. use TimberPost; $post = new Post(1); $collection = Timber::get_posts($wpQueryArray); Timber Post Object
  43. 43. use RareloopLumberjackPost; use AppPostTypesProduct; $post = new Post(1); $collection = Post::query($wpQueryArray); $product = new Product(1); $collection = Product::query($wpQueryArray); Lumberjack Post Object
  44. 44. class Product extends Post { public function getPhotos() : array { // Do database query to get the assigned photos } } Encapsulate Business Logic $product = new Product(123); $photos = $product->getPhotos();
  45. 45. class Product extends Post { } Register Custom Post Types // config/posttypes.php return [ 'register' => [ AppPostTypesProduct::class, ], ]; protected static function getPostTypeConfig() { return [ 'labels' => [ 'name' => __('Products'), 'singular_name' => __('Product'), ], 'public' => true, 'has_archive' => false, ]; } public static function getPostType() { return 'product'; }
  46. 46. Supercharged Queries
  47. 47. Advanced Queries $productType = new ProductType; $products = Product::builder() ->whereMeta('type', '"' . $productType->id . '"', 'LIKE') ->limit(10) ->orderBy('title', 'asc') ->get();
  48. 48. Using the Query Builder directly $products = QueryBuilder::wherePostType([ Product::getPostType(), GiftSet::getPostType(), ]) ->limit(10) ->orderBy(‘title', 'asc') ->get();
  49. 49. Supercharged Custom Requests
  50. 50. Router::get('hello/world', function () { return HtmlResponse('<h1>Hello World!</h1>'); }); Simple Routes use RareloopLumberjackFacadesRouter; use ZendDiactorosResponseHtmlResponse;
  51. 51. Router::get('hello/{name}', function ($name) { return HtmlResponse('<h1>Hello ' . $name . '!</h1>'); }); echo Router::url('hello.world', ['name' => 'adam']); ->name('hello.world'); Params & Named Routes
  52. 52. Router::get('hello/world', 'HelloController@show'); Controller Definitions
  53. 53. AJAX endpoint that returns JSON class ArticleCommentController { } Router::post('articles/{id}/comments', 'ArticleCommentController@store'); public function store(int $id) { } $comment = request()->input('comment'); wp_new_comment([ 'comment_post_ID' => $id, 'comment_author' => get_current_user_id(), 'comment_content' => $comment, ]); return new JsonResponse([ 'data' => [ 'content' => $comment, ] ], 201);
  54. 54. • Extend WordPress site with custom URL endpoints (e.g. for ajax, forms) • Access to all REST based verbs • Can add Groups, for collecting similar resources together • Named routes • You have a convention & documentation Router benefits
  55. 55. • PSR11 Dependency Injection Container (using PHP-DI) • Facades • Exception Handling (PSR3) • Validation (currently an external package) • View Models More power at your fingertips ✨ • Service Providers • Hatchet (CLI) • Global helper functions (e.g. config(‘app.environment’); ) • ‘Responsable’ objects (from Laravel) - in, but currently undocumented
  56. 56. - Jared Novack - Timber creator “Lumberjack is the deluxe version of what Modern WordPress should look like today.
 
 The team has done a great job of making it easy to build complicated custom applications while taking advantage of the best parts of WordPress.”
  57. 57. • Evaluate the product mindset for you (and your team?) • WordPress is awesome, we can make it even more awesome! • Challenge and push your stack forward. Don’t accept dripping taps • Write code which is easier to change, where applicable • Give MVC WordPress a go • Use only what you need to in Lumberjack In summary…
  58. 58. docs.lumberjack.rareloop.com Documentation rareloop.com/careers Join Our Team lumberjack.rareloop.com Website
  59. 59. Get Involved ⭐

×