14th May '22
/
44 comments

Adding any Custom WP_Query loop to Bricks’ Query Loop

Adding any Custom WP_Query loop to Bricks’ Query Loop

Sometimes we may need to create a custom post loop using Bricks’ query loop feature, but wish to use our own WP_Query code for more flexibility.

This could either be because we need to do something that the built-in settings don’t quite allow for (needing something more dynamic for some of the WP_Query arguments), or maybe we just already have the code on hand for a fairly complicated post query and it’s just quicker pasting in the code than manually having to rebuilding it all through the UI.

Using Bricks’ Query Filters

Bricks comes with a few filters that allow us to change how different features behave and these make this possible.

The developer documentation is a great resource for finding out about all these filters individually. Here we’ll be using some of them together to add our new query type and inserting some custom WP_Query arguments for the Query loop feature to use. (see the links at the end of this post for information on the specific filters being used)

Adding the code snippet

This code would need to be added outside of the builder, either inside your child theme’s functions.php file or a code snippet manager such as WPCodeBox.

The code below takes care of..

  • Adding a new setting in the ‘type’ dropdown of the Query loop control
  • Running a new query if that setting is chosen (our WP_Query code)
  • Set up global post data
/* Add new query type control to query options */
add_filter( 'bricks/setup/control_options', 'bl_setup_query_controls');
function bl_setup_query_controls( $control_options ) {

    /* Adding a new option in the dropdown */
    $control_options['queryTypes']['my_new_query_type'] = esc_html__( 'My new WP Query' );

    return $control_options;

};

/* Run new query if option selected */
add_filter( 'bricks/query/run', 'bl_maybe_run_new_query', 10, 2);
function bl_maybe_run_new_query( $results, $query_obj ) {
	
    if ( $query_obj->object_type !== 'my_new_query_type' ) {
	    return $results;
    }
    
    /* If option is selected, run our new query */ 
    if ( $query_obj->object_type === 'my_new_query_type' ) {
        $results = run_new_query();
    }
    
    return $results;

};


/* Setup post data for posts */
add_filter( 'bricks/query/loop_object', 'bl_setup_post_data', 10, 3);
function bl_setup_post_data( $loop_object, $loop_key, $query_obj ) {
    
    if ( $query_obj->object_type !== 'my_new_query_type' ) {
	    return $loop_object;
    }

     global $post;
     $post = get_post( $loop_object );
     setup_postdata( $post );
    
     return $loop_object;

};


/* Return results from our custom WP Query arguments */
function run_new_query() {

    /* Add all of your WP_Query arguments here */

    $args = [ 
        'post_type' => 'post',
        'orderby'        => 'rand',
        'posts_per_page' => '1',
    ];
    
    $posts_query = new WP_Query( $args );

    return $posts_query->posts;

};

To customize it to make it your own query..

  • Change the query type my_new_query_type where it is mentioned in the first three functions to something more relavent.
  • Change the name from My new WP Query in the first function. (this will be how it appears inside of the settings)
  • Add your WP_Query arguments in the last function, inside the $args array.

That’s it

Now when you go into Bricks you’ll see the new option in the Query Loop type dropdown and can create your post loop.

Edit – See this Youtube video tutorial, by Ivan Nugraha, for an example of implementing this method to show posts based on ACF relationship fields – https://www.youtube.com/watch?v=JLCdFATDdvg

Adding multiple custom queries

To adapt the above code to include multiple new query types, here’s an example..

Named ‘my_first_custom_query’ and ‘my_second_custom_query’ for easier reading and editing to make it your own..

/* Add new query type controls to query options */
add_filter( 'bricks/setup/control_options', 'bl_setup_query_controls');
function bl_setup_query_controls( $control_options ) {

    /* Adding new options in the dropdown */
    $control_options['queryTypes']['my_first_custom_query'] = esc_html__( 'My first WP Query' );
	$control_options['queryTypes']['my_second_custom_query'] = esc_html__( 'My second WP Query' );

    return $control_options;

};

/* Run new query if option selected */
add_filter( 'bricks/query/run', 'bl_maybe_run_new_queries', 10, 2);
function bl_maybe_run_new_queries( $results, $query_obj ) {
	
    if ( $query_obj->object_type === 'my_first_custom_query' ) {
        $results = run_first_query();
    }
	
	if ( $query_obj->object_type === 'my_second_custom_query' ) {
        $results = run_second_query();
    }
    
    return $results;

};


/* Setup post data for posts */
add_filter( 'bricks/query/loop_object', 'bl_setup_post_data', 10, 3);
function bl_setup_post_data( $loop_object, $loop_key, $query_obj ) {
    
    /* setup post data if using any of our custom queries */
    if ( $query_obj->object_type === 'my_first_custom_query' || $query_obj->object_type === 'my_second_custom_query' ) {
		
       global $post;
       $post = get_post( $loop_object );
       setup_postdata( $post );
		
    }
    
    return $loop_object;

};


/* first WP Query arguments */
function run_first_query() {

    /* Add all of your WP_Query arguments here */
    $args = [ 
        'post_type' => 'post',
        'orderby'        => 'rand',
        'posts_per_page' => '2',
    ];
    
    $posts_query = new WP_Query( $args );

    return $posts_query->posts;

};

/* second WP Query arguments */
function run_second_query() {

    /* Add all of your WP_Query arguments here */
    $args = [ 
        'post_type' => 'post',
        'orderby'        => 'rand',
        'posts_per_page' => '1',
    ];
    
    $posts_query = new WP_Query( $args );

    return $posts_query->posts;

};

Query Loop Tutorials

For many useful code examples of creating custom query loops, or customizing existing query types to cover common use cases in Bricks, head to Query Loop Tutorials.

Filter references:

Get access to all 630 Bricks code tutorials with BricksLabs Pro

44 comments

  • Nice work. How can we add the Live Search toggle feature in the controls?

    • A
      David Browne

      Bricks' live search & filters are limited to the 'Posts' Query Type.

  • Justin Vogt

    Great write-up that will definitely help others to create their custom queries. I had to write quite some Custom queries, which is why I created a custom composer package: https://github.com/JUVOJustin/bricks-custom-query

    It allows using WPGridbuilder as well as custom controls. I created it to save myself and others fiddling around with all the filters.

  • Hi everyone !

    I wonder if someone has implemented this including pagination, it seems to be not working when I use a custom query loop, probably more custom code is required.

    • Justin Vogt

      You can make it work with WPGridbuilder pagination. You need to set custom query args "'wpgb_bricks" = 'bricks-element-2123669';

      2123669 is the id of your bricks elements that is set up to be a query

  • Mark Wells

    I'm trying to use this for a custom query using tribe_get_events for The Events Calendar and can't seem to get it right. Any guidance? Here's what I tried (go easy I clearly don't know PHP):

    /* Add new query type control to query options */ add_filter( 'bricks/setup/control_options', 'bl_setup_query_controls'); function bl_setup_query_controls( $control_options ) {

    /* Adding a new option in the dropdown */ $control_options['queryTypes']['get_weekly_events'] = esc_html__( 'Weekly Events' );

    return $control_options;

    };

    /* Run new query if option selected */ add_filter( 'bricks/query/run', 'bl_maybe_run_new_query', 10, 2); function bl_maybe_run_new_query( $results, $query_obj ) {

    if ( $query_obj->object_type !== 'get_weekly_events' ) { return $results; }

    /* If option is selected, run our new query */ if ( $query_obj->object_type === 'get_weekly_events' ) { $results = weekly_events(); }

    return $results;

    };

    /* Setup post data for posts */ add_filter( 'bricks/query/loop_object', 'bl_setup_post_data', 10, 3); function bl_setup_post_data( $loop_object, $loop_key, $query_obj ) {

    if ( $query_obj->object_type !== 'get_weekly_events' ) { return $loop_object; }

    global $post; $post = get_post( $loop_object ); setup_postdata( $post );

    return $loop_object;

    };

    /* Return results from our custom WP Query arguments */ function weekly_events() {

    /* Add all of your WP_Query arguments here */ $args = [ 'start' => 'now', 'posts_per_page' => -1, 'tribeHideRecurrence' => 1, array( 'taxonomy' => 'tribe_events_cat', 'field' => 'slug', 'terms' => 'weekly-schedule' ) ];

    $posts_query = new tribe_get_events( $args );

    return $posts_query->posts; };

  • Hi,

    Is there a way to loop through WP_Comment_Query for Woocommerce products on a single product page? The idea is to be able to create a custom layout for Woocommerce reviews for a single product page and create a custom form to submit a review.

    I'd need to include in the loop data the author, verification status, ratings, data, media, total reviews, title and comment and profile image.

    And then use Bricks Builder filters to filter ratings, with/without media etc.

    Thanks

  • Hello, Thank you very much...

    What would be the arguments to query cross-sell products please?

    I can't achieve it...

  • I'm curious if the following complex COMBINED query can be done within Bricks and still use the query loop, etc. Thanks for your efforts in advance:

    Main Goal example: Find matching tires for your BMW. The front and rear tires are different sizes (ex. 225/40R18 front, and 245/35R18 rear). You want 2 front, and 2 rear. Both need to be same brand/model. (brands/model like Michelin/Pilot Sport, Pirelli/Pzero, Goodyear/AllWeather, etc)

    Key Points: A successful query MUST match the BRAND and MODEL (ex. both front and rear must be Michelin Pilot Sport 4S, while the front size MUST be 225/40R18 and rear MUST be 245/35R18)

    Tire database similar to this: (tire_size, tire_brand, tire_model, SKU, etc) ex. (225/40R18, Michelin, Pilot Sport 4s)

    Query: Find ALL PAIRS of tires that match the SIZE criteria: Front_size = 225/40R18 AND Rear_Size - 245/35R18 (we want to see all results from all brands/models, while matching pairs based on front and rear sizing)

    Expected Results: Pair result 1: Michelin Pilot Sport 4S (front tire SKU 12345, rear tire SKU 12376) Front_size = 225/40R18 AND Rear_Size - 245/35R18

    result 2: Pirelli PZero (front tire SKU 52322, rear tire SKU 52342) Front_size = 225/40R18 AND Rear_Size - 245/35R18

    result 3: Goodyear Eagel F1 (front tire SKU 24322, rear tire SKU 24348) Front_size = 225/40R18 AND Rear_Size - 245/35R18

    Let's connect!

  • Matt Black

    Hello, 2 part question: 1. does this work for post only or can i use it to pull database content from. ive been testing with the wpdb but its not working for me.

    1. can this work with a query loop inside ( or dependant ) of another query loop. ie: query "bdcat" than a query list matching "bdcat"

    maybe if you can reach out you maybe able to help with some custom work after a quick chat.

  • Eric Embacher

    This works great...EXCEPT it doesn't work with WPGridBuilder facets. If I use a regular Bricks query for the query loop, all the facets work fine, but if I use a custom query, the grid works fine but all the facets won't display. Any ideas?

    • A
      David Browne

      I believe the WPGB integration with the query loop was only built to support the 'post' type query, not for custom types.

      If needing to use facets, you're best changing the existing post query variables rather than creating a new one. (using the bricks/posts/query_vars filter)

      There's a few tutorials on here showing that filter being used.

      See https://brickslabs.mystagingwebsite.com/tag/bricks-posts-query_vars/ for examples.

      • Eric Embacher

        I found some posts that mention "bricks/posts/query_vars" but I don't feel I can figure out how to adapt these tutorials for my use case. I simply need to query one of three different CPT ("activities", "hotels" or "restaurants") based on what is specified in the page's URL query parameter. If no URL parameters are specified, it should query all 3 CPTs. The query is for a grid that is to be filtered by WPGridBuilder facets. I'd be grateful for any guidance you could provide...

        • A
          David Browne

          Hi Eric,

          Whatever you're adding to the $args = [] to add in your query arguments in the above tutorial, you'd add them instead via the bricks/posts/query_vars.

          Here's a simplified version, showing the same args example from the tutorial.. the bottom part of the code is showing how to change exactly the same arguments but to change an existing query loop, rather than creating a new one.

          https://gist.github.com/wplit/32030289385ecc23c87784cac0267a0e

          (the top part of the code isn't needed, it's just showing the snippet from this tutorial so you can see the similarity.)

          In terms of getting it to work with WPGB, as you're talking about changing CPTs conditionally, you may need to add multiple facets, one for each CPT. I don't know if WPGB allows one facet to be used for multiple CPTs.

          • Eric Embacher

            Thanks for the info...I ended up adding multiple facets, just in case you're right about WPGB.

  • Hitesh Patel

    what is the process to run two query at a time. if you want to display post_title,featured image then run post query. $posts_query = new WP_Query( $args ); if you want to display term_name,term_id then run term query $term_query = new WP_Term_Query( $term_args ); But I would like to display post_title,featured image as well as term_name then how its possible?

  • Olliver

    Hi David,

    I have a metabox custom field type post, select multiple where I can select related pages to be shown

    How would I adapt your code so the query shows the selected related pages from the custom field?

    Thanks

  • Brian Andersen

    Is this still working? Im running 1.7beta and added the code, but nothing shows up in the builder under loop.

  • Thanks. Everything works. How to enable infiniti scroll support?

  • Clement

    Hi David, Thank you very much for this tip. I noted that once you're in a Custom Query Loop,if you add a ACF Repeater with custom fields based on the post you are looping, it doesn't output anything anymore

  • Michael Soden

    Hi David,

    Thank you for providing this easy to follow tutorial.

    Is there an easy way to add controls to the custom query that is built? For example, if we want to take some dynamic input from the user for our custom query?

    Any help would be appreciated.

    Thank you

    • A
      David Browne

      There doesn't seem to be any filters for this in Bricks. Any dynamic data would need to be added in arguments in the PHP itself.

  • Thanks for this. Very helpful! I'm trying to customise the Bricks query to return a list of WooCommerce orders/list items, but I can't seem to figure out what to change in your example. It's not a standard WP Query though - it uses WC_Order_Query, so I'm not sure if this will work. I've changed your code to:

    /* Return results from our custom WP Query arguments */ function run_new_query() {

    /* Add all of your WP_Query arguments here */

    $posts = wc_get_orders( array( 'limit' => 10, 'orderby' => 'date', 'order' => 'DESC', ) );

    return $posts;

    But I don't know how to get a single order object back and then display each orders data on the front end.

    • Ahmed Mnsor

      Hi Zayne I'm trying to do that too but I can't find a solution yet Did you find one?

  • Has this worked for folks? Any ideas as to why only my first function works, but not the second? The code is nearly identical!

    • A
      David Browne

      Hi Sarah,

      If you want to share a link to your version of the code I can take a look.

  • Hi. This works nicely, but what if I want to add more than one custom wp_query loop?

Leave a Reply to Mark Wells (Cancel Reply)

 

Related Tutorials..

Pro
Search Results Grouped by Post Types in Bricks

Search Results Grouped by Post Types in Bricks

Updated on 08 Oct 2024 This Pro tutorial provides the steps to arrange the search results by specified post types in a Bricks site. We…
Pro
Meta Box Checkbox List Query Type in Bricks

Meta Box Checkbox List Query Type in Bricks

This Pro tutorial provides the steps to add a new query type in Bricks builder for displaying the values of a Checkbox List type of…
Categories:
Querying Posts by Date Field to Exclude Past Events with ACPT Plugin

Querying Posts by Date Field to Exclude Past Events with ACPT Plugin

In the Bricks' Facebook group, a user asked: Meta query? What am I missing?Hi all, really need a little guidance on this one. I have…
Categories:
Pro
Dynamic Remaining Posts Count for Load more Button in Bricks

Dynamic Remaining Posts Count for Load more Button in Bricks

A user asked in the Bricks Facebook group: I have a loop of a CPT, showing 10 in a total of 16 posts and a…
Pro
Query Loop Index in Bricks

Query Loop Index in Bricks

This Pro tutorial provides the code for getting the index of each post in Bricks' query loops. This can be used for either outputting the…
Categories:
Pro
Adding active class to the current term/post in a Bricks query loop on Term archives/single posts

Adding active class to the current term/post in a Bricks query loop on Term archives/single posts

Updated on 29 Feb 2024 In the Sibling Terms Bricks Query Loop tutorial, a member asked: How can I set the class "active" to the…
Categories:
How to create filters with IsotopeJS in Bricks (Part 3): apply multiple filters

How to create filters with IsotopeJS in Bricks (Part 3): apply multiple filters

This tutorial will review how to apply multiple filters to an isotope container using the IsotopeJS library‘s features in Bricks.
Loop Item ID and Loop Item Object in Bricks

Loop Item ID and Loop Item Object in Bricks

If you are working on a Bricks site with specific requirements, chances are you need to grab the ID and/or object of the current item…
Categories: