Hooks

Actions, Filters, 
& Basic Ajax 





http://slides.com/jupitercow/wp-hooks/live

Jake Snyder

@suckrpnch

jake@jcow.com

Jupitercow

@Jupitercow

Jupitercow.com

info@jcow.com


What is a hook?


An opportunity to make changes 

Hooks allow you to:
  • Manipulate data
  • Add functionality
  • Trigger events

Hook Functions

Add function to a tag
Run all functions for tag



add_filter()
add_action()
apply_filters()
do_action()


Add Filter


add_filter( $tag, $function_to_add, $priority=10, $accepted_args=1 ) 

$tag 

$function_to_add

$priority = 10

$accepted_args = 1

Apply Filters


apply_filters( $tag, $value )

$tag 

$value

Filter Example


Apply filters to the message
$message = "Hello user";$message = apply_filters( 'message_filter', $message );echo $message;
outputs: "Hello  user"

In your functions.php, add a filter
add_filter( 'message_filter', 'custom_message' );
function custom_message( $message ) {
	$user = wp_get_current_user();
	$message = "Hello " . $user->first_name;
	return $message;
}
now it outputs: "Hello Jake"

Add Action


add_action( $tag, $function_to_add, $priority=10, $accepted_args=1 )
$tag

$function_to_add

$priority = 10

$accepted_args = 1

Do Action


do_action( $tag, $arg = '' )

$tag

$arg = ''

Action Example

Add an event to be triggered
add_action( 'wp_head', 'custom_add_analytics_production' );

function custom_add_analytics_production() {
	if (! defined('WP_DEBUG') || ! WP_DEBUG ) : ?>
		<script>
			[Analytics code]
		</script>
<?php endif;}

Create an event trigger
function wp_head() {
    do_action( 'wp_head' );
}


Filters


Always return data

Data passes through a filter and can be
changed before it is returned



Replace "Howdy" with "Welcome"


 



Replace "Howdy" with "Welcome"


add_filter( 'gettext', 'custom_replace_howdy', 10, 3 );

function custom_replace_howdy( $translated, $text, $domain )
{
    if ( false !== strpos($translated, "Howdy") )
    {
        return str_replace("Howdy", "Welcome back", $translated);
    }
    return $translated;
}



Replace "Howdy" with "Welcome"

Before:                                                          After:




Add Share Icons to Content





Add Share Icons to Content


add_filter( 'the_content', 'custom_share_icons' );

function custom_share_icons( $content ) {
	$content = '<h3>Share this post on:</h3>
		<ul class="share-icons">
		<li class="facebook"><a href="#facebook">Facebook</a></li>
		<li class="twitter"><a href="#twitter">Twitter</a></li>
		</ul>';

	return $content;
}


Add Share Icons to Content

Before:
 

After:


in_the_loop  &  is_main_query


add_filter( 'the_content', 'custom_share_icons' );

function custom_share_icons( $content ) {

	if ( in_the_loop() && is_main_query() )
	{
			$content = '<h3>Share this post on:</h3>				<ul class="share-icons">			<li class="facebook"><a href="#facebook">Facebook</a></li>				<li class="twitter"><a href="#twitter">Twitter</a></li>				</ul>';	}

	return $content;
}

Actions


Never return data

Trigger events.
Tell the code, "Whenever you do this, also run this function."




Enqueue a Script






Enqueue a Script

 

add_action( 'wp_enqueue_scripts', 'custom_scripts', 999 );

function custom_scripts()
{
     wp_register_script( 'theme-js', get_stylesheet_directory_uri().'/scripts.js' );
     wp_enqueue_script( 'theme-js' );
}



Enqueue a Script

Before:

After:

Run a Plugin Function in Your Theme

In your plugin:
add_action( 'plugin_name/page_navi', 'custom_page_navi', 10, 2 );
function custom_page_navi()
{
	global $wp_query;

	$bignum = 999999999;
	if ( $wp_query->max_num_pages <= 1 ) return;

	echo '<nav class="pagination">';
	echo paginate_links( array(
		'base'         => str_replace( $bignum, '%#%', esc_url( get_pagenum_link($bignum) ) ),
		'format'       => '',
		'current'      => max( 1, get_query_var('paged') ),
		'total'        => $wp_query->max_num_pages,
		'prev_text'    => '&larr;',
		'next_text'    => '&rarr;',
		'type'         => 'list',
		'end_size'     => 3,
		'mid_size'     => 3
	) );
	echo '</nav>';
}

Run a Plugin Function in Your Theme


In the theme:

<?php do_action( 'plugin_name/page_navi' ); ?>





Pay Attention to Load Order


 

Greatest Hits

'init' vs 'wp'

init
add_action( 'init', 'custom_test_init' );
function custom_test_init() {
	print_r($GLOBALS['post']);
}
does nothing

wp
add_action( 'wp', 'custom_test_init' );
function custom_test_init() {
	print_r($GLOBALS['post']);
}
outputs the current post





Load Order is Important

Ajax

The WordPress Way

The Link

Default excerpt with [...]:

Our excerpt with link:


The Link


add_filter( 'excerpt_more', 'aelc_excerpt_more' );
function aelc_excerpt_more( $more )
{
	global $post;

	$output  = "&hellip;";
	$output .= '<br />';
	$output .= '<a class="excerpt-read-more" data-post_id="'. $post->ID .'" href="'. get_permalink($post->ID) . '" title="Read ' . get_the_title($post->ID).'">';
	$output .= "Read more";
	$output .= '</a>';

	return $output;
}

Static "[...]" becomes "Read more"

Enqueue Scripts


add_action( 'wp_enqueue_scripts', 'aelc_enqueue_scripts', 999 );
function aelc_enqueue_scripts()
{
	wp_register_script( 'aelc-js', plugins_url( 'assets/js/scripts.js', __FILE__ ), array( 'jquery' ), '', true );

	$args = array(
		'ajaxurl' => admin_url( 'admin-ajax.php' ),		'nonce'   => wp_create_nonce( 'aelc_excerpt_more' ),	);
	wp_localize_script( 'aelc-js', 'aelc', $args );

	wp_enqueue_script( 'aelc-js' );
}

aelc_excerpt_more = nonce action



Localize


$args = array(
		'ajaxurl' => admin_url( 'admin-ajax.php' ),
		'nonce'   => wp_create_nonce( 'aelc_excerpt_more' ),
);
wp_localize_script( 'aelc-js', 'aelc', $args );


Ajax Actions


wp_ajax_(action_name)




prefix logged-in users



wp_ajax_nopriv_(action_name)
prefix for non-logged-in users

Your action name


The Handler

add_action( 'wp_ajax_aelc_excerpt_more', 'aelc_load_content' );
add_action( 'wp_ajax_nopriv_aelc_excerpt_more', 'aelc_load_content' );

function aelc_load_content()
{
	if ( empty($_POST['post_id']) || empty($_POST['nonce']) ) return;
	if (! wp_verify_nonce($_POST['nonce'], 'aelc_excerpt_more')) return;

	$post = get_post($_POST['post_id']);
	echo apply_filters( 'the_content', $post->post_content );
	die;
}

Gets the content for the requested post and sends it script.

Add the Ajax actions




add_action( 'wp_ajax_aelc_excerpt_more', 'aelc_load_content' );





The action name used in Javascript


add_action( 'wp_ajax_nopriv_aelc_excerpt_more', 'aelc_load_content' );


The action name used in Javascript



The function name


Make sure the expected variables have been supplied






if ( empty($_POST['post_id']) || empty($_POST['nonce']) ) return;

Verify the nonce






if (! wp_verify_nonce($_POST['nonce'], 'aelc_excerpt_more') ) return;


Name of the nonce action


Get the post, apply filters, echo to javascript





$post = get_post($_POST['post_id']);

echo apply_filters( 'the_content', $post->post_content );


die()


Always exit() or die() at the end of your Ajax Handler


admin-ajax.php:
 die( '0' );


Keep that from happening

jQuery

jQuery(document).ready(function($) {

$('.excerpt-read-more').on('click', function(e) {
		e.preventDefault();

		var $this = $(this),
			$content = $this.closest('p');

		$.ajax({
			url:      theme.ajaxurl,			type:     'post',			async:    true,			cache:    false,			dataType: 'html',			data: {				'action' : 'custom_excerpt_more',				'post_id' : $(this).attr('data-post_id'),				'nonce' : theme.nonce,			},

			success: function( response )
			{
				if ( response )				{						$content.fadeOut('400', function(){							$content				.after( response )									.remove();						});				}			}
		});
});

});

Add a custom onClick event to the link





$('.excerpt-read-more').on('click', function(e) {


And stop the default action

e.preventDefault();

The data we are passing to PHP




PHP handler action name (without the "wp_ajax_" part

'action'  : 'aelc_excerpt_more',

The post id from the link html

'post_id' : $this.data('post_id'),

The nonce

'nonce'   : aelc.nonce,


Results



After Click






Next Steps: Jump In

How to Get Started


Google

Search core and plugin code

hookr.io



Thank You!


http://codex.wordpress.org/Plugin_API

http://codex.wordpress.org/Plugin_API/Action_Reference

http://codex.wordpress.org/Plugin_API/Filter_Reference

http://codex.wordpress.org/AJAX_in_Plugins



live.jcow.com/hooks
(http://slides.com/jupitercow/wp-hooks/)

https://bitbucket.org/jupitercow/ajax-excerpt-load-content
Made with Slides.com