KEMBAR78
Best Practices for Building WordPress Applications | PPTX
Best Practices for
WordPress
Applications
Who Am I?
• My name is Taylor Lovett
• VP of Engineering at 10up
• WordPress plugin creator and core contributor
• Open source community member
@tlovett12
10up is hiring!
@tlovett12
taylor.lovett@10up.com
https://10up.github.io/Engineering-Best-Practices/
C A C H I N G
Redis as a Persistent
Object Cache
• WP lets you drop in a custom object cache.
• Redis lets you store things in memory for fast
read/writes
• Redis offers built in failover features that make it
easier to scale than Memcached
https://wordpress.org/plugins/wp-redis/
Page Caching
• Page caching is the act of caching entire
rendered HTML pages.
• Pages can be stored in the object cache avoiding
database queries entirely.
https://wordpress.org/plugins/batcache/
Fragment Caching
• All output involving a database read on the front
end should be fragment cached aside from the
main WP query.
• For example, generated HTML from a feature
post carousel should be cached since it uses a
WP_Query
Remote Calls
• Remote blocking calls can be a huge
performance bottleneck
• Cache remote calls as long as possible
• Utilize non-blocking remote requests wherever
possible
Prime Cache
Asynchronously
• Don’t make the user wait for a cache to be
primed.
• Re-prime after invalidation
• Cleverly prime cached data asynchronously
(async transients, cron, non-blocking AJAX, job
queue, etc.)
https://github.com/10up/Async-Transients
admin-ajax.php
• Admin-ajax.php is for admin use only. It is not
cached as aggressively as the front end. Page
caching will not work.
Off the Shelf Caching
Plugins
• Can be difficult to install and even more difficult
to remove.
• Created for the general public and often bloated
with features.
• Keep it simple.
D A T A B A S E R E A D S
A N D W R I T E S
Avoid Front End Writes
• Database writes are slow
• Avoid race conditions
• Page caching makes them unreliable.
Understand WP_Query
Parameters
• 'no_found_rows' => true: Tells WordPress not to
pass SQL_CALC_FOUND_ROWS to the database
query.
• 'update_post_meta_cache' => false: useful when
post meta will not be utilized.
• 'update_post_term_cache' => false: useful when
taxonomy terms will not be utilized.
• 'fields' => 'ids': useful when only the post IDs are
needed. Avoids lots of extra preparation.
Understand WP Query
Parameters
• ‘posts_per_page’ => ‘…’: Sets the query limit to
something other than -1
• ‘post__not_in’: Tells MySQL to run a NOT IN
query which is inherently slow. Try to avoid.
Understand WP Query
Parameters
new WP_Query( array(
'no_found_rows' => true,
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'posts_per_page' => 100,
) );
Autoloading Options
• update_option() and add_option() take a 3rd
parameter $autoload.
• If you don’t need an option on every request,
specify false for $autoload.
Job Queues for Heavy
Lifting
• For intense database or remote call activity such
as a generating reports, expensive API calls,
ingesting content, etc, use a job queue.
• WP Minions - https://github.com/10up/wp-
minions
S E A R C H A N D
C O M P L E X Q U E R I E S
Elasticsearch/ElasticPre
ss
• ElasticPress empowers you to execute complex
queries fast.
• E.g. multidimensional taxonomy queries,
multidimensional meta queries, etc.
• On large databases, these types of queries are
not feasible in MySQL.
https://github.com/10up/ElasticPress
Elasticsearch/ElasticPre
ss
• ElasticPress is also a toolbox for vastly improving
the search experience.
• E.g. searching associated terms/meta, author
search, autosuggest, geolocation, custom
weightings, etc.
https://github.com/10up/ElasticPress
M A I N T A I N A B I L I T Y
A N D S T A B I L I T Y
Maintainable Code Improves
Stability
• Easily maintainable and extendible code bases
are less susceptible to bugs.
• Bugs in maintainable code are solved quicker
• New features are more easily created in
maintainable code.
• Happy engineers are more productive (often
overlooked).
Modern PHP Design
Patterns
• WordPress core is backwards compatible with
PHP 5.2.4 (WP 5.2 will up minimum version to
5.6)
• Your project does not need to be constrained by
incredibly outdated software
• Traits, composer, namespaces, etc.
Don’t Obsess Over
MVC PHP
• MVC (model, view, and controller) is a great
pattern in many situations.
• WordPress is inherently not object oriented. We
find that forcing MVC with tools like Twig
ultimately leads to more confusing code that is
harder to maintain.
Feature Plugins
• Group distinct pieces of functionality into plugins
as much as possible.
• This separation simplifies deployments and
enables you to reuse functionality on other
projects.
• Opt-in to functionality through usage of hooks
Documentation
• Properly documented code is more quickly fixed and
iterated upon
• Make documentation a part of your code review process
• PHP Documentation Standards:
https://make.wordpress.org/core/handbook/best-
practices/inline-documentation-standards/php/
• JS Documentation Standards:
https://make.wordpress.org/core/handbook/best-
practices/inline-documentation-standards/javascript/
Wrapping Wrappers
• WordPress has a very rich, easy to use API with
ways to create posts, send HTTP requests,
create metaboxes, etc.
• Creating wrappers around these core APIs more
often than not just results in a layer of confusing
code and another library to memorize.
Write Tests
• Unit tests
• WP Mock - https://github.com/10up/wp_mock
• Acceptance Tests
• WP Acceptance -
https://github.com/10up/wpacceptance
• Tests improve quality and stability through
identification of issues. Decrease regression
Linting
• Enforce linting rules. This keeps your code clean
and makes it more maintainable.
• PHPCS Rules - https://github.com/10up/phpcs-
composer
• ESLint Config - https://github.com/10up/eslint-
config
Manage Dependencies with
Composer
• Manage plugins, themes, and WordPress with
composer when possible.
• This forces updates to be more deliberate and
ensures everyone is running the same versions of
dependencies.
• Disable plugin install/updates in the WP dashboard.
• See https://10up.github.io/Engineering-Best-
Practices/structure/#dependencies
Manage Dependencies with
Composer
|- composer.json _________ # Define dependencies
|- wp-config.php _________ # WordPress configuration
|- wp/ ___________________ # Composer install WordPress here
|- wp-content/ ___________ # Composer dependencies
| |- themes/ ____________ # Themes directory
| |- plugins/ ___________ # Plugins directory
S E C U R I T Y
Clean Input
• Validate/sanitize data being inserted into the
database to strip anything harmful.
Clean Input
if ( ! empty( $_POST['option'] ) ) {
update_post_meta( $post_id, 'option_key', true );
} else {
delete_post_meta( $post_id, 'option_key' );
}
update_post_meta( $post_id, 'key_name', sanitize_text
Secure Output
• Escape data that is printed to the screen
• Escape data as late as possible
• Check out the esc_* functions in the codex.
https://codex.wordpress.org/Validating_Sanitizing_and_Escaping_User_Data
Nonces
• Ensure intent of important actions (database
modifications) by associating them with a nonce
• wp_create_nonce(), wp_verify_nonce(),
wp_nonce_field()
Nonces
<form>
<?php wp_nonce_field( 'prefix-form-action', 'nonc
...
</form>
if ( empty( $_POST['nonce_field'] ||
wp_verify_nonce( $_POST['nonce_field'], 'prefix-
form-action' ) {
return false;
}
Limit Login Attempts
• Limit max number of login attempts to prevent
password guessing.
Require Strong
Passwords
• Weak passwords are one of the most common
ways attackers exploit websites.
• Require your users create strong passwords.
There are a few great plugins that do this
automatically.
T H I R D P A R T Y
C O D E
Review Code
Over 40,000 community plugins
• Plugins reviewed before submission
• Plugin revisions not reviewed
• Review guidelines not geared for high
traffic
Review Code
Thousands of community themes
• More stringent review guidelines than plugins
• Review guidelines not geared for high traffic
• Performance not measured
T E A M S
Workflows
• Keeping track of code history with version control
is critical. At 10up, we use GitLab.
• https://gitlab.com
• Mandate workflow at the start of project to keep
everyone on the same page.
• 10up’s workflow in detail:
https://10up.github.io/Engineering-Best-
Practices/version-control/#workflows
Internal Code Reviews
• Code reviews help ensure performance, security,
maintainability, and scalability
• Engineers improve skills by reviewing and
receiving reviews.
• All code should be reviewed by someone who
didn’t write it.
Continuous Integration
• At 10up we use GitLab and a variety of tools for
continuous integration.
• When merge requests are opened against
master, those changes are tested automatically
(unit tests, acceptance tests, syntax error checks,
vulnerability database comparison, virus scan,
etc.)
WP Snapshots
• WP Snapshots is a tool that empowers teams to
share codebases (database and files) quickly. It
makes on boarding new engineers much faster.
• https://github.com/10up/wpsnapshots
Q U E S T I O N S ?
@ T L O V E T T 1 2
T A Y L O R . L O V E T T @ 1 0 U P . C O
M

Best Practices for Building WordPress Applications

  • 1.
  • 2.
    Who Am I? •My name is Taylor Lovett • VP of Engineering at 10up • WordPress plugin creator and core contributor • Open source community member @tlovett12
  • 3.
  • 4.
  • 5.
    C A CH I N G
  • 6.
    Redis as aPersistent Object Cache • WP lets you drop in a custom object cache. • Redis lets you store things in memory for fast read/writes • Redis offers built in failover features that make it easier to scale than Memcached https://wordpress.org/plugins/wp-redis/
  • 7.
    Page Caching • Pagecaching is the act of caching entire rendered HTML pages. • Pages can be stored in the object cache avoiding database queries entirely. https://wordpress.org/plugins/batcache/
  • 8.
    Fragment Caching • Alloutput involving a database read on the front end should be fragment cached aside from the main WP query. • For example, generated HTML from a feature post carousel should be cached since it uses a WP_Query
  • 9.
    Remote Calls • Remoteblocking calls can be a huge performance bottleneck • Cache remote calls as long as possible • Utilize non-blocking remote requests wherever possible
  • 10.
    Prime Cache Asynchronously • Don’tmake the user wait for a cache to be primed. • Re-prime after invalidation • Cleverly prime cached data asynchronously (async transients, cron, non-blocking AJAX, job queue, etc.) https://github.com/10up/Async-Transients
  • 11.
    admin-ajax.php • Admin-ajax.php isfor admin use only. It is not cached as aggressively as the front end. Page caching will not work.
  • 12.
    Off the ShelfCaching Plugins • Can be difficult to install and even more difficult to remove. • Created for the general public and often bloated with features. • Keep it simple.
  • 13.
    D A TA B A S E R E A D S A N D W R I T E S
  • 14.
    Avoid Front EndWrites • Database writes are slow • Avoid race conditions • Page caching makes them unreliable.
  • 15.
    Understand WP_Query Parameters • 'no_found_rows'=> true: Tells WordPress not to pass SQL_CALC_FOUND_ROWS to the database query. • 'update_post_meta_cache' => false: useful when post meta will not be utilized. • 'update_post_term_cache' => false: useful when taxonomy terms will not be utilized. • 'fields' => 'ids': useful when only the post IDs are needed. Avoids lots of extra preparation.
  • 16.
    Understand WP Query Parameters •‘posts_per_page’ => ‘…’: Sets the query limit to something other than -1 • ‘post__not_in’: Tells MySQL to run a NOT IN query which is inherently slow. Try to avoid.
  • 17.
    Understand WP Query Parameters newWP_Query( array( 'no_found_rows' => true, 'fields' => 'ids', 'update_post_meta_cache' => false, 'update_post_term_cache' => false, 'posts_per_page' => 100, ) );
  • 18.
    Autoloading Options • update_option()and add_option() take a 3rd parameter $autoload. • If you don’t need an option on every request, specify false for $autoload.
  • 19.
    Job Queues forHeavy Lifting • For intense database or remote call activity such as a generating reports, expensive API calls, ingesting content, etc, use a job queue. • WP Minions - https://github.com/10up/wp- minions
  • 20.
    S E AR C H A N D C O M P L E X Q U E R I E S
  • 21.
    Elasticsearch/ElasticPre ss • ElasticPress empowersyou to execute complex queries fast. • E.g. multidimensional taxonomy queries, multidimensional meta queries, etc. • On large databases, these types of queries are not feasible in MySQL. https://github.com/10up/ElasticPress
  • 22.
    Elasticsearch/ElasticPre ss • ElasticPress isalso a toolbox for vastly improving the search experience. • E.g. searching associated terms/meta, author search, autosuggest, geolocation, custom weightings, etc. https://github.com/10up/ElasticPress
  • 23.
    M A IN T A I N A B I L I T Y A N D S T A B I L I T Y
  • 24.
    Maintainable Code Improves Stability •Easily maintainable and extendible code bases are less susceptible to bugs. • Bugs in maintainable code are solved quicker • New features are more easily created in maintainable code. • Happy engineers are more productive (often overlooked).
  • 25.
    Modern PHP Design Patterns •WordPress core is backwards compatible with PHP 5.2.4 (WP 5.2 will up minimum version to 5.6) • Your project does not need to be constrained by incredibly outdated software • Traits, composer, namespaces, etc.
  • 26.
    Don’t Obsess Over MVCPHP • MVC (model, view, and controller) is a great pattern in many situations. • WordPress is inherently not object oriented. We find that forcing MVC with tools like Twig ultimately leads to more confusing code that is harder to maintain.
  • 27.
    Feature Plugins • Groupdistinct pieces of functionality into plugins as much as possible. • This separation simplifies deployments and enables you to reuse functionality on other projects. • Opt-in to functionality through usage of hooks
  • 28.
    Documentation • Properly documentedcode is more quickly fixed and iterated upon • Make documentation a part of your code review process • PHP Documentation Standards: https://make.wordpress.org/core/handbook/best- practices/inline-documentation-standards/php/ • JS Documentation Standards: https://make.wordpress.org/core/handbook/best- practices/inline-documentation-standards/javascript/
  • 29.
    Wrapping Wrappers • WordPresshas a very rich, easy to use API with ways to create posts, send HTTP requests, create metaboxes, etc. • Creating wrappers around these core APIs more often than not just results in a layer of confusing code and another library to memorize.
  • 30.
    Write Tests • Unittests • WP Mock - https://github.com/10up/wp_mock • Acceptance Tests • WP Acceptance - https://github.com/10up/wpacceptance • Tests improve quality and stability through identification of issues. Decrease regression
  • 31.
    Linting • Enforce lintingrules. This keeps your code clean and makes it more maintainable. • PHPCS Rules - https://github.com/10up/phpcs- composer • ESLint Config - https://github.com/10up/eslint- config
  • 32.
    Manage Dependencies with Composer •Manage plugins, themes, and WordPress with composer when possible. • This forces updates to be more deliberate and ensures everyone is running the same versions of dependencies. • Disable plugin install/updates in the WP dashboard. • See https://10up.github.io/Engineering-Best- Practices/structure/#dependencies
  • 33.
    Manage Dependencies with Composer |-composer.json _________ # Define dependencies |- wp-config.php _________ # WordPress configuration |- wp/ ___________________ # Composer install WordPress here |- wp-content/ ___________ # Composer dependencies | |- themes/ ____________ # Themes directory | |- plugins/ ___________ # Plugins directory
  • 34.
    S E CU R I T Y
  • 35.
    Clean Input • Validate/sanitizedata being inserted into the database to strip anything harmful.
  • 36.
    Clean Input if (! empty( $_POST['option'] ) ) { update_post_meta( $post_id, 'option_key', true ); } else { delete_post_meta( $post_id, 'option_key' ); } update_post_meta( $post_id, 'key_name', sanitize_text
  • 37.
    Secure Output • Escapedata that is printed to the screen • Escape data as late as possible • Check out the esc_* functions in the codex. https://codex.wordpress.org/Validating_Sanitizing_and_Escaping_User_Data
  • 38.
    Nonces • Ensure intentof important actions (database modifications) by associating them with a nonce • wp_create_nonce(), wp_verify_nonce(), wp_nonce_field()
  • 39.
    Nonces <form> <?php wp_nonce_field( 'prefix-form-action','nonc ... </form> if ( empty( $_POST['nonce_field'] || wp_verify_nonce( $_POST['nonce_field'], 'prefix- form-action' ) { return false; }
  • 40.
    Limit Login Attempts •Limit max number of login attempts to prevent password guessing.
  • 41.
    Require Strong Passwords • Weakpasswords are one of the most common ways attackers exploit websites. • Require your users create strong passwords. There are a few great plugins that do this automatically.
  • 42.
    T H IR D P A R T Y C O D E
  • 43.
    Review Code Over 40,000community plugins • Plugins reviewed before submission • Plugin revisions not reviewed • Review guidelines not geared for high traffic
  • 44.
    Review Code Thousands ofcommunity themes • More stringent review guidelines than plugins • Review guidelines not geared for high traffic • Performance not measured
  • 45.
    T E AM S
  • 46.
    Workflows • Keeping trackof code history with version control is critical. At 10up, we use GitLab. • https://gitlab.com • Mandate workflow at the start of project to keep everyone on the same page. • 10up’s workflow in detail: https://10up.github.io/Engineering-Best- Practices/version-control/#workflows
  • 47.
    Internal Code Reviews •Code reviews help ensure performance, security, maintainability, and scalability • Engineers improve skills by reviewing and receiving reviews. • All code should be reviewed by someone who didn’t write it.
  • 48.
    Continuous Integration • At10up we use GitLab and a variety of tools for continuous integration. • When merge requests are opened against master, those changes are tested automatically (unit tests, acceptance tests, syntax error checks, vulnerability database comparison, virus scan, etc.)
  • 49.
    WP Snapshots • WPSnapshots is a tool that empowers teams to share codebases (database and files) quickly. It makes on boarding new engineers much faster. • https://github.com/10up/wpsnapshots
  • 50.
    Q U ES T I O N S ? @ T L O V E T T 1 2 T A Y L O R . L O V E T T @ 1 0 U P . C O M