In the previous post in this series we talked about the basics of PHP and how functions are put together. Today we’re going to build on that and talk about how to use Genesis hooks to manipulate theme elements.
Have you ever wondered how the Genesis theme framework knows how to call all that code from your child theme files in the right order?
Genesis uses a WordPress convention called hooks to “hook” into the code at the desired spot just like WordPress as a whole does. (Genesis also uses something called filters too, which we’ll address in the next post in this series.)
One Big Program
Really when you get right down to it your WordPress website is just one big long program. Everything including your core WordPress installations, all of your plugins, your Genesis framework and your child theme are really all just one big long program. It executes in the order that is laid out in the WordPress core files.
And hooks are one of the powerful ways we can modify the presentation of our website.
That’s how there can be so many WordPress websites and many of them look and function radically different from one another on the public facing outside.
WordPress Hooks Defined
We probably should look at what a hook is before we get down to the specifics of using them in the Genesis framework.
Here’s a working definition:
In WordPress, a hook is a PHP function that serves as an anchor point to allow other code to execute at that specific spot in the code.
You can think of it sort of like a hook on a wall. If that wall is your main program, the hook is where you’re going to hang your function so it does what you want where you want it to do it.
It turns out this is an incredibly powerful concept. Personally I think it is one of the big factors that has made the use of WordPress grow so fast in recent years. (Today WordPress powers 21.2% of the internet’s websites, up from 17.4% a year ago.)
WordPress has a do_action function built into it that developers can use in their code. This allows other folks such as you and I to come in behind them and alter their code at that point.
Hooks in Genesis
If you look at the code in the various core Genesis theme framework files you will see do_action functions scattered throughout the code.
For example, if you look in the /genesis/header.php file today you will see this line of code:
do_action( 'genesis_after_header' );
This hook is commonly used to manipulate the main navigation menu in Genesis.
Note: Since you are interested in Genesis theme customization you know that you should never (never, never ever, I mean never!) modify your Genesis files directly. All of your customizations go in your child theme files.
Genesis has hooks like this scattered throughout the framework. To find the right hook to do what you want you can either look at the handy Genesis Hook Reference that StudioPress provides, or you can look through the code for those do_action functions.
WordPress also has a couple other functions built in that allow us to tap into those hooks. These are the add_action and the remove_action functions. In their basic format they look like this according to the WordPress Codex:
add_action( $hook, $function_to_add ); remove_action( $hook, $function_to_remove );
The $hook is the bit inside the specific do_action function that identifies the hook we want to tap into. In our example above that part would be ‘genesis_after_header’ as our hook.
The $function_to_add is the function in our child theme that we want to execute at that point.
In the remove_action function we can make functions in the main Genesis framework not execute at that hook by noting them in the $function_to_remove spot.
This makes for a powerful combination. For example, say we want to move the main navigation of our Genesis child theme from its usual position below the header to above it.
When I first started messing with themes in WordPress doing something like that meant I had to copy the header.php file to my child theme and make my changes to that file. (Actually I started before WordPress even had the ability to do child themes. But never mind that. Just know that WordPress is constantly improving and things have gotten much better and easier to use over the years.)
The trouble with doing things via copying files wholesale is that if the developer comes out with updates to the parent theme that alter the header.php file I’m stuck. I can either ignore those updates or I have to manually incorporate them into my child theme’s files.
If I only have one site to manage that might be workable. But what if I’ve got a hundred or more client sites to deal with?
Instead of doing that, I can use hooks in Genesis and make that same change to move my main navigation with just two lines of code in my child theme’s functions.php file like this:
remove_action( 'genesis_after_header', 'genesis_do_nav' ); add_action( 'genesis_before_header', 'genesis_do_nav' );
Do you see what we did there?
The remove_action function tells the site not to execute the Genesis main navigation at the ‘genesis_after_header’ hook. And the add_action tells the site to put the main navigation before the header where the ‘genesis_before_header’ hook is found.
When we extrapolate that out we have an incredibly powerful combination of tools to customize our Genesis themes.
Benefits of Hooks
Obviously it is a whole lot easier to just add a couple lines of code to our functions.php file rather than copying over the entire contents of our theme files and editing them. But there are some other benefits to using hooks as well.
For one thing we already mentioned that hooks make it far easier to get the full benefit from upgrading our parent theme because we’ve moved the minimum amount of code necessary into our child themes.
This is also a relatively crash proof way to modify things in our themes. If you reference a function that doesn’t exist or the parent theme developer changes or removes a hook, your site will not crash. WordPress just skips over add or remove actions that reference invalid hooks or functions.
Your site may not look the way you want it too. But at least it won’t crash completely if something changes.
Another benefit to using hooks is that it streamlines your code because it allows you reuse functions whenever you want to repeat the same functionality. So multiple add_action statements can reference the same function using different hooks.
So for example, say you had a function to display an advertising block in your theme. Rather than duplicating that function in various theme template files you can simply list it once in your functions.php file and have multiple add_action statements that call your function via hooks to display your ads where you want them.
That’s pretty powerful. And it greatly simplifies the process for making your customization tweaks too, once you get your head around it.
If you ever need to make a change to your ad block you only have to change one function in your functions.php file and it applies your change to all of your ad blocks at once. That’s a whole lot easier than hunting through your theme files for every instance of of your ad block code and editing each of them.
You should know about what is called priority when you are using hooks. One challenge when working with hooks is that by default they execute in the order that they appear in the overall WordPress code. Keep in mind that our WordPress site is just one big long program that includes our core WordPress files, all of our active plugins and the theme/child theme files that are active on our site.
Sometimes it can be a challenge to get things to appear in the order we want when there are multiple functions hanging on the same Genesis hook in our theme. I run into this a fair amount when working with plugins that are used to add a bit of functionality. WordPress loads plugins before themes so any action called in a plugin will naturally appear before that same action is called in your theme.
Fortunately you can designate a priority in your action statements.
The priority is just an optional number added to the action statement to determine the order in which the function associate with that action is called in relation to other functions using that same hook. So adding a priority to our previous example it would look like this:
remove_action( 'genesis_after_header', 'genesis_do_nav', 10 ); add_action( 'genesis_before_header', 'genesis_do_nav', 10 );
In this case 10 is the priority. We can adjust that number 10 up or down to change the order in which our function gets called. Lower numbers are called before higher numbers. The default priority is 10 so setting it to 10 is kind of pointless. That’s what it will be when we leave off the priority anyway.
Understanding priority is important when you are customizing your Genesis themes because with the new HTML5 loop in Genesis 2.0+ the developers have included fewer hooks than we had available previously. In doing so they have simplified things to make it easier for us to remember which hooks to use.
However this also means we need to tap into the hook priority more to get our functions’ output positioned the way we want them.
Priority also comes into play when removing actions too. You cannot remove an action before it is added. So if the add_action statement for the function we want to remove has, say a priority of 15, if we try to use a remove_action statement with the default priority of 10 it won’t work. Instead we’ll need to use a priority of 15 or higher to deactivate that function in our theme.
The best thing to do is to look at the code and see what priority you need to use. But sometimes it just isn’t practical to actually put our eyes on the code in question. In those cases a little trial and error with priority usually will get us to the right place.
When it comes to Genesis theme customization hooks are a tremendously powerful tool we should keep handy in our tool belt. They give us the ability to manipulate and structure our theme the way we want to achieve great looking designs.
This is the tenth in our series of articles on Best Practices for Genesis Theme Customization.
Brett Bumeter says
One of the only (best too) descriptions on priority that I have found.
I was troubleshooting something last night. I ‘thought’ I understood priority but only intuitively. Hadn’t seen anything written on it anywhere. I had some other issue and couldn’t be certain if my use of priority was confounding things or if I had a different issue.
I was using it correctly, but couldn’t be certain until I found your article. that helped me resolve the other issue.
Now I just need to get some bandages after banging my head against a wall most of the night….