Modify a child theme’s functionality using action hooks

When working with a WordPress child theme, you may need to change the functionality of the theme without touching any code in the parent theme. This could be as simple as removing functionality, moving a function to a different hook, or adding your own custom functionality.

In this tutorial we’re going to move a function to a different hook. One such example would be to move the navigation (assuming it’s added via a hook) from above the header to below the header, changing the overall appearance of our theme.

Most themes have custom hooks spread throughout the theme that were added with the do_action function. Having these custom hooks available to us in our themes make it very easy to make some fast customizations.

remove_action() & add_action()

We’ll use WordPress’ remove_action and add_action functions, first removing the parent theme’s navigation, and then adding it back into our child theme at the new location.

If you find the original action hook in the parent theme that added the functionality, it might look something like this:

add_action( 'my_theme_before_header', 'my_theme_do_nav' );

In the example above we can see there is a function called my_theme_do_nav. This function might include the code to retrieve the WordPress menu and some other custom code.

This function is then being loaded on a custom hook called my_theme_before_header. This custom hook would naturally appear in the parent theme, somewhere before the header.

Removing the navigation

By copying and pasting the same code into the child theme’s functions.php, replacing add_action with remove_action, we can remove the entire navigation. The first and second parameters must match exactly.

remove_action( 'my_theme_before_header', 'my_theme_do_nav' );

Adding the navigation back in

Now that the navigation has been removed, we’ll add it back in, but after the header. All we need to do is change the hook in the first parameter to reflect our new location. Let’s assume there’s a custom hook in the parent theme called my_theme_after_header.

add_action( 'my_theme_after_header', 'my_theme_do_nav' );

Child functions are loaded before the parent’s

Stopping there would likely yield no results. One important thing to note is that the child theme’s functions are loaded before the parent theme’s functions. We need to create a new function and load it on to a suitable action hook, so that our remove_action and add_action are executed properly.

The template_redirect() action hook is one such suitable hook. The WordPress Codex states that it is run before the determination of the template file to be used to display the requested page. By using template_redirect, we can be sure our actions will overwrite the parent theme’s actions:

function my_theme_shift_navigation() {

    remove_action( 'my_theme_before_header', 'my_theme_do_nav' );
    add_action( 'my_theme_after_header', 'my_theme_do_nav' );

}
add_action( 'template_redirect', 'my_theme_shift_navigation' );

And that’s it. The simple function above first removes the navigation from the parent theme, then adds it back in at a new location, all without touching the parent theme’s code.

How to add Tracking Code to a WordPress Theme

A common task that all WordPress users need to do is insert some form of tracking code into their WordPress theme to track their visitors. This is achieved by writing some very simple code and placing it in the theme’s functions.php file.

In this example we’re going to use Google Analytics’ tracking code but it really doesn’t matter what service you use, just as long as you use the correct code provided, and make sure you are inserting it into the correct place within your HTML markup.

Creating the function

Shown below is the absolute minimum we’ll need to create our function.

function my_theme_name_tracking_code() { ?>

// tracking code will be placed here

<?php }

All it needs is the actual tracking code as noted by the comment. Note how the function name has been prefixed with the name of the theme to lessen the chances of a conflicting function name.

Adding the tracking code

Your tracking code will vary, but generally it will look something like this:

function my_theme_name_tracking_code() { ?>

    <script type="text/javascript">

	  var _gaq = _gaq || [];
	  _gaq.push(['_setAccount', 'UA-XXXXXXXX-X']);
	  _gaq.push(['_setDomainName', 'mydomain.com']);
	  _gaq.push(['_trackPageview']);

	  (function() {
	    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
	    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
	    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
	  })();

    </script>

<?php }

Hooking the function to an action

Now that we have our function, we need to tell WordPress to actually load it somewhere. We do this by hooking the function to an action hook.

Because Google recommends placing their analytics tracking code just before the closing </head> tag, we’ll be using the wp_head action hook. As mentioned in the Codex, the wp_head action hook is triggered within the section of the user’s template by the wp_head() function.

Now that we know where to load it, we need to use the add_action() function, passing 3 parameters to it as seen in the example below.

add_action( 'wp_head', 'my_theme_name_tracking_code', 20 );

The first parameter is the wp_head action hook.

The second parameter is the name of our function that we created earlier. Double check that the function name matches exactly, or it won’t work.

And finally, the 3rd parameter is the priority. In our example we’re using a priority of 20 to make sure it’s loaded after other functions that may also be using the wp_head action hook. Don’t be afraid to increase this number if your tracking code isn’t quite loading before the closing </head> tag. You can check where it’s loading by viewing the HTML source in your browser.

Putting it all together

This is what the completed function should look like. Don’t forget to replace the tracking code with your own.

function my_theme_name_tracking_code() { ?>

    <script type="text/javascript">

	  var _gaq = _gaq || [];
	  _gaq.push(['_setAccount', 'UA-XXXXXXXX-X']);
	  _gaq.push(['_setDomainName', 'mydomain.com']);
	  _gaq.push(['_trackPageview']);

	  (function() {
	    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
	    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
	    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
	  })();

    </script>

<?php }
add_action( 'wp_head', 'my_theme_name_tracking_code', 20 );