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.

Plugin Development @ WordCamp Norway 2014

2,776 views

Published on

The Plugin Development presentation I gave at WordCamp Norway 2014

Published in: Technology
  • Be the first to comment

Plugin Development @ WordCamp Norway 2014

  1. 1. Plugin Development WordCamp Norway 2014
  2. 2. Barry Kooij • Senior Web Developer @ Yoast • WordPress SEO (Premium),What The File, Sub Posts • Contributor EDD, EDD extensions • Moderator WPNL forum • Twitter: @cageNL
  3. 3. Agenda • Presentation • Q&A • Personal Q&A
  4. 4. Let’s get coding!
  5. 5. Hold up!
  6. 6. There more to a good plugin than good code!
  7. 7. Wait, what?
  8. 8. My Setup
  9. 9. My Setup • MacBook Pro Retina • PhpStorm • GIT -> GitHub • Vagrant w/ Varying Vagrant Vagrants (VVV) -10up
  10. 10. Debugging
  11. 11. Debugging define( 'WP_DEBUG', true );
 if ( WP_DEBUG ) {
 define( 'SCRIPT_DEBUG', true );
 define( 'WP_DEBUG_LOG', true );
 define( 'WP_DEBUG_DISPLAY', true );
 @ini_set( 'display_errors', 1 );
 } display_errors = On;
 error_reporting = E_ALL | E_STRICT; Xdebug
  12. 12. WordPress Core
  13. 13. Open source • WordPress is open source • No really, literally OPEN SOURCE • The code and documentation is all in your project • Try command clicking a function
  14. 14. API • Dashboard Widgets API • Rewrite API • Database API • Settings API • HTTP API • Shortcode API • File Header API • Theme Modification API • Filesystem API • Theme Customization API • Metadata API • Transients API • Options API • Widgets API • Plugin API • XML-RPC WordPress API • Quicktags API • Image Manipulation API
  15. 15. Hooks & Filters • add_action( ‘hook_name’, ‘my_hook_callback’ ); • do_action( ‘hook_name’ ); ! • add_filter( ‘filter_name’, ‘my_filter_callback’ ); • $new_value = apply_filters( ‘filter_name’, $old_value );
  16. 16. JavaScript Hooks • JavaScript events • $('body').bind(’event’, function(event, the_value) { }); • $('body').trigger(’event', [ value ]);
  17. 17. Backwards Compatibility
  18. 18. Backwards Compatibility • Don’t remove code, deprecate it • Don’t change unit tests but add new unit tests to test your update
  19. 19. Code Standards
  20. 20. Naming Conventions • function some_name( $some_variable ) { [...] } • class Walker_Category extends Walker { [...] } • class WP_HTTP { [...] } • my-plugin-name.php • class-my-class.php
  21. 21. Databases • Always use the WP API! • $wpdb->prepare( "SELECT * FROM {$wpdb->posts} WHERE `ID` = %d", $id );
  22. 22. PHP standards • if ( contidion ) • my_function( $parameter ) • $array[‘index’] • $array[ $index ] • WordPress coding standards configuration for PhpStorm by Rarst:
 https://gist.github.com/Rarst/1370155
  23. 23. Yoda Conditions if ( true === $the_force ) { 
 $victorious = you_will( $be ); 
 } ! A little bizarre, it is, to read. Get used to it, you will.
  24. 24. Code Templates
  25. 25. Code Templates • Predefined code with parameters • https://gist.github.com/barrykooij/7632945
  26. 26. The project
  27. 27. Open source your code!
  28. 28. What is someone ‘steals’ my code?!
  29. 29. What is someone tells me it’s poorly written?!
  30. 30. Open source your project • Yes, it’s definitely scary. • It’s what drives our community • It’s the future, not only of code
  31. 31. Versioning • Work with major, minor and bugfix release (x.y.z)
  32. 32. Changelog • Always keep a public change log • Give props to other people
  33. 33. WordPress.org Repository
  34. 34. WordPress repository • Use a header image • Have clear description what your plugin does • Non consumers rate by downloads combined with rating
  35. 35. Ask for ratings • Users don’t mind rating your plugin • Don’t ask right away, let the user use your product first • Make it a optional, and make this very clear!
  36. 36. Performance
  37. 37. Object Orientated Programming • Write OOP code, period. • Don’t know how? Learn it!
  38. 38. Conditional loading of code • Don’t load every class on every page load • Don’t initialise every class on every page load • Split frontend and backend classes - is_admin() • Use an autoloader
  39. 39. Documentation
  40. 40. Code documentation • Write code documentation, people will love you for it! • Write inline documentation directly after the function declaration • • • You won’t ‘forget’ writing it afterwards You’re making yourself rethink what you function should do All good IDE’s will use the inline documentation for autocompletion
  41. 41. Inline documentation • Explain what you’re doing • Explain why you’re doing it
  42. 42. Security
  43. 43. Sanitizing data • Checking if data is of an expected structure (e.g. email) • • is_email Reformatting data so it will be of expected structure (e.g. title) • sanitize_title http://codex.wordpress.org/Data_Validation#Input_Validation
  44. 44. Escaping data • Prevent XSS attacks, escape your data! • esc_url • esc_html
  45. 45. Capabilities • Is the user allowed to do this? ! // Check capabilities
 if ( ! current_user_can( 'manage_options' ) ) {
 wp_die( __( 'Cheatin’ uh?' ) );
 }
  46. 46. Direct file access • Don’t allow direct access to files • Place this at the top of your files: if ( ! defined( 'ABSPATH' ) ) {
 header( 'HTTP/1.0 403 Forbidden' );
 die;
 }
  47. 47. Asynchronous Javascript And XML
  48. 48. AJAX
  49. 49. AJAX allows you to run server side scripts asynchronous
  50. 50. WordPress made AJAX really simple!
  51. 51. Register the AJAX action • Tell WordPress your plugin is accepting AJAX requests • add_action( ‘wp_ajax_my_ajax_action’, array( $this, ’callback’ ) ); • add_action( ‘wp_ajax_nopriv_my_ajax_action’, array( $this, ’callback’ ) );
  52. 52. Use jQuery to do the POST jQuery.post(
 ajaxurl,
 {
 action : 'my_ajax_action',
 ajax_nonce : jQuery(‘.wpseo_redirects_ajax_nonce').val(),
 my_var : my_val
 },
 function (response) {
 // Do something
 }
 );
  53. 53. Internationalisation
  54. 54. Make your plugin translatable • load_plugin_textdomain( ‘my-textdomain', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' ); ! • __( ‘My String’, ‘my-textdomain’ ); • _e( ‘My String’, ‘my-textdomain’ );
  55. 55. Generate a .pot file
  56. 56. Unit Tests
  57. 57. An automated piece of code that invokes your application code to check a single assumption.
  58. 58. Unit Test example function test_get_single_role_by_user_query() { // Arrange
 $this->factory->user->create_many( 2, array( 
 'role' => 'subscriber' 
 ) ); // Act
 $wp_user_search = new WP_User_Query( array( 'role' => 'subscriber' ) ); 
 $users = $wp_user_search->get_results();
 } // Assert
 $this->assertEquals( 2, count( $users ) );
 

  59. 59. Code
  60. 60. Loading your plugin // Create object - Plugin init
 add_action( 'plugins_loaded', create_function( '', 'new MyPlugin();' ) );
  61. 61. Plugin DIR & FILE if ( ! defined( ’X_PLUGIN_DIR' ) ) {
 define( 'X_PLUGIN_DIR’, plugin_dir_path( __FILE__ ) );
 } if ( ! defined( ’X_PLUGIN_FILE' ) ) {
 define( ’X_PLUGIN_FILE', __FILE__ );
 }
  62. 62. Namespaces are great!
  63. 63. But, you can’t use them.
  64. 64. Prefixing • WordPress : PHP version 5.2.4 or greater • Namespaces : 5.3.0 or greater • Prefix your classes • class WPSEO_Admin { [...] }
  65. 65. Test your plugin on PHP 5.2
  66. 66. Thank you. ! Find me on Twitter:
 @CageNL

×