Genesis comes with a handy function called genesis_custom_loop()
. It’s an easy way for you to create a new loop without having to write all the code to create a new loop with WP_Query manually. Here’s how you can use it in your theme.
/** Replace the standard loop with our custom loop */
remove_action( 'genesis_loop', 'genesis_do_loop' );
add_action( 'genesis_loop', 'child_do_custom_loop' );
function child_do_custom_loop() {
global $paged; // current paginated page
global $query_args; // grab the current wp_query() args
$args = array(
'category__not_in' => 42, // exclude posts from this category
'paged' => $paged, // respect pagination
);
genesis_custom_loop( wp_parse_args($query_args, $args) );
}
The above will spit out a loop that excludes posts from category ID 42 and displays posts from the current paginated page (i.e. /page/2
and so on). The wp_parse_args()
function combines the $args
array with the current $query_args
for that page. The $args
array should accept all WP_Query parameters.
Replace with a non-Genesis loop
If you need to completely customize the loop, if you are displaying events or a ecommerce shop page for example, you don’t need to use the genesis_custom_loop()
function at all. Just write your own to replace it.
/** Code for custom loop */
function my_custom_loop() {
// code for a completely custom loop
}
/** Replace the standard loop with our custom loop */
remove_action( 'genesis_loop', 'genesis_do_loop' );
add_action( 'genesis_loop', 'my_custom_loop' );
You can stick this code in functions.php
to affect all the loops in your site, or put it in a template file like date.php
or author.php
to limit it with the template hierarchy. If you do stick it in a template file, remember to end it with genesis()
.
Thank you very much for making this available for free. You just saved my day. I am hopeless (and helpless) when it comes to programming logic. This snippet did exactly what I wanted it to do.
Thanks again!
Yay! Glad we could help 🙂
Hi Dave
would you know how to do multiple loops too, as well as include the featured image where we want it (like before title)
i have searched hi and low and nobody seems to have done this yet
Jamie, you asked the question that was on my mind. 🙂
There’s a reference to a second query here: http://codex.wordpress.org/Class_Reference/WP_Query that might be helpful?
I’m still figuring out how to put it together.
Carrie, i sort of worked out a way to do it, by using the default blog page for one category, and then just adding one extra custom loop, or even a widget with a featured post.
I was going to use it for a client site, but ended up using the genesis featured post amplified plugin and a custom home page with just widgets.
i have bits of code on github that you might find handy, and will be adding more (hope Dave does not mind me posting the link here)
https://gist.github.com/jamiemitchell
hope this helps
Awesome – thanks!
Here’s a page template I came up with based off a fork of Bill Erickson’s “Better Grid Loop”. It uses a completely custom loop (not just a modified genesis_custom_loop) and shows a featured image + a custom field.
Cheers,
Carrie
Hi Jamie, sorry for the late reply – I’ve been drowning in work! (Maybe I can hand off some to you in the future?)
Yes what I do usually is to use WP_Query to create a new loop, and then hook that to one of the actions in Genesis. So for example
I believe that’s how the Genesis Jedi Masters do it too:
http://www.billerickson.net/custom-wordpress-queries/
Great snippit! I’m new to Genesis and I’m having a hard time with it as I want to dig into it’s guts but don’t quite understand programming. I want to make my own custom loop to just show a static page (this works however then my “home page” widgets don’t display unless you go to the blog part of my website). I just want to add in a snippit of code that tells the child theme I’m using (minimum) to display those widget AND my home page. For wordpress child themes I would use but thats not the case with my genesis child theme. Is there a loop out there that will just tell my site to show the home page (that I apply in my settings as the front page) and my widgets? Any advice is appreciated.
Hi Amber, thanks for stopping by! Regarding your question, couldn’t you just create a page with a custom page template, and then set that page as the Home page (under Settings → Reading)? That might be the easiest way.
Otherwise, if you want to replace the loop with a single post, you can always modify the WP_Query object. Your code would look something like this:
The above code is untested! Use at your own risk 😉
More details on customizing WP_Query here: http://www.billerickson.net/customize-the-wordpress-query/
David,
Thanks for this snippet/tutorial.
Do you know how to replace the Genesis loop with the WooCommerce loop?
Woo ( http://docs.woothemes.com/document/third-party-custom-theme-compatibility/ ) says to do it this way for generic themes; but I don’t see how to do it for Genesis.
Any help would be greatly appreciated.
Hi Bob, have you seen this plugin? It should do the necessary to make Genesis work with WooCommerce
http://wordpress.org/extend/plugins/genesis-connect-woocommerce/
David,
Thanks for the quick reply.
Yes, I”m familiar with the Genesis Connect WooCommerce plugin. But it doesn’t handle Woo2.+ . The Woo docs recommend some template or function changes that would be easy with most themes, even with the earlier versions of Genesis. Replacing the Genesis loop with the WooCommerce loop is one of their suggestions; but I don’t see where to make the change.
Alas, if this were easier there would be more people doing it.
Hi Bob, in that case you should be able to do this:
Untested – use at your own risk 🙂
David,
Thanks. I’m on the road today; will check this tomorrow and let you know how it goes.
Hi David, I’m having problem to create a custom loop. I use genesis 1.9 and AgentPress Plugin. I created a child theme and all I want to do is changing the standard loop so I can display not just the Title, featured image and text of a post but a custom field. I followed all the instructions by removing the standard loop and create a custom one in page_blog.php file but it doesn’t work and I only see the standard loop. I have been following all the sample found on the subject but I can’t figure it out. What I’m doing wrong or missing. Could you help please?
Thanks
Hi Thierry, my guess is you probably are probably using $post->ID instead of get_the_ID(). Unfortunately we don’t / can’t provide support here so please try posting in the StudioPress forums, or better yet – send StudioPress a support ticket. Good luck!
Hello David,
I am trying to get an offset of minus two within the loop, so that the latest two posts are not displayed (because I want to feature them inside a widget area above).
I tried the following code. It seems to work except it displays the loop *twice*, once with the offset and then again the whole loop without any posts skipped.
Wondering if you might have any insight as to what is going on. (Also note, unfortunately this is on my dev site which is not public, so I cannot provide a link)
/** Replace the standard loop with our custom loop that offsets (omits) the latest two posts */
remove_action( ‘genesis_loop’, ‘genesis_do_loop’ );
add_action( ‘genesis_loop’, ‘child_do_custom_loop’ );
function child_do_custom_loop() {
global $paged; // current paginated page
global $query_args; // grab the current wp_query() args
$args = array(
‘offset’ => -2, // offset by -2
);
genesis_custom_loop( wp_parse_args($query_args, $args) );
}
In what file did you put your code above?
A custom functions file (I use The Genesis Extender plugin to add custom functions and custom css)
I see. Try adding the code directly to your functions.php and disabling the Genesis Extender plugin. Another idea is to check if you have another add_action(‘genesis_loop’, ‘genesis_do_loop’) somewhere else in the template file you are trying to customize. E.g. check if home.php has its own genesis_do_loop function.
Thanks for the quick response, David. Is there any way to avoid editing the original theme files directly?
Also, I looked for ‘genesis_do_loop’ in both the functions.php file in the genesis and the child theme directories, and could not find them (?)
I think you definitely have to put the code into the theme files. If you are editing a child theme, then it’s not really the *original theme files*, so it’s not a problem to edit your child theme’s functions.php
I suspect what is happening is that the plugin is *running only after the theme has loaded*. Therefore the hook to remove the loop is being called too late – the loop has already been loaded by the time Genesis Extender runs, so it can’t remove it any more.
If you’re comfortable with PHP code I don’t see why you need a plugin like Genesis Extender anyway. One of the attractions of Genesis is the streamline, clean options pages. Genesis Extender just clutters it up and is aimed at people who don’t want to write code.
hi david,
fistly thanks for the snippets 🙂
I’m trying to use the genesis custom loop snippet to ensure all my cpts are included in archive pages. unfortunately it disregards existing category or taxonomy. I get the same chronological list of posts in my travel section as i get in my review section or to put it another way i get all cpts of category review listed in category travel and vice versa despite at present all posts only
I assumed (perhaps wrongly) that the purpose of wp_parse_args was to honour the original query settings but amend those specified by $args however this does not appear to be the case.
below is the code i’m using if you could shed any light on what I might be doing wrong that would be great 🙂
function child_do_custom_loop() {
395 if (is_category()|| is_tag() || is_home()){
396 global $paged; // current paginated page
397 global $query_args; // grab the current wp_query() args
398 $args = array(
399 ‘post_type’ => array(‘holidays’,’courses’,’post’,’accommodation’,’companies’,’experiences’,’gear’),
400 ‘paged’ => $paged, // respect pagination
401 ‘orderby’ => ‘date’
402 );
403
404 genesis_custom_loop( wp_parse_args($args,$query_args) );
405 }else{
406
407 genesis_do_loop();
408 }
You would normally use the archive-post-type-name.php (where post-type-name is the name of your custom post type)
and taxonomy-taxonomy-name.php for taxonomies (where taxonomy-name is the name of your taxonomy)
see http://codex.wordpress.org/Template_Hierarchy
you can then modify the query on a per template basis using genesis hooks and filters
there is no need to build custom loops.
I worked out the issue 🙂
the original posted code creates a global variable called $query_args which is empty. checking wordpress codex i couldn’t find reference to $query_args. I could however find reference to $query_string which can be used with wp_parse_query().
the original code does not honour existing query parameters like category or tag for instance but if you replace $query_args with $query_string it will…..
cheers
Hi David!
I added the code for the custom loop to my site and now I have two loops showing on the home page. Any idea how I can get rid of the second loop?
jill 🙂
Hi Jill, this probably means you have a second
in your functions.php or added through a plugin. Also don’t forget to remove the default loop in the first place.