WordPress Filters Fundamentals

Ok, so you’ve read my previous articles on PHP basics and how to use WordPress action hooks. Now you want to play with the big boys and girls and try your hand at filters. Just a reminder that you are still essentially learning a new language. Be patient with yourself. It took me close to a year to really understand filters, so if I can help you learn it quicker than that I’ll consider this a successful article.

In my discussion of hooks and functions I have described the system of hooks in WordPress as being similar to a parking lot. The hooks are like spaces, the cars are like functions that can be parked anywhere and can be moved around. To expound on this metaphor, (or to beat it to death) I think a filter is similar to changing something about the car while leaving it in the same place. A filter is like a magic function box that takes a value in ( remember I talked about parameters in by Basics tutorial ) do something with it and send it back. So you have a red Porsche on the lot, send it to a filter and it might become a blue Porsche. Or a black pickup truck. Whatever. But it will still be parked in the back, 2 spots from the end.

When browsing WordPress core, themes and plugins, you will be alerted to the availability of a filter by the appearance of the apply_filters() function. In generic terms it will look like so:


apply_filters( 'name_of_target_filter', $variable_getting_filtered, #priority, $other_arg );

It might look like:


return apply_filters( 'name_of_target_filter', $variable_getting_filtered, #priority, $other_arg );

or:


echo apply_filters( 'name_of_target_filter', $variable_getting_filtered, #priority, $other_arg );

or even:


$variable_getting_filtered = apply_filters( 'name_of_target_filter', $variable_getting_filtered, #priority, $other_arg );

Parameters for the Filters

But I repeat, the big tip off is the apply_filters() function. The apply_filters() function can take an unlimited number of parameters but only the first two are required.

1. The first is the name of the filter. I was very confused early on because the Thematic framework tended to name the filters the same thing as the functions that contained them. And then in the one instance where they were difference, I couldn’t get my filter to work for anything. I swore and through things, cried and shaved a few days off my life from the stress. Turns out their sharing names was a convenience factor that makes a lot more sense to me now. So, just remember that first parameter is the filter’s name.

2. This is an important one, because this parameter is the variable that your function will receive. This is the value we’re going to change. This is the red car that we will turn blue.

3. This it the priority. Just like with adding functions to hooks, this controls the order that filter functions will be applied should there be more than one. The default is 10, so if you need your filter to run before that you’d use a lower number. This is rare, and usually you need to run your filters after others, so you’d want to use a higher number. In fact, until you are sure that you are conflicting with another function you can pretty much just leave it at 10.

4+. These are other variables that might give you some useful information for manipulating the variable getting filtered. Remember we talked about scope in the PHP Basics. Instead of declaring these globally and hoping they arrive intact, WordPress will send your filtered variable along with some friends.

A Filter with Training Wheels

In super generic terms let’s take a look at the basic set up for filtering.


function sample_filter_function( $in_from_function, $other_arg ) {

$out_to_function = $in_from_function . " add some bacon here!";

return $out_to_function;

}

add_filter('name_of_target_filter','sample_filter_function', #priority, 2 );

The structure is almost exactly the same as that for add_action(). In reality, we are adding an action, just of a slightly different type: one that modifies a specific variable’s value. One thing to note here, is the number 2. This is the number of parameters that you are passing into the function. You’ll always pass 1 variable ( ie. the variable that you are filtering) and in this case you wouldn’t even need to declare it. That’s the default value, just as 10 is the default value for #priority. However, some filters provide access to other variables (like our fake $other_arg), and if you want to use them in your filter function then you have to name them inside the parentheses and then write the correct number at the end of the add_filter() statement.

If you have 2 parameters in the function, but don’t have the number 2 at the end of add_filter() you will get White Screen of Death. If you have the number 2, but don’t declare two parameters, guess what, you will also get WSOD. So make sure your parameters match up.

And you absolutely, must, sans doute, return a value. If you do not, that is essentially the same as returning a null string. If you echo something here, it will likely not appear where you expect it, so don’t. RETURN, RETURN, RETURN. Remember in my PHP basics I talked about two functions playing catch. The return statement, is you throwing your modified version of the variable back to the apply_filters() function so that WordPress can continue on its merry way, but using your value now.

You’re a Real Boy Now, Pinnochio. A Real Filter

If you’ve managed to read all this, then… well… Bless you. I want to end on a real filter that you can drop into your theme’s functions.php and actually see a working result.


function kia_the_title( $title ) {

$title .= " BACON!";

return $title;

}

add_filter('the_title','kia_the_title' );

Not too shockingly I am using Bacon in my testing code. If this bothers you…. well, its just code. WordPress has a filter called the_title() that lets you modify the title of every post! As written above it will literally add BACON everywhere the_title() is called. Bacon everywhere, all the time has its appeal, sure, but I will whet your appetite with some neato WordPress conditional logic that will only add Bacon to the titles in the main loop, and only on the front-end.


function kia_the_title( $title ) {

if ( ! is_admin() && is_main_loop() ) {

$title .= " BACON!";

}

return $title;

}

add_filter('the_title','kia_the_title' );

Conclusion

I hope that helps things make more sense. Remember, THIS IS HARD!! Do not be discouraged if you don’t get it right away. I cannot provide specific support in the comments ( Hire Me, instead! ) but do let me know if there are places where I could be more clear.

Posted in Understanding the Basics | 6 Responses

Nav Menu Roles Plugin

Over the weekend I was working on a project and my client needed to be able to hide certain menu links from non-logged in users.  In the past I have just created 2 menus, one for logged in users, and another for logged out users.  Not the most convenient thing ever, but simple enough.  However, since this was at least the second, and possibly the third time this has come up in various projects I decided to dig further.

Adding fields to the menu item back-end

This was the trickiest part really, because there aren’t any action hooks in this part of the code.  I have requested one with the following Trac Ticket, but until that gets added to we have to do it in a slightly less efficient way.

Thanks to this WordPress Answer I found that the whole menu item form is created by the Walker_Nav_Menu_Edit Walker, but that tucked away in the code is the ability to filter this and send a new Walker via the wp_edit_nav_menu_walker filter.  Actually this answer got me about 80% of the way there so I can hardly claim to be clever or original.  I just packaged it up.  Couples with this Answer about front-end menu Walkers, the first beta draft of my plugin was born.  At this point it really only handled different roles.

Nav Menu Roles screenshot

New options for menu settings allow you to customize who can view particular menu items

Before it was even added to the WordPress repository, Pippin Williamson did a quick video review, so I guess I am not the only person who has needed this ability from WordPress.  Pippin also had the cool idea to add the ability to show an item to all logged-in users, or all logged-out users, so the video screenshots will look different from the end result of version 1.0.  I think this was a cool addition, so thanks Pippin for the idea and for helping me work on it.

Basic Usage

Install and activate the plugin like normal. Create a custom menu and add items to it just like you usually would. You will now see the extra fields shown in the screenshot. From here you select to show the item to all logged in users, all logged out users… or to customize by role. If you chose customize by role, then you can use the checkboxes to determine which roles should be allowed to see this particular menu item. If you choose customize by role and do not check any roles, then the item will show to everyone just like it used to. There isn’t any more to it than that. It should be pretty straight-forward.

Download

Now available in the WordPress Repo.

Also available via my Github repo. Please report any issues at Github.  Download the zipball. It is translation ready, so if you want to send me some translations (there are only about 5 strings) I’d be happy to add them.

Enjoy! And let me know what you think in the comments.

Posted in Plugins | Tagged , | 18 Responses

Absolute PHP Basics for WordPress Newbs

“I’m just a designer. I’m comfortable with CSS but PHP scares me.” Yeah ok, well first off, if you are a designer…. instead of banging your head into a wall to learn a coding language, why not hire a developer? Some of my best clients have been designers. It is kind of a win, win. I get to work on pretty sites and you get to do more designing and less stressing. Send me an email and let’s see if I can help.

But if you insist on trying to defy your right-brained designery nature and become more left-brained here are a couple of points that I think will help you as you try to learn both PHP and its sub-dialect of WordPress.

Function Function What’s Your Function

Functions do things. Ever learn about functions in middle school math class? Magic black-boxes where numbers go and come out as something else? Well it is pretty much the same. Let’s start with the simplest function possible, a nice spin off on the classic “hello world”.

function hello_bacon(){
  echo “hello bacon”;
}

hello_bacon(); // prints: hello bacon

But not all functions echo out a value because we don’t always want to echo (which is just another way to print something) a value out right away. Sometimes we need to process it more, etc. In that case you’d return a value. Returning a value is just the opposite of echoing a value. It says, don’t print it right now, save it for later.

function hello_bacon(){
   return “hello bacon”;
}

hello_bacon(); // prints: NOTHING! oh hold up!

To print it later we’d have to actually echo out the function.

echo hello_bacon();

or

$hello = hello_bacon();
echo $hello; // prints: hello bacon

See what we did there in that second one? We defined a variable, which if you’ll remember from math class is a bit of an amorphous blob that can have any value. Then we set that variable equal to the value returned from the hello_bacon() function.

Getting into Arguments

The hello_bacon() function is obviously super simple. It always returns the same thing. Well that’s not so much fun and sort of defeats the purpose of a function. Remember those magic black boxes? Well now we want to take a variable in, manipulate it and spit it back as something new and shiny. We send variables into functions as arguments to that function.

function favorite_food($food){
   echo 'My favorite food is ' . $food;
}

favorite_food(); //prints: My favorite food is <--didn't pass an argument so $food is empty, and I'm hungry.
favorite_food('guacamole'); //prints: My favorite food is guacamole

As you can see above, the favorite_food() function accepts 1 argument. Inside of the favorite_food() function this argument will be referred to by the variable $food. This sort of touches on a concept that we’ll get into in a bit, called variable scope. But for now remember that $food does not exist outside the favorite_food() function.

favorite_food('guacamole'); //still prints: My favorite food is guacamole
echo $food; //nothing doing

If you need to ensure that you never get an empty value for “My favorite food is ____” then you can give an argument a default. If you don’t pass an argument when calling a function it will simply use the default. Note below that ‘bacon’ is the default value of the $food variable.

function favorite_food($food = 'bacon'){
   echo 'My favorite food is ' . $food;
}

favorite_food(); //prints: My favorite food is bacon
favorite_food('guacamole'); //prints: My favorite food is guacamole

By now you might have noticed that we’ve only been dealing with what are called, ‘string’ variable types…. words or letters essentially. You’ve been seeing me combine strings together with a period (.) in what is called string concatenation. But just like math class, PHP functions work on numbers.

function double($x){
   return $x * 2;
}

$a = 10;
$a = double($a);
echo $a; //prints: 20

Variable Scope

Whoa hold up! You just said the argument was called $x, but there you go calling it $a. Yup. Remember when I said it was important to remember that variables (usually) only exist inside the function where they are defined. That is what is called variable scope. In PHP and WordPress you can declare variables as global in scope, meaning $x has the same value everywhere, but by default variables are local in scope, meaning again, they only exist within the functions using them.

I could rewrite the above to be:

function double($guacamole){
   return $guacamole * 2;
}

$bacon = 10;
$bacon = double($bacon);
echo $bacon; //prints: 20

I can call the variables anything I want, because the $guacamole in the double() function is not the same as the $bacon outside of it. Remember variables are placeholders. Think of it like the two are playing catch. In the following line:

$bacon = double($bacon);

We are passing a value to the double() function. The function then catches the value as its argument.

function double($guacamole)

Now the variable has a new name, but the same value. In the example the value was 10, that part isn’t any different. Within the function the variable $guacamole now has a value of 10. Then it performs its multiplication and sends back the doubled value. The is the pass back.

return $guacmole *2;

And that brings us back to:

$bacon = double($bacon);

where the variable $bacon catches the return pass, and the variable $bacon is now equal to 20, which we see when we echo $bacon.

So it is like playing catch. If you are out in the yard playing catch with someone who doesn’t speak the same language as you and you toss the ball to your partner, when he catches it, he might call it a beisbol. When he throws it back to you, it is a baseball again, you both just had different words (variables) for it.

This is the official PHP manual that might help explain things if my metaphors made it clear as mud.

http://php.net/manual/en/language.variables.scope.php

In Summary

We covered functions, function arguments, string variables, numeric variables and variable scope. There is quite a bit more, but I already feel like this is a lot actually and hopefully you are well on your way to programming hell… I mean bliss. Please point out any errors or places where I could be more clear, but keep Thematic and WordPress specific questions for their respective forums. Best of luck.

Posted in Understanding the Basics | Tagged , , , | 4 Responses