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 demystified 2017

933 views

Published on

Presented at WordCamp Montreal 2017

For many WordPress users, even seasoned PHP developers, creating new plugins for WordPress seems like a daunting task. This presentation aims to show attendees how simple creating plugins for WordPress from the ground up can be by looking at the architecture of a WordPress plugin, from the basic concepts of registering actions and filters to more advanced concepts such as the creation of admin pages and registering shortcodes.

Published in: Technology
  • Login to see the comments

  • Be the first to like this

Plugin development demystified 2017

  1. 1. Yannick Lefebvre @ylefebvre ylefebvre.ca WordPress Plugin Developer / Author Plugin Development Demystified Second Edition
  2. 2. Topics ● Plugins Overview ● Types of plugin developers ● Plugins vs functions.php ● File Structure ● Required Tools ● Plugin file header ● Turning functions.php code into a plugin ● Actions hook ● Filter hook ● Shortcodes ● More tools ● Considerations ● Publishing your plugin ● Recommended Readings ● Questions Plugin Development Demystified Slides at ylefebvre.ca/wcmtl2017
  3. 3. About me ● WordPress user since 2004 ● Released first plugin in 2005 ● 8 plugins on oficial repository ● Author of WordPress Plugin Development Cookbook, Second Edition – Use code WPDCSEd50 to get 50% of eBook on packtpub.com until Sept 12 ● Custom plugin development Slides at ylefebvre.ca/wcmtl2017
  4. 4. Plugins Overview ● Extend WordPress capabilities ● Open plugin architecture ● Ofer function of varying complexity ● More than 50,000 plugins available today!
  5. 5. Plugins Overview ● Extend WordPress capabilities ● Open plugin architecture ● Ofer function of varying complexity ● More than 50,000 plugins available today! Who makes these plugins and what tools do they use to make them?
  6. 6. Types of plugin developers Site administrator Website developer Community developerFreelance developer
  7. 7. Plugins vs functions.php ● Ever written your own plugin?
  8. 8. Plugins vs functions.php ● Ever written your own plugin? ● Ever added code to functions.php on your own site or in a customer project? function ylefebvre_add_favicon(){ ?> <link rel="shortcut icon" href="<?php echo get_stylesheet_directory_uri(); ?>/images/favicon.ico"/> <?php } add_action( 'wp_head', 'ylefebvre_add_favicon' ); function ylefebvre_add_favicon(){ ?> <link rel="shortcut icon" href="<?php echo get_stylesheet_directory_uri(); ?>/images/favicon.ico"/> <?php } add_action( 'wp_head', 'ylefebvre_add_favicon' );
  9. 9. Plugins vs functions.php ● Ever written your own plugin? functions.php code is 99%of the way towards making a plugin with 0%of the benefits ● Ever added code to functions.php on your own site or in a customer project? function ylefebvre_add_favicon(){ ?> <link rel="shortcut icon" href="<?php echo get_stylesheet_directory_uri(); ?>/images/favicon.ico"/> <?php } add_action( 'wp_head', 'ylefebvre_add_favicon' ); function ylefebvre_add_favicon(){ ?> <link rel="shortcut icon" href="<?php echo get_stylesheet_directory_uri(); ?>/images/favicon.ico"/> <?php } add_action( 'wp_head', 'ylefebvre_add_favicon' );
  10. 10. Plugins vs functions.php Benefit functions.php Plugin Easily activated or deactivated without need to search or risk of afecting other code Theme-independent Easy to update in customer installations
  11. 11. Basic Plugin File Structure ● One or more plain text php code file(s) ● Can contain other file types (e.g. images, text files, translation files, etc…) ● Distributed as zip file
  12. 12. Required Tools Required ● Text Editor (Notepad)
  13. 13. Required Tools Optional ● Code editor (e.g. Notepad++, Programmer’s Notepad, Sublime Text)
  14. 14. Required Tools Optional ● CodeIDE (PhpStorm)
  15. 15. Required Tools Optional ● Image Editor ● Local web server – VVV – Varying Vagrant Vagrants – XAMPP – MAMP – WSL – Windows Subsystem for Linux) ● Archive Tool
  16. 16. Plugin File Header <?php /* Plugin Name: My New Google Analytics Plugin Plugin URI: http://ylefebvre.ca Description: New revolutionary GA Plugin Version: 1.0 Author: Yannick Lefebvre Author URI: http://ylefebvre.ca License: GPL2 */ <?php /* Plugin Name: My New Google Analytics Plugin Plugin URI: http://ylefebvre.ca Description: New revolutionary GA Plugin Version: 1.0 Author: Yannick Lefebvre Author URI: http://ylefebvre.ca License: GPL2 */ ● Registers the plugin with WordPress ● Data visible to users in the Plugins admin section
  17. 17. First plugin sighting
  18. 18. Turning functions.php code into a plugin <?php /* Plugin Name: Add favicon Plugin URI: http://ylefebvre.ca Description: Add favicon to site Version: 1.0 Author: Yannick Lefebvre Author URI: http://ylefebvre.ca License: GPL2 */ function ylefebvre_add_favicon(){ ?> <link rel="shortcut icon" href="<?php echo get_stylesheet_directory_uri();?>/images/favicon.ico"/> <?php } add_action( 'wp_head', 'ylefebvre_add_favicon' ); <?php /* Plugin Name: Add favicon Plugin URI: http://ylefebvre.ca Description: Add favicon to site Version: 1.0 Author: Yannick Lefebvre Author URI: http://ylefebvre.ca License: GPL2 */ function ylefebvre_add_favicon(){ ?> <link rel="shortcut icon" href="<?php echo get_stylesheet_directory_uri();?>/images/favicon.ico"/> <?php } add_action( 'wp_head', 'ylefebvre_add_favicon' );
  19. 19. Three powerful tools Shortcodes Action hooks Filter hooks
  20. 20. Three powerful tools Action Hook Do you want to do something when an event occurs? Filter Hook Shortcode
  21. 21. Three powerful tools Action Hook Do you want to do something when an event occurs? Event WordPress is displaying page header Response Execute plugin code to display additional header content Filter Hook Shortcode
  22. 22. Three powerful tools Action Hook Do you want to do something when an event occurs? Event WordPress is displaying page header Response Execute plugin code to display additional header content Filter Hook Do you want to modify data before it is displayed? Shortcode
  23. 23. Three powerful tools Action Hook Do you want to do something when an event occurs? Event WordPress is displaying page header Response Execute plugin code to display additional header content Filter Hook Do you want to modify data before it is displayed? Event WordPress is preparing posts to be displayed Response Execute plugin code to add Javascript code to all links Shortcode
  24. 24. Three powerful tools Action Hook Do you want to do something when an event occurs? Event WordPress is displaying page header Response Execute plugin code to display additional header content Filter Hook Do you want to modify data before it is displayed? Provide easy-to-use code for users to add content to site Event WordPress is preparing posts to be displayed Response Execute plugin code to add Javascript code to all links Shortcode
  25. 25. Three powerful tools Action Hook Do you want to do something when an event occurs? Event WordPress is displaying page header Response Execute plugin code to display additional header content Filter Hook Do you want to modify data before it is displayed? Provide easy-to-use code for users to add content to site Event WordPress is preparing posts to be displayed Response Execute plugin code to add Javascript code to all links Shortcode Event User has placed shortcode in page content Response Generate content and send back to WP
  26. 26. Assigning an action hook add_action( 'hook_name', 'your_function_name', [priority], [accepted_args] ); Example add_action( 'wp_head', 'newga_header' ); add_action( 'hook_name', 'your_function_name', [priority], [accepted_args] ); Example add_action( 'wp_head', 'newga_header' ); ● Most hook names can be found in WordPress Codex or other repositories ● 864 action hooks ● You can learn about hooks by looking into WP source code: function wp_head() { do_action( 'wp_head' ); } function wp_head() { do_action( 'wp_head' ); }
  27. 27. Full action hook implementation /* Header code */ add_action( 'wp_head', 'newga_header' ); function newga_header() { ?> <script> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r; i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date(); a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g; m.parentNode.insertBefore(a,m)})(window,document,'script', 'https://www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-0000000-0', 'auto'); ga('send', 'pageview'); </script> <? } /* Header code */ add_action( 'wp_head', 'newga_header' ); function newga_header() { ?> <script> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r; i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date(); a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g; m.parentNode.insertBefore(a,m)})(window,document,'script', 'https://www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-0000000-0', 'auto'); ga('send', 'pageview'); </script> <? }
  28. 28. Full action hook implementation
  29. 29. Assigning a filter hook add_filter( 'filter_name', 'your_function_name', [priority], [accepted_args] ); Example add_filter( 'the_content', 'newga_content_filter' ); add_filter( 'filter_name', 'your_function_name', [priority], [accepted_args] ); Example add_filter( 'the_content', 'newga_content_filter' ); ● Receive data that can be modified and returned ● 1674 filter hooks function the_content($more_link_text = null, $stripteaser = 0) { $content = get_the_content($more_link_text, $stripteaser); $content = apply_filters('the_content', $content); $content = str_replace(']]>', ']]&gt;', $content); echo $content; } function the_content($more_link_text = null, $stripteaser = 0) { $content = get_the_content($more_link_text, $stripteaser); $content = apply_filters('the_content', $content); $content = str_replace(']]>', ']]&gt;', $content); echo $content; }
  30. 30. Full filter hook implementation add_filter( 'the_content', 'newga_content_filter' ); function newga_content_filter( $the_content ) { $new_content = str_replace( 'href', 'onClick="recordOutboundLink( this );return false;" href' , $the_content ); return $new_content; } add_filter( 'the_content', 'newga_content_filter' ); function newga_content_filter( $the_content ) { $new_content = str_replace( 'href', 'onClick="recordOutboundLink( this );return false;" href' , $the_content ); return $new_content; } ● Add Javascript function call to any links found in content
  31. 31. Full filter hook implementation
  32. 32. Full filter hook implementation add_action( 'wp_footer', 'footer_analytics_code' ); function footer_analytics_code() { ?> <script type="text/javascript"> function recordOutboundLink( link ) { ga( 'send', 'event', 'Outbound Links', 'Click', link.href, { 'transport': 'beacon', 'hitCallback': function() { document.location = link.href; } } ); } </script> <?php } add_action( 'wp_footer', 'footer_analytics_code' ); function footer_analytics_code() { ?> <script type="text/javascript"> function recordOutboundLink( link ) { ga( 'send', 'event', 'Outbound Links', 'Click', link.href, { 'transport': 'beacon', 'hitCallback': function() { document.location = link.href; } } ); } </script> <?php }
  33. 33. Adding a shortcode ● Simple codes used in a post or page to insert content – [gallery] – [gallery id="123" size="medium"] ● Can be used to output special code before and afer content – [style1]My text block[/style1] – Ofen introduced by themes ● If you repeatedly insert similar code on site, make a shortcode
  34. 34. Shortcode Implementation ● Since shortcodes are found anywhere within posts / pages, they must return their output add_shortcode( 'dq', 'mysite_div_quote' ); function mysite_div_quote( $atts, $content = null ) { if ( !empty( $content ) ) { return '<div class="site_quote" style="text- align:right">' . $content . '</div>'; } } add_shortcode( 'dq', 'mysite_div_quote' ); function mysite_div_quote( $atts, $content = null ) { if ( !empty( $content ) ) { return '<div class="site_quote" style="text- align:right">' . $content . '</div>'; } } [dq]This is my text[/dq][dq]This is my text[/dq]
  35. 35. Shortcode Implementation add_shortcode( 'twitterfeed', 'twitter_embed_shortcode' ); function twitter_embed_shortcode( $args ) { extract( shortcode_atts( array( 'user_name' => 'ylefebvre' ), $args ) ); if ( !empty( $user_name ) ) { $output = '<a class="twitter-timeline" href="'; $output .= esc_url( 'https://twitter.com/' . $user_name ); $output .= '">Tweets by ' . esc_html( $user_name ); $output .= '</a><script async '; $output .= 'src="//platform.twitter.com/widgets.js"'; $output .= ' charset="utf-8"></script>'; } else { $output = ''; } return $output; } add_shortcode( 'twitterfeed', 'twitter_embed_shortcode' ); function twitter_embed_shortcode( $args ) { extract( shortcode_atts( array( 'user_name' => 'ylefebvre' ), $args ) ); if ( !empty( $user_name ) ) { $output = '<a class="twitter-timeline" href="'; $output .= esc_url( 'https://twitter.com/' . $user_name ); $output .= '">Tweets by ' . esc_html( $user_name ); $output .= '</a><script async '; $output .= 'src="//platform.twitter.com/widgets.js"'; $output .= ' charset="utf-8"></script>'; } else { $output = ''; } return $output; }
  36. 36. Shortcode Implementation ● The resulting shortcode [twitterfeed user_name='WordPress'][twitterfeed user_name='WordPress'] becomes
  37. 37. More tools Admin menu
  38. 38. More tools Admin menu Admin pages
  39. 39. More tools Admin menu Admin pages Extend user editor
  40. 40. More tools Admin menu Admin pages Custom post types Extend user editor
  41. 41. More tools Admin menu Admin pages Custom post types Add custom meta boxes to any editor Extend user editor
  42. 42. More tools Admin menu Admin pages Custom post types Add custom meta boxes to any editor Extend user editor New widgets
  43. 43. More tools Admin menu Admin pages Custom post types Add custom meta boxes to any editor Extend user editor New widgets Plugin translation
  44. 44. More tools ● Store and retrieve plugin settings from site database ● Query posts ● Insert styles and scripts in page header and footer ● Directly access database
  45. 45. Considerations ● Function names must be diferent from WordPress core functions and other plugins ● Entire content is evaluated each time site is rendered ● A single error will usually bring down the entire site ● Using a local development environment is much safer than developing on live site
  46. 46. Publishing your plugin ● wordpress.org oficial repository – Free plugins only – Must follow GPL license – Discoverable from admin plugins page – Built-in update mechanism ● Marketplaces (CodeCanyon, MOJO Marketplace, WPEden, etc…) – Paid premium plugins – Need to implement custom update method – Higher level of support expectation
  47. 47. Conclusions ● Creating a plugin can be created using very few lines of code ● When you deliver customer projects, make plugins over adding code to functions.php ● Consider distributing your plugins to WordPress community
  48. 48. Recommended Readings ● WordPress Plugin Development Cookbook, Second Edition by Yannick Lefebvre, Packt Publishing ● WordPress Codex (codex.wordpress.com) ● PHP.net ● StackOverflow.com Programming Samples ● Today's presentation and code samples available at: – http://ylefebvre.ca/wcmtl2017 WPDCSEd50
  49. 49. Questions? Thank you for attending this talk on Plugin Development Demystified Yannick Lefebvre @ylefebvre ylefebvre.ca

×