Once again, I encourage anyone joining in the middle of this series to start at the beginning as each article builds on previous information. The tag archive for the Genesis Explained series is conveniently setup to present the articles in the order they were written. This article begins a new sub series focused on the Filters within Genesis. Like the sub series on Actions, this first article is intended to explain the actual functions, since the functions themselves are not significantly different than the action functions, this tutorial will be shorter and heavily reference the Genesis Explained – Actions work.
Enough of the boring introductory material, let’s dig in.
What are filters?
Filters are functions that change other functions. I call them “voodoo” because they feel like some kind of magic to me, even though I know how they work and use them more and more frequently. in fact, now that I have teh opportunity to make direct recommendations to the Genesis Development, I find I am suggesting additional filters be added since they are often more efficient and convenient than actions.
To use the Lego analogy again, if an action says “add this set of blocks to this location” a filter says “before you do that, change this one piece out, then have a nice day.” With an action you have to provide an instruction to remove the block of code, then another instruction to add a new block of code, plus provide the newly altered code. That is a lot of work when you can say “I just want to change this one thing.
Of course, I’m sure you can see why this feels like voodoo, or cheating. It’s too easy when you think of it like that. Things shouldn’t be that easy, so there has to be a catch. Well, there is. You can only use filters to change something that has filters applied to it.
Apply Filters
A mistake a lot of people make is thinking you can filter any function. This happens because often the “filter name” matches the function. Developers do this because we are lazy and it is much easier to remember it that way and less typing. Someone on the inside can tell if they can use a filter by looking at the function, and now you can too, because I’m breaking open the big secret. Look for the apply_filters() function. This has a couple of important parts.
apply_filters( $tag, $value, $var1, $var2, ... );
The $tag is the filter name. We’ll talk about it in more detail later, in fact we’ll talk about all of these more later. The $value is the value that can be edited or replaced. The $var1/2/… are variables that can be used to get additional information, this is useful for conditional statements, if( ‘blue’ == $var1 ) return ‘color’;, or for str_replace() searches and plenty of other helpful uses. You can’t directly change the $var content though.
Short version is, if you find this function on a value you want to change, then you get a free short cut instead of having tow ork with actions. Just so you know, there are a ton of filters in WordPress, not just Genesis. Genesis uses some of the WordPress filters too, so lets talk about working with the filters.
>Add Filter
The actual function, add_filter(), has the exact same parts as add_action, which I previously explained, if you didn’t look at the Genesis Explained – Actions article I referenced earlier, let me give you a quick refresher, for more detail go look at the article. First you can have an instruction to add or remove the filter, then you have the filter name to work with. Next is the function name (call back function) that will be editing the value followed by the priority, the order it runs the filter relative to other filters, and the number of arguments that the function will use.
That last part needs a bit more explanation, so lets look at a generic filter.
add_action( 'hook', 'hook_function' ); /**generic function with a filter*/ function hook_function() { echo apply_filters( 'hook_filter', 'foo', 'var 1', 'var 2', 'var 3' ); } add_filter( 'hook_filter', 'filter_function', 10, 2 ); /**Changes the value of hook_filter if $var1 == 'var 1' */ function filter_function( $value, $var1 ){ if( 'var 1' == $var1 ) return 'bar'; return $value; }
Now some explanation. You should already be familiar with the action, it is loading the code onto the “hook” hook. All it does is put “foo” on the screen where that hook is at. Before it can do that though it applies any filters. In other words it looks for any changes to the instructions. The add_filter line is adding a filter to that. I have given it a function to run, bot told it I only want 2 arguments, so it will get the $value and the first $var. If I had told it I want 3 arguments it would use the $value and the first two $vars. So if I need the 3rd $var I have to tell it I want 4 arguments, even if I don’t use the first two $vars in my code, they have to have a value so the one I want will be loaded for me to get that value.
In the guts of this I have it check to see if the $var matches a specific string, which it will since I’m not writing a dynamic function that might have difference values in different scenarios, then telling it to return “bar.” This replaces the $value (foo) with “bar” so that will print instead.
This is a very important distinction. The final value must always be returned, not echoed. I have been frustrated time and time again with developers writing plugins who will filter the_content and echo their edited content instead of returning it. If you don’t return the value then all other filters have nothing to work with. That is bad programing, and just plain rude. Always return the $value. By the way, the last line also returns the $value. This is so that the unedited value gets returned. A better way to write this is
add_filter( 'hook_filter', 'filter_function', 10, 2 ); /**Changes the value of hook_filter if $var1 == 'var 1' */ function filter_function( $value, $var1 ){ if( 'var 1' != $var1 ) return $value; return 'bar'; }
This is better because if I am editing $value when the condition isn’t right I might accidentally return an edited version when I don’t want to, this way the $value is sent back before anything else is done to it. Both will work and give the same results, but making a habit of returning your $value in the outset will make it easier to remember to put it back when you are done with it, since you put it back in the beginning if you don’t need it.
Remove Filter
The remove_filter() function is identical in use to the remove_action() function. It needs to match the add_filter() exactly and has to come after the filter was added.
If you feel a bit like you’ve just read some ancient mystical tome, it’s ok I kinda feel like I just wrote one. The next part will use some specific examples from Genesis to show how to make changes without using actions, just for fun I’ll show how to make the change with actions first to demonstrate how much more efficient filters are.
Is there any part of filters that you are struggling with? What can I explain in more detail?
By the way, if you are enjoying the series you should subscribe to my feed. Alternately you can get the feed in your email using the form in the sidebar.
Boomboom says
Great series. I want the next redesign to one of my sites using a proper Child Theme I code myself. And I think your tutorial series is going to help me to do that. Honestly this intro to Filters has not really sunk in. So I will look forward to the next one 🙂
nickthegeek says
Filters took a very long time for me. I was using them for months before it really clicked, and even now it feels like magic. The next article uses real examples from Genesis, that is the kind of thing that helps me, so I hope it helps you too.
Jordan Wilcken says
These are very helpful. If I might offer one small piece of constructive criticism – have someone edit these. I don’t really care about grammar or spelling errors. I’m talking about sentences that, if rewritten, could be understood much more quickly. It’s a small thing, really. These are very helpful.
nickthegeek says
Thanks for the recommendation. I am going through editing for an ebook form of this series. IF you have any specific changes in mind I am happy to listen. Before I release the ebook I will be asking several people to help in the final edit.
Sudhanshu says
I want to have posts of a certain category be accessible via a menu link to that category tag, and not show up on the main blog post.
I’ve found the category ID that I’m supposed to put in the “Exclude category” section of the settings (Genesis -> Theme Settings) and it still won’t work for some reason. Not sure if I’m doing something wrong.
Within the URL it says “category&tag_ID=573”
I would put the 573 in the space to exclude, correct? or would I put the slug name? It seems to have posted on the main page as well.
nickthegeek says
This is actually kinda different. You need to modify the WP query and there are several ways to do that but only one way that will not give you a 404 error at some point.
http://billerickson.net/customize-the-wordpress-query/