WordPress Plugins: ur doin it wrong ur doin it wrong <ul><li>Will Norris < http://willnorris.com /> </li></ul>
 
 
 
Effect of Plugins <ul><li>Upgradability </li></ul><ul><li>Performance </li></ul><ul><li>Security </li></ul><ul><li>Extensi...
Unique Function Names
Function Name Prefix <ul><li>wcsea_activate() </li></ul><ul><li>wcsea_deactivate() </li></ul><ul><li>wcsea_uninstall() </l...
Class <ul><li>class WordCampSEA { </li></ul><ul><li>function activate() </li></ul><ul><li>function deactivate() </li></ul>...
Escape Values
What do these have in common? <ul><li>XSS </li></ul><ul><li>CSRF </li></ul><ul><li>SQL-injection </li></ul>
Escape Values <ul><li>1. Standard prefix </li></ul><ul><li>2. Context (attr, html, js, sql, url, url_raw) </li></ul><ul><l...
Never Assume File Location
Traditional Directory Layout <ul><li>example.com/ </li></ul><ul><li>wordpress/ </li></ul><ul><li>wp-config.php </li></ul><...
Non-Traditional Layout (since WP 2.6) <ul><li>example.com/ </li></ul><ul><li>wordpress/ </li></ul><ul><li>wp-config.php </...
Plugin URL <ul><li>ur doin it wrong: </li></ul><ul><li><img src=”<?php bloginfo(‘wpurl’) ?>/wp-content/plugins/wcsea/logo....
Plugin URL <ul><li>plugins_url() </li></ul><ul><ul><ul><li>supports WPMU plugin directory </li></ul></ul></ul><ul><ul><ul>...
Friends of plugins_url() <ul><li>site_url() </li></ul><ul><li>admin_url() </li></ul><ul><li>includes_url() </li></ul><ul><...
Including Files <ul><li>ur doin it wrong: </li></ul><ul><li>include ‘../../wp-content/...’ </li></ul><ul><li>dats bedder: ...
Find the Right Hook <ul><li>Load as late as possible, but no later </li></ul>
Admin Hooks <ul><li>ur doin it wrong: </li></ul><ul><li>add_action(‘admin_init’, ‘wcsea_admin_init’) </li></ul><ul><li>add...
Styles and Scripts <ul><li>ur doin it wrong: </li></ul><ul><li><script rel=”<?php echo plugins_url(‘wcsea.js’, __FILE__) ?...
Styles and Scripts <ul><li>wp_register_* and wp_enqueue_* </li></ul><ul><ul><ul><li>support dependencies </li></ul></ul></...
Add your own hooks <ul><li>A strategically placed hook covers a multitude of sins. </li></ul>
Custom Hooks <ul><li>Can do everything core WP hooks do: </li></ul><ul><ul><ul><li>event notification (actions) </li></ul>...
Custom Hooks <ul><li>do_action(‘my-action’) </li></ul><ul><li>do_action(‘my-action’, $a, $b) </li></ul><ul><li>do_action_r...
Custom Tables
Designed for Flexibility <ul><li>WordPress database supports </li></ul><ul><ul><ul><li>custom options </li></ul></ul></ul>...
Custom Post Types <ul><li>Used by WordPress core for </li></ul><ul><ul><ul><li>posts </li></ul></ul></ul><ul><ul><ul><li>p...
If it walks like a duck... <ul><li>author </li></ul><ul><li>date and time </li></ul><ul><li>title </li></ul><ul><li>conten...
Admin Settings Pages
Admin Settings Pages <ul><li>Don’t waste time processing manually </li></ul><ul><li>register_setting( ‘wcsea’, ‘my-option’...
Admin Settings Pages <ul><li>Do you really need a dedicated page? </li></ul><ul><li>Add options to any built-in settings p...
Direct Plugin Files
Direct Plugin File Calls <ul><li>Direct HTTP request to plugin file ajax.php: </li></ul><ul><li>echo ‘<script type=”text/j...
Direct Plugin File Calls <ul><li>If ajax.php includes anything similar to: </li></ul><ul><li>require_once(‘../../../wp-loa...
WordPress Requests <ul><li>Permalink URL: </li></ul><ul><li>http://example.com/2009/01/hello-world </li></ul><ul><li>becom...
Custom WP Request <ul><li>Instead of making an AJAX call to: </li></ul><ul><li>http://example.com/wp-content/plugins/wcsea...
Custom WP Requests <ul><li>function wcsea_parse_request($wp) { </li></ul><ul><li>// only process requests with &quot;wcsea...
Upcoming SlideShare
Loading in …5
×

WordPress Plugins: ur doin it wrong

2,615
-1

Published on

Slides from presentation at WordCamp Portland

Published in: Technology, Business
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,615
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
43
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide
  • started from my personal pet peeves in plugins Andrew Ozz wrote great post two weeks ago Simplicity of WP plugins is double edged sword - low barrier to entry (even if you ride the PHP Short Bus...) - deceptively simple -- easy to learn, hard to master
  • Plugins break WP Upgrades - Scoble didn’t upgrade
  • suffix is optional, and only available for html and attr contexts
  • delay expensive operations until they’re actually needed
  • Goal of WordPress core nor plugins is to add every feature possible standard install makes 1200 filter calls, 20 action calls MySpaceID plugin extends OpenID plugin
  • no registration necessary, just call them just in time extensions for your own plugins ex: Activity Streams - ‘register service’ model - just in time adding of new services
  • WordPress Plugins: ur doin it wrong

    1. 1. WordPress Plugins: ur doin it wrong ur doin it wrong <ul><li>Will Norris < http://willnorris.com /> </li></ul>
    2. 5. Effect of Plugins <ul><li>Upgradability </li></ul><ul><li>Performance </li></ul><ul><li>Security </li></ul><ul><li>Extensibility </li></ul>
    3. 6. Unique Function Names
    4. 7. Function Name Prefix <ul><li>wcsea_activate() </li></ul><ul><li>wcsea_deactivate() </li></ul><ul><li>wcsea_uninstall() </li></ul>
    5. 8. Class <ul><li>class WordCampSEA { </li></ul><ul><li>function activate() </li></ul><ul><li>function deactivate() </li></ul><ul><li>function uninstall() </li></ul><ul><li>} </li></ul>
    6. 9. Escape Values
    7. 10. What do these have in common? <ul><li>XSS </li></ul><ul><li>CSRF </li></ul><ul><li>SQL-injection </li></ul>
    8. 11. Escape Values <ul><li>1. Standard prefix </li></ul><ul><li>2. Context (attr, html, js, sql, url, url_raw) </li></ul><ul><li>3. Optional translation suffix </li></ul>http://markjaquith.wordpress.com/2009/06/12/escaping-api-updates-for-wordpress-2-8/
    9. 12. Never Assume File Location
    10. 13. Traditional Directory Layout <ul><li>example.com/ </li></ul><ul><li>wordpress/ </li></ul><ul><li>wp-config.php </li></ul><ul><li>wp-content/ </li></ul><ul><li>plugins/ </li></ul><ul><li>themes/ </li></ul>
    11. 14. Non-Traditional Layout (since WP 2.6) <ul><li>example.com/ </li></ul><ul><li>wordpress/ </li></ul><ul><li>wp-config.php </li></ul><ul><li>wordpress-content/ </li></ul><ul><li>plugins/ </li></ul><ul><li>themes/ </li></ul>
    12. 15. Plugin URL <ul><li>ur doin it wrong: </li></ul><ul><li><img src=”<?php bloginfo(‘wpurl’) ?>/wp-content/plugins/wcsea/logo.png” ?> </li></ul><ul><li>dats bedder: </li></ul><ul><li><img src=”<?php echo WP_PLUGIN_URL ?>/wcsea/logo.png ?>”/> </li></ul><ul><li>you haz it: </li></ul><ul><li><img src=”<?php echo plugins_url(‘logo.png’, __FILE__) ?>” /> </li></ul>
    13. 16. Plugin URL <ul><li>plugins_url() </li></ul><ul><ul><ul><li>supports WPMU plugin directory </li></ul></ul></ul><ul><ul><ul><li>auto detects SSL </li></ul></ul></ul><ul><ul><ul><li>supports renamed plugin directory </li></ul></ul></ul><ul><ul><ul><li>calls ‘plugins_url’ filter </li></ul></ul></ul>
    14. 17. Friends of plugins_url() <ul><li>site_url() </li></ul><ul><li>admin_url() </li></ul><ul><li>includes_url() </li></ul><ul><li>content_url() </li></ul><ul><li>no home_url() (why not?) </li></ul>
    15. 18. Including Files <ul><li>ur doin it wrong: </li></ul><ul><li>include ‘../../wp-content/...’ </li></ul><ul><li>dats bedder: </li></ul><ul><li>include ABSPATH . ‘wp-content/...’ </li></ul><ul><li>you haz it: </li></ul><ul><li>include WP_CONTENT_DIR . ‘/...’ </li></ul>
    16. 19. Find the Right Hook <ul><li>Load as late as possible, but no later </li></ul>
    17. 20. Admin Hooks <ul><li>ur doin it wrong: </li></ul><ul><li>add_action(‘admin_init’, ‘wcsea_admin_init’) </li></ul><ul><li>add_action(‘admin_head’, ‘wcsea_admin_head’) </li></ul><ul><li>you haz it: </li></ul><ul><li>$hookname = add_options_page( ... ) </li></ul><ul><li>add_action(“admin_load-$hookname”, ‘wcsea_admin_init’) </li></ul><ul><li>add_action(“admin_head-$hookname”, ‘wcsea_admin_head’) </li></ul>
    18. 21. Styles and Scripts <ul><li>ur doin it wrong: </li></ul><ul><li><script rel=”<?php echo plugins_url(‘wcsea.js’, __FILE__) ?>”></script> </li></ul><ul><li>you haz it: </li></ul><ul><li>wp_enqueue_script(‘wcsea’, plugins_url(‘wcsea.js’, __FILE__)) </li></ul><ul><li>wp_enqueue_style(‘wcsea’, plugins_url(‘wcsea.css’, __FILE__)) </li></ul>
    19. 22. Styles and Scripts <ul><li>wp_register_* and wp_enqueue_* </li></ul><ul><ul><ul><li>support dependencies </li></ul></ul></ul><ul><ul><ul><li>push scripts to footer </li></ul></ul></ul><ul><ul><ul><li>caching support based on version </li></ul></ul></ul><ul><ul><ul><li>(one day) server side concatenation </li></ul></ul></ul>
    20. 23. Add your own hooks <ul><li>A strategically placed hook covers a multitude of sins. </li></ul>
    21. 24. Custom Hooks <ul><li>Can do everything core WP hooks do: </li></ul><ul><ul><ul><li>event notification (actions) </li></ul></ul></ul><ul><ul><ul><li>massage data (the_content) </li></ul></ul></ul><ul><ul><ul><li>replace values (stylesheet) </li></ul></ul></ul><ul><ul><ul><li>extend functionality (http_api_curl) </li></ul></ul></ul><ul><ul><ul><li>replace functionality </li></ul></ul></ul>
    22. 25. Custom Hooks <ul><li>do_action(‘my-action’) </li></ul><ul><li>do_action(‘my-action’, $a, $b) </li></ul><ul><li>do_action_ref_array(‘my-action’, array($wcsea)) </li></ul><ul><li>apply_filters(‘my-filter’, $wcsea) </li></ul><ul><li>apply_filters(‘my-filter’, $wcsea, $a, $b) </li></ul>
    23. 26. Custom Tables
    24. 27. Designed for Flexibility <ul><li>WordPress database supports </li></ul><ul><ul><ul><li>custom options </li></ul></ul></ul><ul><ul><ul><li>arbitrary metadata for posts, users, and comments (2.9) </li></ul></ul></ul><ul><ul><ul><li>custom taxonomies </li></ul></ul></ul><ul><ul><ul><li>custom post types </li></ul></ul></ul>
    25. 28. Custom Post Types <ul><li>Used by WordPress core for </li></ul><ul><ul><ul><li>posts </li></ul></ul></ul><ul><ul><ul><li>pages </li></ul></ul></ul><ul><ul><ul><li>revisions </li></ul></ul></ul><ul><ul><ul><li>attachments </li></ul></ul></ul>
    26. 29. If it walks like a duck... <ul><li>author </li></ul><ul><li>date and time </li></ul><ul><li>title </li></ul><ul><li>content </li></ul><ul><li>comments </li></ul><ul><li>categories and tags </li></ul><ul><li>permalink </li></ul><ul><li>order </li></ul><ul><li>hierarchy </li></ul><ul><li>(additional arbitrary metadata) </li></ul>
    27. 30. Admin Settings Pages
    28. 31. Admin Settings Pages <ul><li>Don’t waste time processing manually </li></ul><ul><li>register_setting( ‘wcsea’, ‘my-option’ ) </li></ul><ul><li>http://codex.wordpress.org/Settings_API </li></ul><ul><li>http://codex.wordpress.org/Creating_Options_Pages# Register_Settings </li></ul>
    29. 32. Admin Settings Pages <ul><li>Do you really need a dedicated page? </li></ul><ul><li>Add options to any built-in settings page </li></ul><ul><li>add_settings_field( ... ) </li></ul>
    30. 33. Direct Plugin Files
    31. 34. Direct Plugin File Calls <ul><li>Direct HTTP request to plugin file ajax.php: </li></ul><ul><li>echo ‘<script type=”text/javascript”> </li></ul><ul><li>jQuery.get(“‘ . plugins_url(‘ajax.php’, __FILE__) . ‘”); </li></ul><ul><li>// do something with AJAX data </li></ul><ul><li></script>’; </li></ul>
    32. 35. Direct Plugin File Calls <ul><li>If ajax.php includes anything similar to: </li></ul><ul><li>require_once(‘../../../wp-load.php’); </li></ul><ul><li>ur doin it wrong </li></ul>
    33. 36. WordPress Requests <ul><li>Permalink URL: </li></ul><ul><li>http://example.com/2009/01/hello-world </li></ul><ul><li>becomes: </li></ul><ul><li>http://example.com/index.php? </li></ul><ul><li>year=2009& </li></ul><ul><li>monthnum=01& </li></ul><ul><li>name=hello-world </li></ul>
    34. 37. Custom WP Request <ul><li>Instead of making an AJAX call to: </li></ul><ul><li>http://example.com/wp-content/plugins/wcsea/ajax.php </li></ul><ul><li>we want a URL like: </li></ul><ul><li>http://example.com/index.php?wcsea=ajax-handler </li></ul>
    35. 38. Custom WP Requests <ul><li>function wcsea_parse_request($wp) { </li></ul><ul><li>// only process requests with &quot;wcsea=ajax-handler&quot; </li></ul><ul><li>if (array_key_exists('wcsea', $wp->query_vars) </li></ul><ul><li>&& $wp->query_vars['wcsea'] == 'ajax-handler') { </li></ul><ul><li>// process the request. </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>add_action('parse_request', 'wcsea_parse_request'); </li></ul><ul><li>function wcsea_query_vars($vars) { </li></ul><ul><li>$vars[] = 'wcsea'; </li></ul><ul><li>return $vars; </li></ul><ul><li>} </li></ul><ul><li>add_filter('query_vars', 'wcsea_query_vars'); </li></ul>
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×