In the first part of this series, Genesis Explained: The Framework, I explained in general how the Framework works, and I showed the contents of a single file to show how the hooks look in the Framework. In the second part, Genesis Explained: Actions, I explained how add/remove actions work, the technical rules around them. This post is intended to tie these other two posts together, bridging the gap between the theoretical actions and the Framework.
Let’s start by talking files. Genesis does a great job of using directory structure to organize files. Here is the directory structure found in Genesis, with a very brief description of what the files within the directory do
- genesis: contains all files and directories. The files exposed in this directory are general template files, mostly loading other files in the framework. The header.php and footer.php are core framework files with hooks.
- images: all the images used with the Genesis theme, since you should be using a child theme this doesn’t do much
- lib: contains the core files for the Framework, the init.php file loads all the other files and the framework.php file contains the core hooks used by the framework
- admin: files related to admin operations
- images: images used in the admin part of the site
- classes: files with php classes used by the theme
- css: loads styles for the admin section of the site
- functions: general or helper functions used in the theme and child themes. I will be writing a post that discusses many of these in the future
- js: handles script loading for the theme, includes admin, comment, and menu scripts
- languages: handles translation files
- shortcodes: all the short codes built into the theme
- structure: handles the output on the front end of the site, the remainder of this article will be dealing with this directory
- tools: tools used by Genesis to handle some special functions
- widgets: the theme specific widgets
- admin: files related to admin operations
As you can see, if you choose to look through Genesis, the directories will help you quickly identify the files you are looking for. I could write several tutorials on each directory, but this one focuses on integrating the actions with the Framework, which means looking in the structure directory.
The files in this directory include almost every action used in Genesis. A question I’m often asked is “how do you know exactly what code removes a given element on the site?” Because I know what directory has the original action. If I don’t know the answer off the top of my head (after a year I do know a lot of the functions by rote) I can quickly find it. Let’s look at the files in the structure directory.
- archive.php: has actions specific to archive pages like the archive title output
- comments.php: has actions specific to the comments on the site like the comment form
- footer.php: the footer actions, including the new widgeted footer
- header.php: the actions that load on hooks in the header.php including the site title
- layout.php: actions that handle loading the sidebars
- loops.php: handles the 3 loops available in Genesis: standard, custom, and grid loops
- menu.php: controls the menu output
- post.php: essentially this is everything that loads inside the loop
- search.php: actions specific to search pages
- sidebar.php: the hooks and actions that create the sidebars if they are loaded by the layout.php file
Again, you can see how easy it is to find the code you are looking for based on the file structure. The names are essentially an index for the functions.
Working with Genesis Hooks
Ok, enough of the preliminary details. You came here for specific examples on how to work with the hooks. I’m going to break this section down into three parts: removing actions, moving actions, and modifying actions. In each section I will give a specific example from Genesis files with explanations on what is happening and how you can use that information to do this on your own with other actions.
Removing Actions
This is the easiest part. In the previous article I explained how removing an action is a matter of having the exact same action, but with “remove” instead of “add.” All you really need to do is find the action you want to remove, copy it into your child theme functions.php file, and change “add” to “remove.” There is a tutorial on Dev.SP on removing the post info, but let’s say there wasn’t and you needed to remove that from your site. What do we know about this? Well we know it is in the loop, we know that because it appears on every post in an archive view (one that shows multiple posts on a page). Ok now look at the files, which one says it deals with loop actions? Yep the post.php file, so open that up and have a look, try to see if you can find the right code.
add_filter('genesis_post_info', 'do_shortcode', 20); add_action('genesis_before_post_content', 'genesis_post_info'); /** * Add the post info (byline) under the title * * @since 0.2.3 */ function genesis_post_info() { if ( is_page() ) return; // don't do post-info on pages $post_info = '[post_date] ' . __('By', 'genesis') . ' [post_author_posts_link] [post_comments] [post_edit]'; printf( '<div class="post-info">%s</div>', apply_filters('genesis_post_info', $post_info) ); }
Ok, now we have the code needed, there is a filter, an action, and a function. The filter is for another tutorial, so let’s ignore that for now. We don’t need to function to remove or move an action, so we can ignore that. All we need is line two from this. Copy that into the functions.php of your child theme and change “add” to “remove.” This is what you will get
remove_action('genesis_before_post_content', 'genesis_post_info');
If you look at the tutorial on Dev.SP, you will find that is the exact code you need to add to your functions.php file to remove this. Pretty easy.
Moving Actions
The first part of moving an action is removing the action. Think of it like a cut and paste in Microsoft Word. If you want to move some code, first you cut it, then you add in back in where you want it. Another helpful tutorial on Dev.SP shows how to move the navigation menus. Let’s see if we can use our new knowledge to replicate that by looking at the code. First we need to know what file to look in. Since we are dealing with the menu the answer should be pretty apparent … yep, menu.php. For this we want to move the primary navigation. Nothing to fancy, we just want it above the header instead of below it. Did you find the code for the primary nav menu yet? I’m not going to copy it all here, but this is the relevant part
add_action('genesis_after_header', 'genesis_do_nav'); /** * This function is responsible for displaying the "Primary Navigation" bar. * * @uses genesis_nav(), genesis_get_option(), wp_nav_menu() * @since 1.0 */ function genesis_do_nav() {
So we know how to remove this, just copy the action into the child theme functions.php file, and change “add” to “remove” but now we want it to be put somewhere else, so paste the code again and change the hook. With some effort you can memorize all the hooks, but there is a handy hook reference in the Dev.SP site and also in my first part in this series. Since we want to go before the header, we can change it from “genesis_after_header” to “genesis_before_header.” This is the code we end up with
remove_action('genesis_after_header', 'genesis_do_nav'); add_action('genesis_before_header', 'genesis_do_nav');
A quick check of the tutorial and we will find that is exactly what is happening.
Modifying Actions
This is the hardest thing when dealing with Genesis Actions. You have to remove the existing action, then create your own function to replace it. One of the most common changes done in child themes is the need for a custom loop. This can be done in several ways, but for the sake of this example we are going to remove the existing loop and replace it with a custom loop using genesis_custom_loop().
Since we are working with loops, which file should we open. If you said footer.php then you are on crack or something. Of course it is loops.php. The code is right at the top of the file
add_action('genesis_loop', 'genesis_do_loop');
That was easy. This loads a function that decides which loop to load, we will be bypassing that. I’m going to skip to the final code so I can explain what I would add to the child theme, and how this can be done with other actions
remove_action('genesis_loop', 'genesis_do_loop'); add_action('genesis_loop', 'child_do_loop'); function child_do_loop() { global $query_string; $args = array ( 'cat' => -1, 'order' => 'ASC' ); $args = wp_parse_args( $query_string, $args ); genesis_custom_loop( $args ); }
Ok, if you have been following along you know the first line just removes the existing loop function. The second line ads out custom loop function. It must have a unique name. I often change “genesis” to “child” and call it good. If this were added in a archive.php file I might go with “child_do_archive_loop” instead. Also notice that line 3 defines the function and it exactly matches the function name in the action, this is very important as well.
The guts of this are creating the $args for the custom loop. The first part makes the existing query something that can be used inside the function. Any variable not defined in the function needs to be declared global before you can use it. If I wanted to use the $post->ID, a very common need, then I would also need to make $post global. You can make more than one variable global by using comma separated variables
global $post, $query_string;
Moving on, the next lines defines the $args I’m going to use for the custom query. These are the same args used in WP_Query or query_posts().
Since I want to keep the existing query, I need to merge that with the $args I defined. The wp_parse_args() function does exactly this.
With my newly merged $args I can now run the genesis_custom_loop(), which basically takes the args to build a new query and then run that loop using the exact same hooks that are found in the standard loop.
To change some functions, you might be best starting by copying the existing function, giving it a new name, and editing it to what you need it to be. As I said before, there are other options to modifying a function. In some future parts of this series I will be explaining filters, which can let you make big changes without removing, adding, modifying actions.
For now you can find actions in the Genesis files and then remove, move, or modify them. That’s a pretty good start. In the next part of the series I will be dealing with some other cool tips and tricks for working with actions including how to add new actions, using existing functions, and using functions outside the normal actions.
Have anything to add, I’d love to hear from you. I’m also looking for other topics that might need more explanation.
Lynne says
This series is great, keep going!
I’ve been trying to figure it out for a week and I was having a hard time finding an explanation of how to do things on the Genesis site. They do have tutorials, but they are do not provide enough information or examples.
Grégoire Noyelle says
Hi Nick
Thanks a lot for thist tutorial. Your genesis_custom_loop is really awesome.
I try with custom taxonomy and it works so well. So I can even display my hierarchical custom post type like I want and keep the query safe in the same time 🙂
Dariusz Rudnicki says
Hi Nick,
I’m looking for a way to move “comments” form from after to before the comments in Delicious / Genesis theme. Under some of my posts I have so many comments that my visitors can’t even find the form (or are too lazy to scroll all the way down the page). I’m assuming this can be done by adding a filter to functions.php, or maybe by using hooks but I have no idea how to do it.
Also, I was wondering how can I place a link or a few links within a post that would scroll (when clicked) to the comment form location under the post.
I appreciate your help, thank you.
Darek
nickthegeek says
Dariusz, Thanks for commenting, please post this in the StudioPress support forums, I don’t handle support questions in my comments, thanks
Mike says
I love that this is fully broken down, as I’d like to be able to expand my Genesis usage beyond just the “flip the switch” style, but I think I’m getting lost on some of this.
Where can I find out about what $args are, declaring global variables, etc.
Is that PHP basics? Do you have suggestions or recommended resources for it?
Thanks.
nickthegeek says
Those are php basics. You might want to look at some of the introduction to php books available or w3schools php articles.
Basically, $args is a variable that will have different meanings in different settings. Anything that starts with $ is a variable and has to have a value assigned to it before it is useful. There are several ways to assign a value to a variable, but if it was assigned in another function it needs to be declared global with
Global is a special kind of php statement that brings variables with the current assigned values into a function, but only if those variables have already been declared global so this can be done.
Hope that helped some.
Shipra says
Hi Nick,
Just wanted to commend you on the excellent articles on Genesis. I’ve been planning on reading them for some months now, but only got the time this weekend. Your articles have been very useful in helping me build my own website with Genesis.
Thanks!
Leonard says
Great series, Nick. Thank you. This site is the missing manual to Genesis!!! Keep up the great work.
nickthegeek says
thanks
Nick Ruta says
Hi Nick,
Thank you for writing these articles on Genesis!
” If you said footer.php then you are on crack or something.” – a little comic relief went a long way!
Annie says
Hi Nick,
Quick question. WHY does Genesis even have remove/add action functions in the first place? It seems redundant to me. If you don’t want to write a certain piece of code, why not just delete or comment out the function? Why would you WRITE a function that just deletes previous code? Does it make sense why I’m confused? Any help is much appreciated!
Thanks so much!
nickthegeek says
Annie,
Great question. Basically Genesis is created so that it can be extended via plugins and child themes. This allows the Genesis core to remain unaltered. The reason that is important is Genesis can now be updated and it won’t break the site. The actions and filters allow for changes to be made via the child themes and plugins which will be retained during update.
It also means developers who have learned the system can work much more efficiently. It may not seem like it when starting out, but the action/filter system allows for rapid development. I am at the point now where I can develop a Genesis theme from a PSD in about a day. Working with other themes where I have to open and edit a dozen template files takes a week for the same project. That is a huge win.
Brian Novak says
I’m using Genesis 2.0 Beta and was not able to remove the post info using
remove_action( ‘genesis_before_post_content’, ‘genesis_post_info’ ); in my child function.php file. I was however able to remove the Genesis footer using remove_action( ‘genesis_footer’, ‘genesis_do_footer’ ); . Any ideas on why I cannot remove post actions?
nickthegeek says
The post info changes for HTML5. Check out the genesis/lib/structure/post.php file to see the new actions being used or go check out the snippets at my.studiopress.com
James L says
This is such a great series. The biggest issue for newbie developers approaching Genesis is that they have been able to create webpages with HTML and CSS exclusively and while the introduction of PHP seems to speed up dev time exponentially, it is a completely new set of rules and language with a bit more of a learning curve than some of us would have hoped when hopping into Genesis.
I’ve just spent the last day looking at the PHP in functions.php and wondering, “Where the crack do I put the divs!?” – your article clarified so much. Maybe most importantly you clarified something major. That before really tackling Genesis to make original child themes, PHP knowledge is totally 100% necessary – something that wasn’t disclosed very openly when I got excited and purchased it. PHP – so much more than just three letters at the end of WordPress files, 😀
bitkahuna says
great tutorial thanks. i see though that the advice to add:
remove_action('genesis_before_post_content', 'genesis_post_info');
is already obsolete with the latest genesis sample child theme (thanks studiopress).
it’s now:
remove_action( 'genesis_entry_header', 'genesis_post_info', 12 );
even the freaking 12 is needed. can you tell i don’t like genesis so far?
nickthegeek says
The code in this is not obsolete, but the code you provided is the HTML5 variant. Yes, the “12” is needed. This is part of how WordPress works, not Genesis though.
Nur Ahmad Furlong says
Hi Nick as always your explanations are some of the best covering Genesis thanks so much for the insight.
Do you happen to know where we can get a list of all the “do” functions.
It seems all the hook guides only cover the main hook boxes but these “do” parts are not listed anywhere. I don’t even know what the do part is a hook or action etc, but it’s clear knowing the correct syntax is key to being able to easily unhook and rehook or replace with your own custom elements
Nur Ahmad Furlong says
I just realised I asked the same Q about this list of functions on one of your previous posts. Sorry, still baffled to figure that out.