AFAIK that sort of hook does not exists. You have 2 choiches:
- use
'post_class'
filter hook, check if in admin and if the query string contain a shortcode and if so and if the post has not that shortcode addhidden
class that via core admin CSS is set todisplay: none
. In this way the posts without shortcode are retrieved, but hidden. - Second solution is to use a filter on
'posts_where'
and add a SQL where clause usingREGEXP
MySQL function in this way post are not retrieved
I prefer the second solution, that seems to me more elegant and performant, however, maybe the core has_shortcode
function is more reliable than a simple SQL regex.
Solution 1
add_filter( 'post_class', 'filter_posts_by_shortcode_css', 10, 3 );
function filter_posts_by_shortcode_css( $classes, $class, $postid ) {
if ( is_admin() ) {
$screen = get_current_screen();
$sh = filter_input( INPUT_GET, 'shortcode', FILTER_SANITIZE_STRING );
if ( ! empty( $sh ) && $screen->base === 'edit' ) {
$post = get_post( $postid );
if( ! has_shortcode( $post->post_content, $sh ) ) {
$classes[] = 'hidden';
}
}
}
return $classes;
}
Solution 2
add_action('posts_where', 'filter_posts_by_shortcode');
function filter_posts_by_shortcode( $where ) {
if ( is_admin() ) {
$screen = get_current_screen();
$sh = filter_input( INPUT_GET, 'shortcode', FILTER_SANITIZE_STRING );
if ( $screen->base === 'edit' && ! empty( $sh ) && shortcode_exists( $sh ) ) {
$where .= " AND post_content REGEXP '\\\[([[:blank:]]*)$sh([^\\\[]*)\\\]'";
}
}
return $where;
}
Please note that to make both solution work, the shortcode(s) must be registered via add_shortcode
, so if the shortcode(s) is(are) registered by yourself or by a third party plugin/theme, be sure that it/they is/are registered in admin screens and before the query happen.