Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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?

share|improve this question
    
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 '12 at 2:30
    
Your guess was correct. Iv'e updated the question. –  Will Dec 13 '12 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 '12 at 11:49

2 Answers 2

up vote 5 down vote accepted

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' );
share|improve this answer
2  
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 '13 at 20:25
    
Thanks, Iv'e updated the answer –  Will Mar 6 '13 at 21:35

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');
}
share|improve this answer
    
I prefer to add the filters in add_action('admin_head-edit.php, 'callback'), like here. –  brasofilo Dec 13 '12 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 '12 at 4:30
    
I think it's because [cat] => 18 does not have any article with issue == 171. –  Max Yudin Dec 14 '12 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 '12 at 5:06

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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