3

I have a custom post type "Article" which has a custom field "issue" that is the id number of a "issue" post type that i am selecting using a simple select box.

I want to add a drop down of issues to filter the article listing found here:

edit.php?post_type=article

Is this possible? Is this sort of thing documented anywhere? I have not been able to find documentation or examples.

what hooks are there to filter lists & add selects to the filter controls?

3
  • I believe you are referring to the filter in the screen edit.php?post_type=article, but guessing games are not nice, please explain better and add screenshots if necessary (editing the Question, not here in the comments). But more important, what have you tried?
    – brasofilo
    Dec 13, 2012 at 2:30
  • Your guess was correct. Iv'e updated the question.
    – Will
    Dec 13, 2012 at 3:41
  • Apart from Max's Answer bellow, check this wonderful post by Mike Schinkel: wordpress.stackexchange.com/a/582/12615
    – brasofilo
    Dec 13, 2012 at 11:49

2 Answers 2

8

I had to modify max answer to get the filter working. Renaming the select to issue_restrict_articles stopped it incorrectly filtering & kept the filter controls on the screen. posts_where filter and a SQL query to actually filter.

function restrict_articles_by_issue() {
    global $wpdb;
    $issues = $wpdb->get_col("
        SELECT DISTINCT meta_value
        FROM ". $wpdb->postmeta ."
        WHERE meta_key = 'issue'
        ORDER BY meta_value
    ");
    ?>
    <label for="issue">Issues:</label>
    <select name="issue_restrict_articles" id="issue">
        <option value="">Show all</option>
        <?php foreach ($issues as $issue) { ?>
        <option value="<?php echo esc_attr( $issue ); ?>" <?php if(isset($_GET['issue_restrict_articles']) && !empty($_GET['issue_restrict_articles']) ) selected($_GET['issue_restrict_articles'], $issue); ?>>
        <?php
          $issue   = get_post($issue);
          echo $issue->post_title;
        ?>
        </option>
        <?php } ?>
    </select>
    <?php
}
add_action('restrict_manage_posts','restrict_articles_by_issue');



function posts_where( $where ) {
    if( is_admin() ) {
        global $wpdb;       
        if ( isset( $_GET['issue_restrict_articles'] ) && !empty( $_GET['issue_restrict_articles'] ) && intval( $_GET['issue_restrict_articles'] ) != 0 ) {
            $issue_number = intval( $_GET['issue_restrict_articles'] );

            $where .= " AND ID IN (SELECT post_id FROM " . $wpdb->postmeta ." 
WHERE meta_key='issue' AND meta_value=$issue_number )";
        }
    }   
    return $where;
}
add_filter( 'posts_where' , 'posts_where' );
1
  • 3
    Appreciate the code. You may want to edit line 34 to use $wpdb->postmeta instead of hard-coding 'cmsdb_postmeta', as names of Wordpress's postmeta table can vary by installation.
    – Jay Neely
    Mar 6, 2013 at 20:25
3

Place following code in your theme functions.php.

function articlesIssuesRequestAdmin($request) {
    if( isset($_GET['issue']) && !empty($_GET['issue']) ) {
        $request['meta_key'] = 'issue';
        $request['meta_value'] = $_GET['issue'];
    }
    return $request;
}

function articlesIssuesRestrictManagePosts() {
    global $wpdb;
    $issues = $wpdb->get_col("
        SELECT DISTINCT meta_value
        FROM ". $wpdb->postmeta ."
        WHERE meta_key = 'issue'
        ORDER BY meta_value
    ");
    ?>
    <label for="issue">Issues:</label>
    <select name="issue" id="issue">
        <option value="">Show all</option>
        <?php foreach ($issues as $issue) { ?>
        <option value="<?php echo esc_attr( $issue ); ?>" <?php if(isset($_GET['issue']) && !empty($_GET['issue']) ) selected($_GET['issue'], $issue); ?>><?php echo esc_attr($issue); ?></option>
        <?php } ?>
    </select>
    <?php
}

if( is_admin() && isset($_GET['post_type']) && $_GET['post_type'] == 'articles' ) {
    add_filter('request', 'articlesIssuesRequestAdmin');
    add_filter('restrict_manage_posts', 'articlesIssuesRestrictManagePosts');
}
4
  • I prefer to add the filters in add_action('admin_head-edit.php, 'callback'), like here.
    – brasofilo
    Dec 13, 2012 at 11:46
  • Thanks. After a bit of fiddling I got the drop down to display correctly - but it doesn't return any records at all when an issue is chosen, with or without the request filter function. Is there any docs around that - how to effect the search done? The request returned from the filter is: Array ( [m] => 0 [cat] => 18 [s] => [paged] => 1 [post_type] => article [name] => 171 [posts_per_page] => 20 [meta_key] => issue [meta_value] => 171 )
    – Will
    Dec 14, 2012 at 4:30
  • I think it's because [cat] => 18 does not have any article with issue == 171.
    – Max Yudin
    Dec 14, 2012 at 8:27
  • No, there are articles. Something is going wrong - the filter boxes all disappear & no records are returned when they should be.
    – Will
    Dec 17, 2012 at 5:06

Your Answer

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

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