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.
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 so...
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 fo...
Page Caching
• Page caching is the act of caching entire
rendered HTML pages.
• Pages can be stored in the object cache av...
Fragment Caching
• All output involving a database read on the front
end should be fragment cached aside from the
main WP ...
Remote Calls
• Remote blocking calls can be a huge
performance bottleneck
• Cache remote calls as long as possible
• Utili...
Prime Cache
Asynchronously
• Don’t make the user wait for a cache to be
primed.
• Re-prime after invalidation
• Cleverly p...
admin-ajax.php
• Admin-ajax.php is for admin use only. It is not
cached as aggressively as the front end. Page
caching wil...
Off the Shelf Caching
Plugins
• Can be difficult to install and even more difficult
to remove.
• Created for the general p...
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
...
Understand WP Query
Parameters
• ‘posts_per_page’ => ‘…’: Sets the query limit to
something other than -1
• ‘post__not_in’...
Understand WP Query
Parameters
new WP_Query( array(
'no_found_rows' => true,
'fields' => 'ids',
'update_post_meta_cache' =...
Autoloading Options
• update_option() and add_option() take a 3rd
parameter $autoload.
• If you don’t need an option on ev...
Job Queues for Heavy
Lifting
• For intense database or remote call activity such
as a generating reports, expensive API ca...
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 ...
Elasticsearch/ElasticPre
ss
• ElasticPress is also a toolbox for vastly improving
the search experience.
• E.g. searching ...
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 ...
Modern PHP Design
Patterns
• WordPress core is backwards compatible with
PHP 5.2.4 (WP 5.2 will up minimum version to
5.6)...
Don’t Obsess Over
MVC PHP
• MVC (model, view, and controller) is a great
pattern in many situations.
• WordPress is inhere...
Feature Plugins
• Group distinct pieces of functionality into plugins
as much as possible.
• This separation simplifies de...
Documentation
• Properly documented code is more quickly fixed and
iterated upon
• Make documentation a part of your code ...
Wrapping Wrappers
• WordPress has a very rich, easy to use API with
ways to create posts, send HTTP requests,
create metab...
Write Tests
• Unit tests
• WP Mock - https://github.com/10up/wp_mock
• Acceptance Tests
• WP Acceptance -
https://github.c...
Linting
• Enforce linting rules. This keeps your code clean
and makes it more maintainable.
• PHPCS Rules - https://github...
Manage Dependencies with
Composer
• Manage plugins, themes, and WordPress with
composer when possible.
• This forces updat...
Manage Dependencies with
Composer
|- composer.json _________ # Define dependencies
|- wp-config.php _________ # WordPress ...
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_me...
Secure Output
• Escape data that is printed to the screen
• Escape data as late as possible
• Check out the esc_* function...
Nonces
• Ensure intent of important actions (database
modifications) by associating them with a nonce
• wp_create_nonce(),...
Nonces
<form>
<?php wp_nonce_field( 'prefix-form-action', 'nonc
...
</form>
if ( empty( $_POST['nonce_field'] ||
wp_verify...
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...
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 gu...
Review Code
Thousands of community themes
• More stringent review guidelines than plugins
• Review guidelines not geared f...
T E A M S
Workflows
• Keeping track of code history with version control
is critical. At 10up, we use GitLab.
• https://gitlab.com
•...
Internal Code Reviews
• Code reviews help ensure performance, security,
maintainability, and scalability
• Engineers impro...
Continuous Integration
• At 10up we use GitLab and a variety of tools for
continuous integration.
• When merge requests ar...
WP Snapshots
• WP Snapshots is a tool that empowers teams to
share codebases (database and files) quickly. It
makes on boa...
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
Upcoming SlideShare
Loading in …5
×

Best Practices for Building WordPress Applications

Learn about modern best practices for building enterprise-ready WordPress applications.

  • Be the first to comment

Best Practices for Building WordPress Applications

  1. 1. Best Practices for WordPress Applications
  2. 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. 3. 10up is hiring! @tlovett12 taylor.lovett@10up.com
  4. 4. https://10up.github.io/Engineering-Best-Practices/
  5. 5. C A C H I N G
  6. 6. 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/
  7. 7. 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/
  8. 8. 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
  9. 9. 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
  10. 10. 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
  11. 11. 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.
  12. 12. 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.
  13. 13. D A T A B A S E R E A D S A N D W R I T E S
  14. 14. Avoid Front End Writes • Database writes are slow • Avoid race conditions • Page caching makes them unreliable.
  15. 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. 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. 17. 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, ) );
  18. 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. 19. 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
  20. 20. S E A R C H A N D C O M P L E X Q U E R I E S
  21. 21. 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
  22. 22. 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
  23. 23. 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
  24. 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. 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. 26. 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.
  27. 27. 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
  28. 28. 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/
  29. 29. 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.
  30. 30. 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
  31. 31. 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
  32. 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. 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. 34. S E C U R I T Y
  35. 35. Clean Input • Validate/sanitize data being inserted into the database to strip anything harmful.
  36. 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. 37. 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
  38. 38. Nonces • Ensure intent of important actions (database modifications) by associating them with a nonce • wp_create_nonce(), wp_verify_nonce(), wp_nonce_field()
  39. 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. 40. Limit Login Attempts • Limit max number of login attempts to prevent password guessing.
  41. 41. 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.
  42. 42. T H I R D P A R T Y C O D E
  43. 43. Review Code Over 40,000 community plugins • Plugins reviewed before submission • Plugin revisions not reviewed • Review guidelines not geared for high traffic
  44. 44. Review Code Thousands of community themes • More stringent review guidelines than plugins • Review guidelines not geared for high traffic • Performance not measured
  45. 45. T E A M S
  46. 46. 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
  47. 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. 48. 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.)
  49. 49. 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
  50. 50. 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

×