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.
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)
• Difficult to change
• 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
36. // ** 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
51. 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();
52. 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';
}
57. Router::get('hello/world', function () {
return HtmlResponse('<h1>Hello World!</h1>');
});
Simple Routes
use RareloopLumberjackFacadesRouter;
use ZendDiactorosResponseHtmlResponse;
60. 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);
61. • 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
62. • 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
63. - 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.”
64. • 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…