Purpose:
Standardize the way the various widgets access the Query-Control Module’s autocomplete & show-title functionality.
Audience: widgets developers.
This change was introduced in Elementor Pro 2.6.0.
The old API is deprecated and will be declared “end of life” in Elementor Pro 2.10.0 or 3.0.0 (whichever is earlier).
Method:
Each widget using the ElementorPro\Modules\QueryControl\Module::QUERY_CONTROL_ID
control, should specify an autocomplete array, according to the following syntax:
$this->add_control(
'my_unique_control_id',
[
//...
'type' => ElementorPro\Modules\QueryControl\Module::QUERY_CONTROL_ID,
'autocomplete' => [
'object' => ElementorPro\Modules\QueryControl\Module::QUERY_OBJECT_TAX,
'display' => 'detailed',
'by_field' => 'term_taxonomy_id',
'query' => [],
],
]
);
“autocomplete” Properties:
object
(required)(string) : The object to query, accepts:
- post: will use
WP_Query()
, if query[‘post_type’] is empty or missing, will default to ‘any’. - tax: will use
get_terms()
. When `post_type` is provided,get_object_taxonomies()
is used to build that `taxonomy` args that are passed toget_terms()
. When both `taxonomy` and `post_type` are provided, ‘post_type’ is ignored. - user: will use
WP_User_Query()
with the args defined in ‘query‘, if none are provided, will default to search fields: `ID` and `display_name` and search columns: `user_login` and `user_nicename`. - author: will use
WP_User_Query()
. The following pre-defined args are always added to the query args:- $query[‘who’] = ‘authors’
- $query[‘has_published_posts’] = true
- library_template: will use
WP_Query()
with add the following to the query args:- $query[‘post_type’] = Elementor\TemplateLibrary\Source_Local::CPT;
- $query[‘orderby’] = ‘meta_value’;
- $query[‘order’] = ‘ASC’;
- attachment: will use
WP_Query()
with post_type = attachment. The following pre-defined args are always added to the query args:- $query[‘post_type’] = ‘attachment’;
- $query[‘post_status’] = ‘inherit’;
display
(string) : Output formating, accepts :
- minimal: (default) name only.
- detailed: name and context, according to one of the following patterns:
- Post & Taxonomies: `<Taxonomy name|Post-Type name> : [parent] … [parent] > name`
- Users & Authors: `name <email>`
- user defined: representing a user-defined hook, note that each `object` value requires a different hook string:
`object` value | Hook name |
tax | “elementor/query/get_autocomplete/tax/{user defined value}” |
post | attachment | “elementor/query/get_autocomplete/custom/{user defined value}” |
user | author | “elementor/query/get_autocomplete/user/{user defined value}” |
by_field
(string) : The Id field that is used for the term query, relevant only if `object` is set to either ‘tax’ or ’cpt_tax’.
query
(array) : Array of args, as defined in WordPress, to be passed “as-is” to the relevant WordPress query object or function, see `object`.
Example:
Before:
// In your Widget you would have
$this->add_control(
'template_id',
[
'label' => __( 'Choose Template', 'elementor-pro' ),
'type' => ElementorPro\Modules\QueryControl\Module::QUERY_CONTROL_ID,
'filter_type' => 'library_widget_templates',
'label_block' => true,
]
);
// And to support it you whould also have
add_filter( 'elementor_pro/query_control/get_autocomplete/library_widget_templates', function ( array $results, array $data ) {
$document_types = ElementorPro\Plugin::elementor()->documents->get_document_types( [
'show_in_library' => true,
] );
$query_params = [
'post_type' => \Elementor\TemplateLibrary\Source_Local::CPT,
'posts_per_page' => -1,
'meta_query' => [
[
'key' => Elementor\Core\Base\Document::TYPE_META_KEY,
'value' => array_keys( $document_types ),
'compare' => 'IN',
],
],
];
$query = new \WP_Query( $query_params );
foreach ( $query->posts as $post ) {
$document = \Elementor\Plugin::instance()->documents->get( $post->ID );
if ( $document ) {
$results[] = [
'id' => $post->ID,
'text' => $post->post_title,
];
}
}
return $results;
}, 10, 2 );
add_filter( 'elementor_pro/query_control/get_value_titles/library_widget_templates', function ( $results, $data ) {
$document = \Elementor\Plugin::instance()->documents->get( $data['id'] );
if ( $document ) {
$results[ $data['id'] ] = $document->get_post()->post_title;
}
return $results;
}, 10, 2 );
After:
// In your widget
$document_types = ElementorPro\Plugin::elementor()->documents->get_document_types( [
'show_in_library' => true,
] );
$this->add_control(
'template_id',
[
'label' => __( 'Choose Template', 'elementor-pro' ),
'type' => ElementorPro\Modules\QueryControl\Module::QUERY_CONTROL_ID,
'label_block' => true,
'autocomplete' => [
'object' => ElementorPro\Modules\QueryControl\Module::QUERY_OBJECT_LIBRARY_TEMPLATE,
'query' => [
'meta_query' => [
[
'key' => Elementor\Core\Base\Document::TYPE_META_KEY,
'value' => array_keys( $document_types ),
'compare' => 'IN',
],
],
],
],
]
);
As you can see the control already accepts the query arguments so there is no need to add supporting filters.