Welcome once again to the Genesis Explained series. Remember, this series builds on previous articles, so if you didn’t read the first Filters article, go catch up. All other posts can be found in the Genesis Explained tag archive.
In the previous tutorial I went over the basics of how the add/remove filter function works. I said that filters work more efficiently than actions when changing existing content rather than adding new content. The trick is finding where filters exist. In the Framework Actions article I explained where to find most of the actions used in Genesis. Many of the filters you will need can be found in the same files. A few notable exceptions exist. There are several filters available in the genesis/lib/classes/breadcrumb.php file and in the files within genesis/lib/functions/ folder. The names of the files should help identify the contents of the folders, but I’ll be addressing those files in the next sub series, which addresses Genesis functions.
So now to some very specific examples on using filters in Genesis. Like the Framework Actions tutorial I will use a couple of the Dev.SP as a guide, well rather more like a target. The goal here is to show how the tutorials work to better explain finding filterable content, and editing it with filters inside the framework.
Replacing a string
First, let me explain the concept of “string.” In php there are a few different kinds of data. Simplistically they are strings and arrays. Technically this might be a bit too simple, but for the sake of what we are covering that is enough. If you want to dig in deeper please check out the PHP Manual.
Anyways, long story short, a string is (for the sake of this tutorial) a text or numeric value. This can include html, since html is just text.
So, now that we have some basic idea of what a string is (more on that later) lets look for one to replace. If someone does a search and no posts are returned it will say “Sorry, no posts matched your criteria.” That’s fine, but what if I want to say something else? This is run inside the loop, which means we should start by looking in the post.php (remember loop.php builds the loop structure but post.php creates the actual output within the loop). We will find:
add_action('genesis_loop_else', 'genesis_do_noposts'); /** * No Posts */ function genesis_do_noposts() { printf( '<p>%s</p>', apply_filters( 'genesis_noposts_text', __('Sorry, no posts matched your criteria.', 'genesis') ) ); }
If you read the previous article on filters you should knwo the apply_filters() function is the place where the magic happens. It looks like a lot is going on, but really there is just one string there, the __() function is used for translating the text. If you don’t need to translate, then you can skip it and just put in your string, but we’ll leave it in just in case. Remember, you have to update your translation files if you make changes to the string the files are looking for. You might be able to write this already, but lets check it out and go through how it works.
add_filter( 'genesis_noposts_text', 'child_noposts_text' ); /**Changes the No Posts text for search pages */ function child_noposts_text( $text ) { if( ! is_search() ) return $text; return '<span class="no-posts">' . __( 'Sorry, no posts were found for your search.', 'genesis' ) . '</span>'; }
You will notice that the priority and number of accepted arguments aren’t specified. We are using the default so it doesn’t have to be added. Next you should notice that we are returning the $text if it isn’t the search page. We do this early on so we don’t forget later, but it could be done at the end as well. Finally, we return the translatable string that should appear on search pages without a valid response. I’m building an html string with some php, so I have to put them together with “.”. You can skip this if you aren’t using a translatable string, just put:
return '<span class="no-posts">Sorry, no posts were found for your search.</span>';
You also don’t need this if you aren’t adding the extra html. I personally like to be able to target the results, so I put the html in with the translatable string. If you look over at the Dev.SP article you will see that we got things pretty much the same, but with a couple extra niceties.
Changing Strings
This is slightly different, when changing strings you will be retaining some portion of the existing string and building something new, possibly by adding on, or using some advanced techniques like str_replace() or preg_replace(). Now over on the Dev.SP site there is a great tutorial on making this change, but to demonstrate how to use str_replace with args we’ll do something a little more complex.
One of the more common tasks people with to to is change the footer to suit their needs. Now there is a handy plugin to handle that, Genesis Simple Edits, but if you are building a child theme or need to use php that won’t work. So let’s see if that might be filterable. We know from the Framework Actions article that the footer actions are in genesis/lib/structure/footer.php. Check there to see if the filters are in that same file (it’s ok I’m not leading you on a wild goose chase). At the end of the genesis_do_footer() function, you will find this line of code
echo apply_filters( 'genesis_footer_output', $output, $backtotop_text, $creds_text );
Now based on the first filters article we know that the $output can be changed or replaced, but we can also make use of the $backtotop_text, and $creds_text. These are args with values that can be edited or used with the str_replace() function, which is what we’ll do here.
add_filter( 'genesis_footer_output', 'child_footer_output', 10, 3); /**Modifies the footer text */ function child_footer_output( $output, $backtotop_text, $creds_text ){ $child_creds_text = 'Copyright 2007 - '. date( 'Y' ) .'<a href="https://designsbynickthegeek.com">Nick the Geek</a>'; $output = str_replace( $creds_text, $child_creds_text, $output ); return $output; }
This is making things a little complex for what I’ve done here, I could have just done a simple replace on the “genesis_footer_creds_text” filter hook, but then I couldn’t show one way of using str_replace() to change the string value. there are times when this is the best solution, so it is important to see how this works.
Line 5 sets up the text we will be adding. I have built a string with a start date for the copyright, and the current year as the end date. I’ve found a lot of people want to know how to do this, so now you know how. All the other stuff in the footer went away. Remember, any html including plain text can go inside the single quotes (apostrophes), but the php has to go outside. To build the string you put the “.” between string values.
Line 7 uses str_replace() to find the $creds_text inside the $output and replace it with the $new_creds_text.
I’m sure you can see how this simple function can come in very handy when you have a string you want to modify, but it has already been joined together in the string that can be filtered.
This has been a lot to take in, I’ll be working on some other techniques in the next article, specifically focusing on working with arrays, which are a kind of complex string.
I’m sure you can see why I refer to filters as a kind of voodoo. They can be difficult to grasp when starting out, and many developers will want to fall back to actions to accomplish the same end, but with some practice filters will become your preferred method. In fact, you will start pestering the folks behind StudioPress to include more filters to save you time and code.
Again, I want to remind you to sign up for the RSS feed or fill out the email sign up in the sidebar to get the latest articles in this series and in the series I have planned.
Boomboom says
Good thing first. A great post. Thanks Nick. Now bad thing is I understood 10% of it 🙂 Well I am half asleep now at 1:15AM maybe thats why. Will have to go through this again. I understand string replace and stuff but the main thing is grasping the concept of filters. I guess I will have to check them again 🙂
nickthegeek says
Yeah, filters are one of the most difficult concepts. I have another article where I will use more examples, hopefully this will help clear it up a bit more. Plus the series after Genesis Explained will show filters in practical applications, which should help to clarify it some more.