1

I need to filter the Posts and Pages tables in the Admin panel by certain shortcodes. In my plugin, I have added a column for shortcodes to the Posts and Pages views that works like the "Categories" and "Tags" columns, displaying a listing of shortcodes that are used in each post. Now I want to be able to click on one of the shortcodes in the column and have it filter the list of posts or pages to just the ones that use that shortcode.

In my custom column, I am outputting this: <a href="?shortcode=my-shortcode-1">[my-shortcode-1]</a>, <a href="?shortcode=my-shortcode-2">[my-shortcode-2]</a>, ...

I just need a filter that will make ?shortcode=... work. Here's basically what I have in mind, but I need to know what hook I could use to accomplish this:

add_filter( 'manage_posts_row', 'filter_by_shortcode' ); // I made up this filter

function filter_by_shortcode(){

    global $post; // Get the current post

    if(!empty($_GET['shortcode']){ // Check for ?shortcode=...

        // Check if given shortcode is used in the post
        if( has_shortcode( $post->post_content, $_GET['shortcode'] )
            return $post; // Return post if shortcode is found

        // Return nothing if shortcode is not used

    }else{
        return $post; // Return post if ?shortcode=... argument is not used
    }

}

Is there a hook that fires for each row of the show all Posts/Pages table in the Admin panel? Or is there another filter I can tie into for this?

2 Answers 2

0

AFAIK that sort of hook does not exists. You have 2 choiches:

  1. 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 add hidden class that via core admin CSS is set to display: none. In this way the posts without shortcode are retrieved, but hidden.
  2. Second solution is to use a filter on 'posts_where' and add a SQL where clause using REGEXP 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.

0
0

Use this filter to add a new column (http://codex.wordpress.org/Plugin_API/Filter_Reference/manage_posts_columns), then this filter to add content to it (http://codex.wordpress.org/Plugin_API/Action_Reference/manage_posts_custom_column) and with get_post($post_id) in it you can search for your shortcode.

3
  • I've actually already done that part. I've added the column and the content for the column. I now want to be able to click on a link in that column to filter the entire list. I'm looking for a hook that fires before executing a row in the table or another filter that will let me filter the list by content that has a given shortcode.
    – Matt
    Commented Mar 4, 2014 at 18:24
  • so then you could use pre_get_posts hook. codex.wordpress.org/Plugin_API/Action_Reference/…
    – Jonathan
    Commented Mar 4, 2014 at 19:20
  • I've used pre_get_posts before, but I don't know of a way to manipulate the query to exclude posts that have a particular shortcode in the post content. Is this possible?
    – Matt
    Commented Mar 4, 2014 at 21:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.