SlideShare uma empresa Scribd logo
1 de 68
Baixar para ler offline
Supercharging 

WordPress Development
by Adam Tomat @adamtomat
Slack
Digital Product Studio
Projects
vs
Products
Projects
Cost of Introduction
- Only adding new code (e.g. controllers, models etc)
Cost of Change
- Making changes to existing code
Cost of Ownership
- Refactoring, writing tests etc
Products
Konstantin Kudryashov - Laracon EU 2015
– Liz Keogh
“You’re not really ‘done’ until the software has been
retired and is no longer used at all”
Make your website

easier to change.
I ❤ PHP
I ❤ WordPress
“Not Waving But Drowning” - Stevie Smith
Starts with drips
Cognitive Behavioural Therapy
• 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?
• 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?
What does this code look like?
$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
$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
odel
C
M
V iew
ontroller
https://www.rareloop.com/posts/comparing-modern-mvc-wordpress-frameworks/
WordPress MVC Frameworks
CONTENT SITE BESPOKE SYSTEM
Project Spectrum
Timber!
<?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
What are the problems with Timber
controllers?
<?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.
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);
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'
]);
}
}
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
Setting up a project

&

Deploys
Traditional WordPress
Theme
WordPressTimber
Yoast
ACF
// ** 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
Bedrock 🙌
Theme
Bedrock
Bedrock
WordPress v5.2.*
Timber
v1.9.*
Wordpress
SEO
v10.0.*
ACF
v5.8.2
How does Lumberjack fit
into this?
Lumberjack Starter Theme
Lumberjack + Bedrock = ❤
Bedrock
Lumberjack Core v4.3.*
WordPress v5.2.*
Timber
v1.9.*
Wordpress
SEO
v10.0.*
ACF
v5.8.2
Take Lumberjack for a spin
Supercharged Config
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'),
];
return [
'logs' => [
'enabled' => true,
'location' => '/tmp',
],
];
config/app.php
Some PHP file
$location = config(‘app.logs.location'); // => '/tmp'
Benefits
• Structured file system
• Dependencies managed (install with 1 command)
• Supercharged config
• Easier & safer deploys
Querying Data
$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();
use TimberPost;
$post = new Post(1);
$collection = Timber::get_posts($wpQueryArray);
Timber Post Object
use RareloopLumberjackPost;
use AppPostTypesProduct;
$post = new Post(1);
$collection = Post::query($wpQueryArray);
$product = new Product(1);
$collection = Product::query($wpQueryArray);
Lumberjack Post Object
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();
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';
}
Supercharged Queries
Advanced Queries
$productType = new ProductType;
$products = Product::builder()
->whereMeta('type', '"' . $productType->id . '"', 'LIKE')
->limit(10)
->orderBy('title', 'asc')
->get();
Using the Query Builder directly
$products = QueryBuilder::wherePostType([
Product::getPostType(),
GiftSet::getPostType(),
])
->limit(10)
->orderBy(‘title', 'asc')
->get();
Supercharged Custom Requests
Router::get('hello/world', function () {
return HtmlResponse('<h1>Hello World!</h1>');
});
Simple Routes
use RareloopLumberjackFacadesRouter;
use ZendDiactorosResponseHtmlResponse;
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
Router::get('hello/world', 'HelloController@show');
Controller Definitions
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);
• 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
• 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
- 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.”
• 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…
docs.lumberjack.rareloop.com
Documentation
rareloop.com/careers
Join Our Team
lumberjack.rareloop.com
Website
Get Involved
⭐
[Bristol WordPress] Supercharging WordPress Development

Mais conteúdo relacionado

Mais procurados

Laravel 8 export data as excel file with example
Laravel 8 export data as excel file with exampleLaravel 8 export data as excel file with example
Laravel 8 export data as excel file with exampleKaty Slemon
 
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...Ryan Weaver
 
You Don't Know Query - WordCamp Portland 2011
You Don't Know Query - WordCamp Portland 2011You Don't Know Query - WordCamp Portland 2011
You Don't Know Query - WordCamp Portland 2011andrewnacin
 
Caldera Learn - LoopConf WP API + Angular FTW Workshop
Caldera Learn - LoopConf WP API + Angular FTW WorkshopCaldera Learn - LoopConf WP API + Angular FTW Workshop
Caldera Learn - LoopConf WP API + Angular FTW WorkshopCalderaLearn
 
Introduction to AngularJS For WordPress Developers
Introduction to AngularJS For WordPress DevelopersIntroduction to AngularJS For WordPress Developers
Introduction to AngularJS For WordPress DevelopersCaldera Labs
 
Extending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh PollockExtending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh PollockCaldera Labs
 
Refresh Austin - Intro to Dexy
Refresh Austin - Intro to DexyRefresh Austin - Intro to Dexy
Refresh Austin - Intro to Dexyananelson
 
Contributing to WordPress Core - Peter Wilson
Contributing to WordPress Core - Peter WilsonContributing to WordPress Core - Peter Wilson
Contributing to WordPress Core - Peter WilsonWordCamp Sydney
 
Introduction to PowerShell
Introduction to PowerShellIntroduction to PowerShell
Introduction to PowerShellSalaudeen Rajack
 
Mojolicious - A new hope
Mojolicious - A new hopeMojolicious - A new hope
Mojolicious - A new hopeMarcus Ramberg
 
WordCamp Ann Arbor 2015 Introduction to Backbone + WP REST API
WordCamp Ann Arbor 2015 Introduction to Backbone + WP REST APIWordCamp Ann Arbor 2015 Introduction to Backbone + WP REST API
WordCamp Ann Arbor 2015 Introduction to Backbone + WP REST APIBrian Hogg
 
You Don't Know Query (WordCamp Netherlands 2012)
You Don't Know Query (WordCamp Netherlands 2012)You Don't Know Query (WordCamp Netherlands 2012)
You Don't Know Query (WordCamp Netherlands 2012)andrewnacin
 
Scalable web application architecture
Scalable web application architectureScalable web application architecture
Scalable web application architecturepostrational
 
Integrating React.js Into a PHP Application
Integrating React.js Into a PHP ApplicationIntegrating React.js Into a PHP Application
Integrating React.js Into a PHP ApplicationAndrew Rota
 
Beyond the WordPress 5 minute Install
Beyond the WordPress 5 minute InstallBeyond the WordPress 5 minute Install
Beyond the WordPress 5 minute InstallSteve Taylor
 
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and more
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and moreSymfony Guard Authentication: Fun with API Token, Social Login, JWT and more
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and moreRyan Weaver
 
Writing Software not Code with Cucumber
Writing Software not Code with CucumberWriting Software not Code with Cucumber
Writing Software not Code with CucumberBen Mabey
 

Mais procurados (20)

WordPress and Ajax
WordPress and AjaxWordPress and Ajax
WordPress and Ajax
 
Laravel 8 export data as excel file with example
Laravel 8 export data as excel file with exampleLaravel 8 export data as excel file with example
Laravel 8 export data as excel file with example
 
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
 
You Don't Know Query - WordCamp Portland 2011
You Don't Know Query - WordCamp Portland 2011You Don't Know Query - WordCamp Portland 2011
You Don't Know Query - WordCamp Portland 2011
 
Caldera Learn - LoopConf WP API + Angular FTW Workshop
Caldera Learn - LoopConf WP API + Angular FTW WorkshopCaldera Learn - LoopConf WP API + Angular FTW Workshop
Caldera Learn - LoopConf WP API + Angular FTW Workshop
 
Introduction to AngularJS For WordPress Developers
Introduction to AngularJS For WordPress DevelopersIntroduction to AngularJS For WordPress Developers
Introduction to AngularJS For WordPress Developers
 
Extending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh PollockExtending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh Pollock
 
Nodejs.meetup
Nodejs.meetupNodejs.meetup
Nodejs.meetup
 
Refresh Austin - Intro to Dexy
Refresh Austin - Intro to DexyRefresh Austin - Intro to Dexy
Refresh Austin - Intro to Dexy
 
Contributing to WordPress Core - Peter Wilson
Contributing to WordPress Core - Peter WilsonContributing to WordPress Core - Peter Wilson
Contributing to WordPress Core - Peter Wilson
 
Introduction to PowerShell
Introduction to PowerShellIntroduction to PowerShell
Introduction to PowerShell
 
Mojolicious - A new hope
Mojolicious - A new hopeMojolicious - A new hope
Mojolicious - A new hope
 
WordCamp Ann Arbor 2015 Introduction to Backbone + WP REST API
WordCamp Ann Arbor 2015 Introduction to Backbone + WP REST APIWordCamp Ann Arbor 2015 Introduction to Backbone + WP REST API
WordCamp Ann Arbor 2015 Introduction to Backbone + WP REST API
 
You Don't Know Query (WordCamp Netherlands 2012)
You Don't Know Query (WordCamp Netherlands 2012)You Don't Know Query (WordCamp Netherlands 2012)
You Don't Know Query (WordCamp Netherlands 2012)
 
Scalable web application architecture
Scalable web application architectureScalable web application architecture
Scalable web application architecture
 
Integrating React.js Into a PHP Application
Integrating React.js Into a PHP ApplicationIntegrating React.js Into a PHP Application
Integrating React.js Into a PHP Application
 
Beyond the WordPress 5 minute Install
Beyond the WordPress 5 minute InstallBeyond the WordPress 5 minute Install
Beyond the WordPress 5 minute Install
 
Writing Pluggable Software
Writing Pluggable SoftwareWriting Pluggable Software
Writing Pluggable Software
 
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and more
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and moreSymfony Guard Authentication: Fun with API Token, Social Login, JWT and more
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and more
 
Writing Software not Code with Cucumber
Writing Software not Code with CucumberWriting Software not Code with Cucumber
Writing Software not Code with Cucumber
 

Semelhante a [Bristol WordPress] Supercharging WordPress Development

Becoming a better WordPress Developer
Becoming a better WordPress DeveloperBecoming a better WordPress Developer
Becoming a better WordPress DeveloperJoey Kudish
 
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)Mike Schinkel
 
Childthemes ottawa-word camp-1919
Childthemes ottawa-word camp-1919Childthemes ottawa-word camp-1919
Childthemes ottawa-word camp-1919Paul Bearne
 
Cloud Automation with Opscode Chef
Cloud Automation with Opscode ChefCloud Automation with Opscode Chef
Cloud Automation with Opscode ChefSri Ram
 
Mojolicious, real-time web framework
Mojolicious, real-time web frameworkMojolicious, real-time web framework
Mojolicious, real-time web frameworktaggg
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)arcware
 
Introduction to Plugin Programming, WordCamp Miami 2011
Introduction to Plugin Programming, WordCamp Miami 2011Introduction to Plugin Programming, WordCamp Miami 2011
Introduction to Plugin Programming, WordCamp Miami 2011David Carr
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkBo-Yi Wu
 
PSD to WordPress
PSD to WordPressPSD to WordPress
PSD to WordPressNile Flores
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsMike Subelsky
 
Exploring Symfony's Code
Exploring Symfony's CodeExploring Symfony's Code
Exploring Symfony's CodeWildan Maulana
 
[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018Adam Tomat
 
Introduction To Code Igniter
Introduction To Code IgniterIntroduction To Code Igniter
Introduction To Code IgniterAmzad Hossain
 
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...King Foo
 
Node.js & Twitter Bootstrap Crash Course
Node.js & Twitter Bootstrap Crash CourseNode.js & Twitter Bootstrap Crash Course
Node.js & Twitter Bootstrap Crash CourseAaron Silverman
 
Drupal Best Practices
Drupal Best PracticesDrupal Best Practices
Drupal Best Practicesmanugoel2003
 

Semelhante a [Bristol WordPress] Supercharging WordPress Development (20)

Becoming a better WordPress Developer
Becoming a better WordPress DeveloperBecoming a better WordPress Developer
Becoming a better WordPress Developer
 
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
 
Codegnitorppt
CodegnitorpptCodegnitorppt
Codegnitorppt
 
Childthemes ottawa-word camp-1919
Childthemes ottawa-word camp-1919Childthemes ottawa-word camp-1919
Childthemes ottawa-word camp-1919
 
Cloud Automation with Opscode Chef
Cloud Automation with Opscode ChefCloud Automation with Opscode Chef
Cloud Automation with Opscode Chef
 
Mojolicious, real-time web framework
Mojolicious, real-time web frameworkMojolicious, real-time web framework
Mojolicious, real-time web framework
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
 
Introduction to Plugin Programming, WordCamp Miami 2011
Introduction to Plugin Programming, WordCamp Miami 2011Introduction to Plugin Programming, WordCamp Miami 2011
Introduction to Plugin Programming, WordCamp Miami 2011
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
 
PSD to WordPress
PSD to WordPressPSD to WordPress
PSD to WordPress
 
WCLA12 JavaScript
WCLA12 JavaScriptWCLA12 JavaScript
WCLA12 JavaScript
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web Apps
 
Exploring Symfony's Code
Exploring Symfony's CodeExploring Symfony's Code
Exploring Symfony's Code
 
[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018
 
Intro to Laravel 4
Intro to Laravel 4Intro to Laravel 4
Intro to Laravel 4
 
Fatc
FatcFatc
Fatc
 
Introduction To Code Igniter
Introduction To Code IgniterIntroduction To Code Igniter
Introduction To Code Igniter
 
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
 
Node.js & Twitter Bootstrap Crash Course
Node.js & Twitter Bootstrap Crash CourseNode.js & Twitter Bootstrap Crash Course
Node.js & Twitter Bootstrap Crash Course
 
Drupal Best Practices
Drupal Best PracticesDrupal Best Practices
Drupal Best Practices
 

Último

Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...SelfMade bd
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfproinshot.com
 
Pharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodologyPharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodologyAnusha Are
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...kalichargn70th171
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedSector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedDelhi Call girls
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park masabamasaba
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdfPearlKirahMaeRagusta1
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrainmasabamasaba
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 

Último (20)

Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
Pharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodologyPharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodology
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedSector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 

[Bristol WordPress] Supercharging WordPress Development

  • 1. Supercharging 
 WordPress Development by Adam Tomat @adamtomat Slack
  • 4. Projects Cost of Introduction - Only adding new code (e.g. controllers, models etc)
  • 5. Cost of Change - Making changes to existing code Cost of Ownership - Refactoring, writing tests etc Products
  • 6. Konstantin Kudryashov - Laracon EU 2015
  • 7. – Liz Keogh “You’re not really ‘done’ until the software has been retired and is no longer used at all”
  • 9. I ❤ PHP I ❤ WordPress
  • 10.
  • 11.
  • 12.
  • 13. “Not Waving But Drowning” - Stevie Smith
  • 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?
  • 18. What does this code look like?
  • 19. $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
  • 20. $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
  • 23.
  • 24. CONTENT SITE BESPOKE SYSTEM Project Spectrum
  • 25.
  • 27. <?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
  • 28. What are the problems with Timber controllers?
  • 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
  • 34. Setting up a project
 &
 Deploys
  • 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
  • 39. How does Lumberjack fit into this?
  • 40. Lumberjack Starter Theme Lumberjack + Bedrock = ❤ Bedrock Lumberjack Core v4.3.* WordPress v5.2.* Timber v1.9.* Wordpress SEO v10.0.* ACF v5.8.2
  • 41.
  • 44. 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'), ];
  • 45. return [ 'logs' => [ 'enabled' => true, 'location' => '/tmp', ], ]; config/app.php Some PHP file $location = config(‘app.logs.location'); // => '/tmp'
  • 46. Benefits • Structured file system • Dependencies managed (install with 1 command) • Supercharged config • Easier & safer deploys
  • 48. $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();
  • 49. use TimberPost; $post = new Post(1); $collection = Timber::get_posts($wpQueryArray); Timber Post Object
  • 50. use RareloopLumberjackPost; use AppPostTypesProduct; $post = new Post(1); $collection = Post::query($wpQueryArray); $product = new Product(1); $collection = Product::query($wpQueryArray); Lumberjack Post Object
  • 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'; }
  • 54. Advanced Queries $productType = new ProductType; $products = Product::builder() ->whereMeta('type', '"' . $productType->id . '"', 'LIKE') ->limit(10) ->orderBy('title', 'asc') ->get();
  • 55. Using the Query Builder directly $products = QueryBuilder::wherePostType([ Product::getPostType(), GiftSet::getPostType(), ]) ->limit(10) ->orderBy(‘title', 'asc') ->get();
  • 57. Router::get('hello/world', function () { return HtmlResponse('<h1>Hello World!</h1>'); }); Simple Routes use RareloopLumberjackFacadesRouter; use ZendDiactorosResponseHtmlResponse;
  • 58. 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
  • 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…
  • 65.