Hello,
I have a Custom Search which displays child posts and I have found out that it also displays posts of parent posts which are not published yet (in Pending Review state). Is there any way how to hide child posts which parents are not published from search results?
Hi Dave,
Thank you for contacting us and I'll be happy to assist.
You can hide those results, using conditional HTML block and "wpv-post-status" shortcode.
( ref: https://toolset.com/documentation/user-guides/views-shortcodes/#vf-153411 )
For example, you can wrap the output of your view's content template, inside a conditional block:
[wpv-conditional if="( '[wpv-post-status item='$parent']' ne 'pending' )"]
// Content template data
[/wpv-conditional]
This will make sure that a child post, whose parent is set to pending review status, is not shown.
I hope this helps and please let me know if you need any further assistance around this.
regards,
Waqar
Hi Waqar,
thank you for the help, but it did a half of the job. The search includes [wpv-found-count] and it still shows the original number. I was thinking about setting up the Custom Search Filter, but I did not found any option which could help.
Hi Dave,
There is no direct search filter available for this kind of filtering, but you can use "wpv_filter_query" ( ref: https://toolset.com/documentation/programmer-reference/views-filters/#wpv_filter_query ) and "get_posts" ( ref: https://codex.wordpress.org/Template_Tags/get_posts ) functions to filter/exclude those results from the View's query:
For example:
add_filter( 'wpv_filter_query', 'filter_pending_status_fn', 1000 , 3 );
function filter_pending_status_fn( $query_args, $view_settings ) {
if ( !is_admin() && ( isset($view_settings['view_id']) && $view_settings['view_id'] == 123) ) {
$post_type = "post-type-slug";
$args = array(
'posts_per_page' => -1,
'post_type' => $post_type,
'post_status' => 'pending',
);
$posts_array = get_posts( $args );
foreach ($posts_array as $post_array ) {
$query_args['post__not_in'][] = $post_array -> ID;
$args_child = array(
'posts_per_page' => -1,
'post_type' => $post_type,
'post_status' => 'publish',
'post_parent' => $post_array -> ID,
);
$posts_array_child = get_posts( $args_child );
foreach ($posts_array_child as $post_array_child ) {
$query_args['post__not_in'][] = $post_array_child -> ID;
}
}
}
return $query_args;
}
The above code can be added into the active theme's "functions.php" file and you'll replace "123" and "post-type-slug" with the actual ID of the view and the slug of the custom post type, respectively.
As a result, all pending posts and their children will be excluded from the view's output.
regards,
Waqar
Hi,
I have tried the code you have provided to me, but the view still shows the child posts of not published parent posts. What could be wrong?
Hi Dave,
Thanks for writing back.
Can you please share temporary admin login details for the website, where this view is set up?
I've set your next reply as private so that only you and our support team can access it.
Note: Please make a complete backup copy of the website, before sharing the access details.
regards,
Waqar
Hi Dave,
Thank you for sharing the admin access.
Looking into the website's setup, I've noticed that from "displays child posts" you meant posts in a post-relationship and not in a hierarchical relationship (within the same post type).
For such a case, you'll need to filter the view using the "toolset_get_related_posts" function:
https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_posts
Example:
add_filter( 'wpv_filter_query', 'filter_pending_status_fn', 1000 , 3 );
function filter_pending_status_fn( $query_args, $view_settings ) {
if ( !is_admin() && ( isset($view_settings['view_id']) && $view_settings['view_id'] == 1398) ) {
$post_type = "spolecnost";
$args = array(
'posts_per_page' => -1,
'post_type' => $post_type,
'post_status' => 'pending',
);
$posts_array = get_posts( $args );
foreach ($posts_array as $post_array ) {
// get parent post in a relationship
$query_by_element = $post_array -> ID; // ID of post to get relationship from
$relationship = 'investice-spolecnosti'; // relationship slug
$query_by_role_name = 'parent'; // $query_by_element is a parent in this relation
$limit = 999999; // defaults
$offset = 0; // defaults
$args = array(); //nothing needed
$return = 'post_id'; // We want Post ID
$role_name_to_return = 'child'; // We want child.
$get_results = toolset_get_related_posts(
$query_by_element,
$relationship,
$query_by_role_name,
$limit,
$offset,
$args,
$return,
$role_name_to_return
);
foreach ($get_results as $get_result ) {
$query_args['post__not_in'][] = $get_result;
}
}
}
return $query_args;
}
The above example snippet first gets all "pending" status "spolecnost" posts and then finds any related "investice" posts, to exclude them.
Note: The custom code snippets that we provide are to give an idea and example of the usage of Toolset functions. For step-by-step troubleshooting and 1-1 personalized assistance around custom code, we recommend hiring a professional from our list of recommended contractors:
https://toolset.com/contractors/
regards,
Waqar