Upload
michael-stowe
View
4.584
Download
1
Embed Size (px)
DESCRIPTION
An introduction to hooks in WordPress including the Filter Hook, the Action Hook, advanced hook functions, and also implementing custom hooks into your WordPress plugins.
Citation preview
Get “Hooked” on WordPress Hooks
November 17, 2013
MIKESTOWE
• Open Source Contributor (3 WP Plugins)
• Author, Speaker, and Consultant
• 10+ years experience hacking PHP
• Zend Certified PHP 5.3 Software Engineer
• Developer Advocate with Constant Contact
.com @mikegstowe
About You…
• Familiar with WordPress
• Familiar with PHP Code (at least beginner)
• Learning to, have written, or in the process of writing a WordPress Plugin
• Have a GREAT sense of humor
@insert_your_twi8er_handle_here
Not You…
No problem!*
These slides will be posted online, just go to http://www.mikestowe.com/slides and start with “PHP for Web Designers,” then do “Building Your WordPress Plugin,” and then feel free to jump to these slides and they should make sense J *Unless you don’t have a sense of humor, nothing I can do for you there…
Insert Frownie Face Here…
What we’re gonna talk about… What Are Hooks
• What are Hooks
• How they Work
• Code Considera<ons
Types of Hooks
• The Filter Hook
• The Ac<on Hook
• Advanced Hooking
• Custom Hooks
• The Codex
What we’re NOT talking about…
This guy…
What are Hooks? In technical and strict terms: a Hook is an event, i.e.
event as understood by Observer paIern, invoked
by the do_action() or apply_filters() call
that aJerwards triggers all the ac<on or filter
func<ons, previously hooked to that event…
h8p://codex.wordpress.org/Glossary#Hook
What are Hooks? Essen<ally, the hook or event triggers the appropriate
Observer, that takes an array of “hooked” func<ons
and calls them using the PHP call_user_func()
func<on, allowing for code and opera<ons to be
implemented into the core process without modifying
the core code.
A Rose by Any Other Name… Because Hooks are required by Ac<ons and Filter you
may hear the phrase "Ac<on Hooks" and "Filter Hooks"
used from <me to <me.
h8p://codex.wordpress.org/Glossary#Hook
Don’t let Hooks inQmidate you!
Ok, we might talk about this guy a little bit
*Source code remains untouched for easy upgrades
Hook Example <?php add_filter('the_content', 'my_function'); function my_function($content) { return $content . '<p>Share with a Friend!</p>'; } ?> !
The above code creates a very simple “Filter Hook” that adds the text “Share with a Friend!” after each post/ page entry… Yeah, it’s that easy!
*Source code remains untouched for easy upgrades
One Caveat Because your func<on called by the hook becomes part of the WordPress code it is important to make sure you have a unique name for your func<on. If your func<on contains the same name as another WordPress or plugin func<on a fatal PHP error will be thrown, breaking your en<re site.
start_process() output() modify_content()
pluginname_process() pluginname_output() pluginname_modify_content()
FuncQon Naming Example <?php add_filter('the_content', '_trackableshare_process'); function _trackableshare_process($content) { /* ... */ } ?> !
For the Trackable Social Share Icons plugin all functions start with the “_trackableshare_” prefix to prevent confusion with other plugins.
OOP – and You know me If you are using Object Oriented Code, or build your plugin as a class you can avoid func<on naming concerns as your methods will be separate from the core func<on (or in another scope). However, you s<ll need to make sure your class name (or it’s namespace) is unique.
Class/ Object Oriented Example <?php class trackable_social_share { public function __construct() { // Add Hooks add_filter('the_content', array($this, 'process')); } public function process($content) { /* ... */ } } $trackable_social_share = new trackable_social_share(); ?> !
This is a little bit more complex, and you don’t have to build your plugin this way. This is just an example of the differences.
QuesQons so far? • A hook is an event that calls a func<on or a method upon an ac<on
• Your code is pulled into the WordPress code dynamically, becoming part of the site
• Hooks are oJen referred to as “Ac<on Hooks” and “Filter Hooks”
• You can use procedural or Object Oriented Code with Hooks
• Just remember naming is key!
• Pirates are bad.
The Filter Hook The Filter Hook is designed modify content. Rather
than being enacted on a specific ac<on, filter
hooks are called when processing content,
whether it be for saving or rendering.
The Filter Hook In our previous examples we used the filter hook
to append content to our post/ page content. This
is a perfect example of how this hook works.
We can also manipulate the content using other
PHP func<ons as wanted.
Content ManipulaQon Example <?php add_filter('the_content', 'ninjas_vs_pirates'); function ninjas_vs_pirates($content) { return str_replace('Pirates Rule', 'Ninjas Rule', $content); } ?> !
The above code will replace every instance of “Pirates Rule” with “Ninjas Rule” in the page/ post text
Pro Tip Don’t use Filter Hooks to replace [shortcodes]… You can do this using str_replace(), but WordPress has a built in func<on just for short codes called add_shortcode()
<?php add_shortcode('pirate', 'ninja_function'); function ninja_function() { return 'ninja'; } ?> !
Filtering Beyond Posts Filters can be used at mul<ple <mes and on mul<ple types of content. This means you can modify the content before storing it to the database, or later during the rendering phase. You may also modify author data, comments, widgets, links, blogroll, dates/<mes, items in the wp-‐admin, etc. all dynamically without having to modify the WordPress core code.
View all opQons at: h8p://codex.wordpress.org/Plugin_API/Filter_Reference
Pre-‐Save Comment Filter <?php add_filter('comment_status_pre ', 'pluginname_noswearwords'); function pluginname_noswearwords($content) { $badwords = array('pirate', 'pirates', 'plank', 'patch', 'hook'); return str_replace($badwords, '*ninja starred*', $content); } ?> !
This code replaces the “bad words” in the array with the text “*ninja starred*” before saving it to the database.
Adding Filter Hooks All Filter Hooks are added using the add_filter() func<on:
add_filter( $tag, $function, [$priority], [$accepted_args] ) Tag: (string) What type of content process the filter should be applied to FuncQon: (callback) The func<on to be run Priority: (int) – op<onal Order in which it should be run, the lower the number the sooner it will be executed, default is 10 Accepted Args: (int) – op<onal Number of accepted arguments when using WP >= 1.5.1 and a matching apply_filters() call. Default is 1
hIp://codex.wordpress.org/Func<on_Reference/add_filter
In PracQce <?php add_filter('the_content', 'pirates_rule'); add_filter('the_content', 'ninjas_rule', 9); add_filter('the_content', 'you_rule', 8); function pirates_rule($content) { return str_replace('who_rules', 'Pirates Rule', $content); } function ninjas_rule($content) { return str_replace('who_rules', 'Ninjas Rule', $content); } function you_rule($content) { return str_replace('who_rules', 'You Rule', $content); } ?> !
Assuming our blog post text is just “who_rules,” what would be the output of this code?
Rock Star! The correct answer is “You Rule” as this has the highest priority. Since we are running a string replace (str_replace()), this will replace the who_rules text with “You Rule” leaving nothing for pirates_rule or ninjas_rule to replace!
In PracQce – Trick QuesQon <?php add_filter('the_content', 'pirates_rule'); add_filter('the_content', 'ninjas_rule', 9); add_filter('the_content', 'you_rule', 8); function pirates_rule($content) { return 'Pirates Rule'; } function ninjas_rule($content) { return 'Ninjas Rule'; } function you_rule($content) { return 'You Rule'; } ?> !
Assuming our blog post text is just “who_rules,” what would be the output of this code?
You Can’t Be Tricked! The correct answer is “Pirates Rule” as this has the lowest priority (default of 10). This <me we aren’t replacing any set of text, but are actually overwri<ng the content of the post completely! First we overwrote the text with “You Rule”, then we overwrote that with “Ninjas Rule,” and finally, because it was executed last we overwrote the text with “Pirates Rule!”
Thank ya, Thank ya very much
Thank ya, thank ya very much
The AcQon Hook The Ac<on Hook is triggered in WordPress when an
ac<on event takes place, such as loading a page
(front-‐end or admin), inser<ng comments, saving
blog posts, or even switching themes.
The AcQon Hook For example, when loading header, footer, or even
the admin menu an Ac<on Hook is triggered.
Likewise, when crea<ng a post the admin_init
Ac<on Hook is called, and when saving it the
save_post Ac<on Hook is called.
The AcQon Hook The Ac<on Hook is designed to provide greater
flexibility in how items are processed as well as the
ability to add addi<onal features to the WordPress
system (such as addi<onal text fields when
crea<ng or edi<ng a post), adding JavaScript/
Stylesheets, and other items.
AcQon Hook Example <?php add_action('admin_menu', 'my_new_plugin_add_admin_menu_item'); function my_new_plugin_add_admin_menu_item() { if(function_exists('add_submenu_page')) { add_submenu_page('plugins.php','My New Plugin', 'My New Plugin', 10, 'my_new_plugin', 'my_new_plugin_admin_page_function'); } } ?> !
The above code adds a new menu item to the admin menu when it is built, allowing us to create an admin page for our Plugin if desired.
AcQon Hook Example The AcQon: Get Admin Menu
The Request: While building the Admin Menu, Run this func<on that adds an addi<onal item under the Plugins sec<on.
The Result: The menu is generated with our requested link included under the Plugin Sec<on. When the link is clicked the func<on we set in the add_submenu_page() or my_new_plugin_admin_page() will be used to generate the admin page for our plugin.
AcQon Hook Example #2 <?php add_action('admin_init', 'add_pirate_comments', 1); function add_pirate_comments() { add_meta_box( 'pirate_comments', __( 'What does the Pirate Say', 'pirate_text' ), ‘pirate_text_box_function’, 'post', 'normal', 'high' ); } ?> !
The above code adds a new meta Create/ Edit post screen in the admin panel box based on the pirate_text_box_function() using the add_meta_box() function
Pro Tip The __() func<on is the Translate func<on for WordPress. By pumng your text in this func<on WordPress will use the translate() func<on to grab the proper text based on the locale of your user.
hIp://codex.wordpress.org/Func<on_Reference/_2
<?php add_action('admin_init', 'add_pirate_comments', 1); function add_pirate_comments() { add_meta_box( 'pirate_comments', __( 'What does the Pirate Say', 'pirate_text' ), ‘pirate_text_box_function’, 'post', 'normal', 'high' ); } ?> !
Pro Tip This means for some locales we could have the text “What does the Pirate Say” actually be…
hIp://codex.wordpress.org/Func<on_Reference/_2
Pro Tip This means for some locales we could have the text “What does the Pirate Say” actually be…
Or whatever the heck the Fox says…
hIp://codex.wordpress.org/Func<on_Reference/_2
AcQon Hook Example #3 <?php add_action('save_post', 'my_plugin_save_post_data'); function _trackableshare_save_box_postdata($id) { // Save logic goes here where $id is the ID of the post } ?> !
The above code calls the my_plugin_save_post_data() function when a post is created or updated. There we can store the data where-ever we need to.
Adding AcQon Hooks All Ac<on Hooks are added using the add_ac<on() func<on:
add_action( $tag, $function, [$priority], [$accepted_args] ) Tag: (string) What type of content process the filter should be applied to FuncQon: (callback) The func<on to be run Priority: (int) – op<onal Order in which it should be run, the lower the number the sooner it will be executed, default is 10 Accepted Args: (int) – op<onal Number of accepted arguments when using WP >= 1.5.1 and a matching apply_filters() call. Default is 1
hIp://codex.wordpress.org/Func<on_Reference/add_ac<on
QuesQons so far? • Filter Hooks are designed to modify Content. Ac<on Hooks are designed to add or remove Code in that ac<on.
• Filter hooks are added using the add_filter() func<on
• Ac<on hooks are added using the add_ac<on() func<on
• Priority is important! Remember a lower number is more important priority wise than a higher number.
• We do not really know what the Fox says.
Advanced Hooking WordPress also provides several func<ons for
determining what func<ons have been hooked to a
filter, if the hook has already been triggered,
removing func<ons from hooks, and even
removing all func<on calls from a hook.
AcQon Based FuncQons has_action(‘hook’, ‘function’); did_action(‘hook’); remove_action(‘hook’, ‘function’); remove_all_actions(‘hook’);
Filter Based FuncQons has_filter(‘hook’, ‘function’); did_filter(‘hook’); current_filter(); remove_filter(‘hook’, ‘function’); remove_all_filters(‘hook’);
has_* The has_action() and has_filter() func<ons detect whether or not a func<on has been added to the array of hooks for that par<cular event. This will return boolean true or false.
did_* The did_action() and did_filter() func<ons detect whether or not the event has been triggered. If your event was not hooked, but the event was run it will s<ll return true as it is not func<on specific. This will return boolean true or false.
current_filter The current_filter() func<on returns the current event that is being processed. For example, if the hook triggered was “the_content,” this func<on would return “the_content.” This is especially useful when using one func<on or method to handle mul<ple types of filter events.
remove_* The remove_action() and remove_filter() func<ons will remove a specific func<on from a specific ac<on or filter hook. This is useful if you no longer want the func<on to be called when the event is triggered.
remove_all_* The remove_all_actions() and remove_all_filters() func<ons will remove all associated func<ons from an ac<on hook or filter hook. This func<on takes the ‘hook’ as the first parameter, and also accepts a second, op<onal parameter that is priority specific. For example, if you wanted to remove all items from the_content with a priorit of 4: remove_all_filters(‘the_content’, 4);
CreaQng Custom Hooks You can also setup custom hooks in your plugin or theme that can be hooked into by other plugins using the do_ac<on() and apply_filters() func<ons. do_action(‘hook_name’); apply_filters(‘hook_name’, $content);
‘hook_name’ is the name you created for your new hook, such as ‘my_plugin_init’ or ‘my_plugin_content’
Adding Custom Hooks <?php function my_plugin_function() { // Allow hooks into this function do_action('my_plugin_init'); // Create Content $content = 'Hello world'; // Allow Content to have filters ran against it // Be sure to store the returned result of the FILTER!!! $content = apply_filters('my_plugin_content', $content); } ?> !
QuesQons? • WordPress provides several func<ons that we can use to modify hooks even aJer using the add_filter() or add_ac<on() func<ons.
• WordPress also allows you to create custom Hooks within your plugin or theme .
• When crea<ng a custom Filter Hook it is important to remember to store the result as the filtered content will be passed back through the apply_filters() func<on.
• This sec<on wasn’t very funny.
Use the Codex We’ve covered a lot of informa<on about WordPress hooks, and there is a LOT more informa<on available on the WordPress Codex, including the types of params certain hooks will send to your hooked func<on when that event is triggered. You can learn about the different Filter Hooks at: hIp://codex.wordpress.org/Plugin_API/Filter_Reference And AcQon Hooks at: hIp://codex.wordpress.org/Plugin_API/Ac<on_Reference Of course, always remember the main Codex URL:
h8p://codex.wordpress.org/
A Final Thought…
A Final Thought…
And Kaygo likes music L Don’t be a pirate.
THANK YOU.
@mikegstowe
visit mikestowe.com/slides for more on PHP and Web Development
@ctct_api
A big thank you to Constant Contact for making this presentation possible