Creating a custom query integration requries several steps depending on your needs.
Setting up your query
To connect Search & Filter with your query you will need to add an argument to the query itself with the name search_filter_query_id
. The value of this argument should be the ID of of the Search & Filter query you want to connect to.
Adding as an argument
When creating a query the argument can be passed in just like the other arguments:
$args = array(
'post_type' => array( 'post' ),
'search_filter_query_id' => 1,
'paged' => get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1,
);
$query = new WP_Query( $args );
Modifying an existing query
To modify an existing query you would need to use the pre_get_posts
hook, from here you need to call set()
on the query and add the search_filter_query_id
argument.
function pre_get_posts_function( $query ) {
$query->set( 'search_filter_query_id', 1 );
}
add_action( 'pre_get_posts', array( $this, 'pre_get_posts_function' ) );
Adding the query integration to admin
The next step is to add a new option in our UI allowing users to select this new query integration.
This can be done using the search-filter/settings/init
hook:
add_action( 'search-filter/settings/init', 'example_add_integration_option' ), 10 );
/**
* Add a new query integration option - 'Custom query widget' to the list of
* single integration options.
*/
function example_add_integration_option() {
// Get the setting.
$query_integration_setting = \Search_Filter\Queries\Settings::get_setting( 'queryIntegration' );
if ( ! $query_integration_setting ) {
return;
}
$new_integration_type_option = array(
'label' => __( 'Custom query widget', 'search-filter' ),
'value' => 'vendor-prefix/widget-name',
);
$query_integration_setting->add_option( $new_integration_type_option );
}
This adds the option to the query options dropdown:

Note: vendor-prefix/widget-name
should be changed – this is used internally as a reference.
Once this step is complete the query integration should already be working.
Supporting dynamic update
Search & Filter Pro supports dynamic updating of the results – this means the results will be updated without refreshing the page.
To support this there are two steps:
Add the CSS selectors for the query
We can use the search-filter/queries/query/get_attributes
filter to overide the query settings and insert our own queryContainer
and paginationSelector
values.
add_filter( 'search-filter/queries/query/get_attributes', 'example_update_query_attributes', 10, 2 );
/**
* Automatically set the Ajax CSS selectors for the query container and pagination
* so the user doesn't have to set it themselves.
*/
function example_update_query_attributes( $attributes, $query ) {
// We want `queryContainer` and `paginationSelector` to be set automatically.
$id = $query->get_id();
if ( ! isset( $attributes['queryIntegration'] ) ) {
return $attributes;
}
$query_integration = $attributes['queryIntegration'];
if ( $query_integration === 'vendor-prefix/widget-name' ) {
// The query container is a CSS selector that contains the results and pagination.
$attributes['queryContainer'] = '.my-custom-query';
// The pagination selector must be considered a child of the query container.
// An attribute of `.pagination a` will be converted to `.my-custom-query .pagination a`.
$attributes['paginationSelector'] = '.pagination a';
}
return $attributes;
}
Note: as there can be multiple queries on a page its best if this class or ID is unique, internally we use the query ID as the class name to ensure uniqueness.
Note 2: 'vendor-prefix/widget-name'
needs to be updated to reflect your reference name.
Hide the CSS selector options from the UI
Warning: this implementation is likely to change.
Again we can use the register hook to modify the options and change the conditions to display these settings.
add_action( 'search-filter/settings/init', array( $this, 'example_hide_css_selector_options' ), 10 );
/**
* Hide the query container and pagination selector settings from the user as we're
* automatically setting them above.
*/
public function example_hide_css_selector_options() {
$depends_conditions = array(
'relation' => 'AND',
'action' => 'hide',
'rules' => array(
array(
'option' => 'queryIntegration',
'compare' => '!=',
'value' => 'vendor-prefix/widget-name',
),
),
);
$query_container = \Search_Filter\Queries\Settings::get_setting( 'queryContainer' );
if ( $query_container ) {
$query_container->add_depends_condition( $depends_conditions );
}
$pagination_selector = \Search_Filter\Queries\Settings::get_setting( 'queryPaginationSelector' );
if ( $pagination_selector ) {
$pagination_selector->add_depends_condition( $depends_conditions );
}
// To support "load more".
$query_posts_container = \Search_Filter\Queries\Settings::get_setting( 'queryPostsContainer' );
if ( $query_posts_container ) {
$query_posts_container->add_depends_condition( $depends_conditions );
}
}
Essentially, this code specifies that the setting should only be displayed if the integration type is set to a single page and the single integration type is not set to the integration name.
Note: vendor-prefix/widget-name
needs to be updated with the name you have chosen.
Once these steps have been completed your query should support all Search & Filter features.
Example plugin
You can use our example plugin as a guide, it uses a shortcode to create a custom query listing and then configures the options above to support dynamic updates.
* Download will be available again when we launch the new site.
Use the shortcode [my_custom_query]
to display the query.
Allowing users to choose a query
If you are building a query or widget that will be distributed, it is often a good idea to allow a user to choose which Search & Filter query they would like to connect to your widget.
To get a list of Search & Filter queries to choose from you can use the following code:
$queries = \Search_Filter\Queries::find( array(
'status' => 'enabled', // Only get enabled queries.
'number' => 0, // Get all.
'meta_query' => array(
array(
'key' => 'query_integration',
'value' => 'vendor-prefix/widget-name',
'compare' => '=',
),
),
), 'records' );
var_dump($queries);
Note: here we will fetch a list of queries that have specifically been set to use vendor-prefix/widget-name