Working with hooks and filters – basics and syntax

This is the documentation for the Thematic Theme. At the moment it is very bare bones but will grow with time. It ‘s community editable so if you have an account and feel you can contribute, please help us expand the docs.

Hooks and filters are two programming techniques that enable you to modify style, function, and content of your site from your child theme.

Action Hooks

An action hook is a placeholder at a given spot in the WordPress or Thematic code where you can insert a function.  Thematic is well-designed so that you have ample opportunity to add your special functions wherever you wish in the code.  Here’s an example using Thematics’s header.


<?php
// Filter provided for altering output of the header opening element
echo ( apply_filters( 'thematic_open_header',  '<div id="header">' ) );
?>

<?php
// Action hook creating the theme header
thematic_header();
?>

<?php
// Filter provided for altering output of the header closing element
echo ( apply_filters( 'thematic_close_header', '</div><!-- #header-->' ) );

Wait, you say, this looks nothing like an html header.  True.  But there is a function. called “thematic_header()”.  This is an action hook (note: explain how to recognize action hooks).  If you open the file “header-extensions.php” (found in the extensions folder), you’ll find the following (paraphrased for this example):


function thematic_brandingopen() {
echo "\t<div id=\"branding\">\n";
}

add_action( 'thematic_header','thematic_brandingopen',1 );

...

function thematic_blogtitle() {
?>

<div id="blog-title"><span><a href="<?php echo home_url() ?>/" title="<?php bloginfo('name') ?>" rel="home"><?php bloginfo('name') ?></a></span></div>

<?php
}

add_action('thematic_header','thematic_blogtitle',3);

Look at the function “thematic_brandingopen(). In this code, you can see that it outputs <div id=”branding”>. THIS looks like html.
Shortly below that, you’ll see “add_action(‘thematic_header’,’thematic_brandingopen’,1)”

This simple line takes the function that creates the <div id=”branding”> and adds it to the action hook.

Following that logic, you can see that <div id=”blog-title”> … </div> is also added to thematic_header.

Here’s the power of this design (part 1):

Anything you want to add to the header, you can do it from your own child theme function.php file by using this same technique, without ever having to touch Thematic.


add_action('thematic_header','jim_smith',2)

function jim_smith(){

echo ' <p>My name is Jim Smith</p>';//add a paragraph to the header

}

With these few lines of code, I have added my own custom function into the header.  It will be inserted between the branding open and the blog title.   I know this because the branding open has a sequence number of “1” and the blog title has a sequence number of “3” and so I simply had to add my function with a sequence number of “2”.  (That would be the power of Thematic’s design (part deux)).

(next: filters…)

Filter Hooks

Whereas an Action Hook gives you a point in the code where you can insert a function, a Filter Hook gives you the opportunity to edit a given output  within the code.  (I use “output” lightly because I can’t think of a better word.)  The output isn’t necessarily going to the screen; it can be a variable, a setting, a string.  Here’s a few examples to illustrate:


*/
function thematic_content_init() {
global $thematic_content_length;

$content = '';
$thematic_content_length = '';

if (is_home() || is_front_page()) {
$content = 'full';
} elseif (is_single()) {
$content = 'full';
} elseif (is_tag()) {
$content = 'excerpt';
} elseif (is_search()) {
$content = 'excerpt';
} elseif (is_category()) {
$content = 'excerpt';
} elseif (is_author()) {
$content = 'excerpt';
} elseif (is_archive()) {
$content = 'excerpt';
}

$thematic_content_length = apply_filters('thematic_content', $content);

In this example, Thematic is deciding whether to use the full post or just the excerpt.  The function being used will set the global variable $thematic_content_length to a string of either “full” or “excerpt.”  Before setting it, however, Thematic gives you an opportunity to modify the variable however you wish by creating a filter called ‘thematic_content.’

To take advantage of this opportunity, you will create a function that outputs whatever you wish $thematic_content_length to be and then add your function to the filter.  You do it like this:


add_filter('thematic_content','sample-filter-version-a');

function sample-filter-version-a($original){

$my_value = $original;

return $my_value;

}

In version a above, we don’t actually do anything; this example just illustrates the mechanics.  You:

  1. receive the original value as an input to your function
  2. modify it however you wish
  3. return your value in place of the original

In version 2, we completely override the value with our own.


add_filter('thematic_content','sample-filter-version-2');

function sample-filter-version-2($original){

$my_value = "full";

return $my_value;

}

This example will take the original (either “full” or “excerpt”) and overwrite it with “full” so that each one of the pages will display the full excerpt.

For a third example, let’s look at a situation where you like the standard functionality EXCEPT you would rather display the full content on author pages.  In this situation, we’ll combine a little of what we’ve done in the first two examples

add_filter('thematic_content','sample-filter-version-pi');

function sample-filter-version-pi($original){

   $my_value = $original;

   if( is_author() ){

      $my_value = "full";

   }

return $my_value;

}

Here’s a step-by-step explanation:

  1. we connect our function to the filter
  2. we receive $original into our function
  3. we set the default return value to be whatever the original value was
  4. we create a conditional that will modify the return value to be “full” only when our condition is met
  5. we return our value

By going through these steps, we ensure that the theme will operate as normal except in the cases where we want to create an exception.  It’s a clean way to customize only the aspects of the parent theme that you want modified while letting a battle-hardened theme otherwise do what it does best.