Custom Query Guide

Custom Query Filter for Posts Widget

Setting Up a Custom Filter

In your post widget, assign a unique Query ID under Content > Query > Query ID. This ID connects your post widget with your custom query filter. It is useful when you need more control over the post widget’s query than the available options give you.

Using the Custom Filter

After assigning a Query ID, add your custom query logic in your theme’s functions.php or a custom plugin. Use the action hook with this format:


function custom_query( $query, $widget ) {
    // Modify the posts query here
}
add_action( 'bpfwe/query/{$query_id}', 'custom_query', 10, 2 );

For example, if you use my_custom_filter as the Query ID, the hook you will use is bpfwe/query/my_custom_filter.

Hook Arguments:

ArgumentTypeDescription
queryWP_QueryThe query used by this widget. Change it with $query->set().
widget\Elementor\Widget_BaseThe post widget instance. Optional: you can leave it out and register the hook with one argument.

Example 1: Show Multiple Post Types in a Post Widget


function bpfwe_by_post_types( $query ) {
    $query->set( 'post_type', [ 'page', 'post', 'product' ] );
}
add_action( 'bpfwe/query/my_custom_filter', 'bpfwe_by_post_types' );

Example 2: Show Posts with Multiple Statuses at Once


function bpfwe_by_post_status( $query ) {
    // Draft posts are visible to anyone who can see the page, so only show them to editors.
    if ( current_user_can( 'edit_posts' ) ) {
        $query->set( 'post_status', [ 'publish', 'draft' ] );
    }
}
add_action( 'bpfwe/query/my_custom_filter', 'bpfwe_by_post_status' );

Example 3: Order Posts by Most Popular Post by Comment Count


function bpfwe_by_different_order( $query ) {
    $query->set( 'orderby', 'comment_count' );
}
add_action( 'bpfwe/query/my_custom_filter', 'bpfwe_by_different_order' );

Notes

  • Replace my_custom_filter with your actual Query ID.
  • The hook runs for the post widget’s own query, and only for that query. Other queries on the page aren’t affected.
  • When visitors filter, sort or search: the results come from the filter’s own query, not the post widget’s. Your bpfwe/query/ changes are applied to those results only if the Filter widget has Include Loop Grid Query ID turned on. In that case, the hook receives a limited query object that only supports $query->set(), so avoid reading values with $query->get() or calling methods like is_main_query(). To change filtered results directly, use the filter below.
  • Refer to the pre_get_posts from WordPress documentation for more advanced query options.

Custom Query Args Filter for Filter Widget

Setting Up a Custom Args Filter

In your filter widget, assign a unique Query ID under Content > Query > Filter Query ID. This ID connects your filter widget with your custom args filter. It is useful when you need to directly modify the $args array passed by the filter before the query runs.

Using the Custom Args Filter

After assigning a Query ID, add your custom query logic in your theme’s functions.php or a custom plugin. Use the filter hook with this format:

add_filter( 'bpfwe/filter_query_args/{$query_id}', function( $args, $ajax ) {
    // Modify the $args array here
    return $args;
}, 10, 2 );

For example, if you use my_custom_filter as the Query ID, the hook you will use is bpfwe/filter_query_args/my_custom_filter.

Hook Arguments:

ArgumentTypeDescription
argsarrayThe WP_Query arguments built from the visitor’s selections. Return the modified array.
ajaxBPFWE_AjaxThe plugin’s request handler. You usually don’t need it.

Example 1: Filter Posts by Meta Value

add_filter( 'bpfwe/filter_query_args/my_custom_filter', function( $args, $ajax ) {
    // Show only posts where meta key 'highlight' equals 'yes', on top of the visitor's selections.
    $highlight = [
        'key'     => 'highlight',
        'value'   => 'yes',
        'compare' => '=',
    ];

    if ( ! empty( $args['meta_query'] ) ) {
        $args['meta_query'] = [
            'relation' => 'AND',
            $args['meta_query'],
            $highlight,
        ];
    } else {
        $args['meta_query'] = [ $highlight ];
    }

    return $args;
}, 10, 2 );

Example 2: Filter Posts by Taxonomy Term

add_filter( 'bpfwe/filter_query_args/my_custom_filter', function( $args, $ajax ) {
    // Show only posts in the 'events' category, on top of the visitor's selections.
    $events = [
        'taxonomy' => 'category',
        'field'    => 'slug',
        'terms'    => 'events',
    ];

    if ( ! empty( $args['tax_query'] ) ) {
        $args['tax_query'] = [
            'relation' => 'AND',
            $args['tax_query'],
            $events,
        ];
    } else {
        $args['tax_query'] = [ $events ];
    }

    return $args;
}, 10, 2 );

Example 3: Order Posts by Custom Date Meta

add_filter( 'bpfwe/filter_query_args/my_custom_filter', function( $args, $ajax ) {
    // Order posts by meta key 'event_date' descending
    $args['meta_key'] = 'event_date';
    $args['orderby']  = 'meta_value';
    $args['order']    = 'DESC';
    return $args;
}, 10, 2 );

Changing All Filters at Once

To change the query of every filter on your site, use the global hook bpfwe_ajax_query_args. It receives the same $args array and the request handler, and runs before the Query ID hook.

add_filter( 'bpfwe_ajax_query_args', function( $args, $ajax ) {
    // Applies to every filter query
    return $args;
}, 10, 2 );

Notes

  • Replace my_custom_filter with your actual Query ID.
  • This filter works at the $args level, after the plugin has built the arguments from the visitor’s selections.
  • When you add to tax_query or meta_query, wrap the existing conditions as in Examples 1 and 2 instead of appending to them. The plugin may already have set a relation (from the widget’s Parent Logic), and appending your condition to it would combine yours with OR instead of AND.
  • Example 3 replaces the ordering, including a choice made with the Sorting widget.
  • Refer to the WP_Query documentation for a full list of arguments you can use.