如何通过自定义字段对WordPress自定义帖子类型的管理区域进行排序


52

编辑我的一种自定义帖子类型时,我希望能够通过一个自定义字段列出所有条目,而不是它们的发布日期(对于自定义帖子类型而言,这可能是不相关的)。我从有关自定义帖子类型的博客帖子的评论中得到线索,作者说这是可能的,甚至他做到了,因此您可以单击列名称进行自定义排序。他提到了posts_orderby我在自己的评论中指出的功能,但现在我可以找到该博客文章了。有什么建议么?我看到一种解决方案

add_action('wp', 'check_page');

而且该check_page函数用于add_filter更改查询,但是我敢肯定它只能在主题文件中使用,而不能在管理区域中使用。


1
这是另一个有用的答案,可以按.... <br/> wordpress.stackexchange.com/questions/66455/…
T.Todua 2014年

Answers:


66

正如您可能会想到的那样,由于缺少提供的答案,因此解决方案并非完全无关紧要。我所做的是创建一个自成体系的示例,该示例假定自定义帖子类型为“ movie”,而自定义字段键为“ 流派 ”。

免责声明:这适用于WP3.0,但我不确定它是否适用于早期版本。

基本上,您需要钩两(2)个钩才能使其正常工作,而另外需要两(2)个钩才能使其明显且有用。

第一个钩子是' restrict_manage_posts',它使您可以<select>在帖子列表上方的区域中发出HTML ,该列表中包含“ 批量操作 ”和“ 显示日期 ”过滤条件。提供的代码将生成如以下屏幕片段所示的“ Sort by: ”功能:

如何在WordPress管理员中为自定义帖子类型创建“排序依据”功能
(来源:mikeschinkel.com

该代码使用SQL直接,因为没有一个WordPress API函数来提供一个职位类型所有meta_keys的列表(听起来像一个未来的TRAC票给我...)总之,这里的代码。请注意,它从中获取帖子类型$_GET并进行验证,以确保它既是有效的帖子类型又post_type_exists()movie帖子类型(这两项检查过大,但是我这样做是为了向您展示如何不想让您-编码帖子类型。)最后,我使用sortbyURL参数,因为它与WordPress中的其他参数没有冲突:

add_action('restrict_manage_posts','restrict_manage_movie_sort_by_genre');
function restrict_manage_movie_sort_by_genre() {
    if (isset($_GET['post_type'])) {
        $post_type = $_GET['post_type'];
        if (post_type_exists($post_type) && $post_type=='movie') {
            global $wpdb;
            $sql=<<<SQL
SELECT pm.meta_key FROM {$wpdb->postmeta} pm
INNER JOIN {$wpdb->posts} p ON p.ID=pm.post_id
WHERE p.post_type='movie' AND pm.meta_key='Genre'
GROUP BY pm.meta_key
ORDER BY pm.meta_key
SQL;
            $results = $wpdb->get_results($sql);
            $html = array();
            $html[] = "<select id=\"sortby\" name=\"sortby\">";
            $html[] = "<option value=\"None\">No Sort</option>";
            $this_sort = $_GET['sortby'];
            foreach($results as $meta_key) {
                $default = ($this_sort==$meta_key->meta_key ? ' selected="selected"' : '');
                $value = esc_attr($meta_key->meta_key);
                $html[] = "<option value=\"{$meta_key->meta_key}\"$default>{$value}</option>";
            }
            $html[] = "</select>";
            echo "Sort by: " . implode("\n",$html);
        }
    }
}

第二个必需步骤是使用parse_query在WordPress确定一个查询应运行但在运行查询之前调用的挂钩。在这里,我们可以在查询的数组中设置orderby和的值,meta_key这些值记录在食典中的参数中。我们进行测试以确保:query_varorderbyquery_posts()

  1. 我们在管理员(is_admin())中,
  2. 我们在列出管理员($pagenow=='edit.php')中帖子的页面上,
  3. 该页面已使用post_type等于的URL参数进行了调用movie,并且
  4. 该页面也已使用sortbyURL参数进行了调用,并且未传递值“ None

如果所有的测试都通过了,我们再设置query_vars(如记录在这里),以meta_value我们sortby的“价值类型 ”:

add_filter( 'parse_query', 'sort_movie_by_meta_value' );
function sort_movie_by_meta_value($query) {
    global $pagenow;
    if (is_admin() && $pagenow=='edit.php' &&
        isset($_GET['post_type']) && $_GET['post_type']=='movie' && 
        isset($_GET['sortby'])  && $_GET['sortby'] !='None')  {
        $query->query_vars['orderby'] = 'meta_value';
        $query->query_vars['meta_key'] = $_GET['sortby'];
    }
}

这就是您要做的全部;没有“ posts_order”或“ wp”所需的挂钩!当然,您实际上确实需要做更多;您需要在页面上添加一些列来列出帖子,以便您可以实际查看其排序的值,否则用户会感到困惑。因此manage_{$post_type}_posts_columns,在这种情况下,请添加一个挂钩manage_movie_posts_columns。这个钩子传递了默认的列数组,为简单起见,我只用两个标准列替换了它。复选框(cb)和帖子名称(title)。(您可以使用进行检查posts_columnsprint_r()以查看默认情况下还有哪些可用。)

我决定为有URL参数和无URL参数时添加一个“ Sorted By: ” :sortbyNone

add_action('manage_movie_posts_columns', 'manage_movie_posts_columns');
function manage_movie_posts_columns($posts_columns) {
    $posts_columns = array(
        'cb' => $posts_columns['cb'],
        'title' => 'Movie Name',
        );
    if (isset($_GET['sortby']) && $_GET['sortby'] !='None') 
        $posts_columns['meta_value'] = 'Sorted By';

    return $posts_columns;
}

最后,我们使用manage_pages_custom_column钩时,有相应的职位类型的职位,并与可能的冗余测试实际显示的数值is_admin()$pagenow=='edit.php'。当存在sortbyURL参数时,我们提取自定义字段值,该值将通过显示在列表中进行排序。这是它的样子(请记住,这是测试数据,所以花生画廊对电影分类没有评论!:):

在WordPress管理员中为自定义帖子类型添加了自定义列
(来源:mikeschinkel.com

这是代码:

add_action('manage_pages_custom_column', 'manage_movie_pages_custom_column',10,2);
function manage_movie_pages_custom_column($column_name,$post_id) {
    global $pagenow;
    $post = get_post($post_id);
    if ($post->post_type=='movie' && is_admin() && $pagenow=='edit.php')  {
        switch ($column_name) {
            case 'meta_value':
                if (isset($_GET['sortby']) && $_GET['sortby'] !='None') {
                    echo get_post_meta($post_id,$_GET['sortby'],true);
                }
                break;
        }
    }
}

请注意,这只会为选取第一个“ 流派movie,即在给定键有多个值的情况下,第一个meta_value。但是话又说回来,我不确定它如何工作!

对于不熟悉此代码放置位置的用户,可以将其放置在插件中,或者对于新手,更可能将其放置functions.php在当前主题的文件中。

这有什么帮助。


2
+1,只是为了努力。但是,如果圈子是手绘的,那就更好 :-)
Jan Fabry

知道如何完全删除“显示所有日期”过滤器,以便仅显示给定帖子类型的自定义过滤器吗?
RailsTweeter 2014年

@RailsTweeter使用我在此处显示的技术,将HTML生成括起来的两个钩子分别位于'months_dropdown_results''restrict_manage_posts'。PS Upvotes始终受到赞赏。:)
MikeSchinkel

@MikeSchinkel,现在有了WP API,这会在某种程度上更新您的代码吗?
samjco

@samjco不确定。不幸的是,我目前没有时间修改此内容。
MikeSchinkel


-1

这是一个简单的解决方案:

/* --------Sortable Events on Dashboard - show start date, time, venue--------- */

/*-------------------------------------------------------------------------------
    Custom Columns
-------------------------------------------------------------------------------*/

function my_*YOUR POST TYPE*_columns($columns)
{
    $columns = array(
        'cb'        => '<input type="checkbox" />',
        'title'     => 'Title',
        'your_custom_field'     => 'Custom Field Name',          
        'date'      =>  'Date',
    );
    return $columns;
}

function my_custom_columns($column)
{
    global $post;
    if($column == 'your_custom_field')
    {
        if(get_post_meta($post->ID, 'your_custom_field', true);)
        {
            echo get_post_meta($post->ID, 'your_custom_field', true);
        }
    }

}

add_action("manage_posts_custom_column", "my_custom_columns");
add_filter("manage_edit-*YOUR POST TYPE*_columns", "my_events_columns");

/*-------------------------------------------------------------------------------
    Sortable Columns
-------------------------------------------------------------------------------*/

function my_column_register_sortable( $columns )
{
    $columns['your_custom_field'] = 'your_custom_field';
    return $columns;
}

add_filter("manage_edit-*YOUR POST TYPE*_sortable_columns", "my_column_register_sortable" );

只需替换您的POST TYPE'your_custom_field'

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.