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
- rareloop.com/careers
- https://www.rareloop.com/posts/comparing-modern-mvc-wordpress-frameworks/
- https://lizkeogh.com/2017/08/31/reflecting-reality/amp
- https://www.youtube.com/watch?v=uQUxJObxTUs
- https://www.upstatement.com/timber
- https://roots.io/bedrock
---
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.
5. Cost of Change
- Making changes to existing code
Cost of Ownership
- Refactoring, writing tests etc
Products
Cost of Introduction
- Only adding new code (e.g. controllers, models etc)
16. • 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?
17. • 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)
• Unable to change the current situation
WordPress: What fills your bathtub?
29. <?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.
30.
31. 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);
32. 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'
]);
}
}
33. 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
47. 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();
48. 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';
}
53. Router::get('hello/world', function () {
return HtmlResponse('<h1>Hello World!</h1>');
});
Simple Routes
use RareloopLumberjackFacadesRouter;
use ZendDiactorosResponseHtmlResponse;
56. 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);
57. • 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
58. • Config
• 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
• Sessions
59. • 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)
• Unable to change the current situation
WordPress: What fills your bathtub?
60. • 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…