bounty将在6天后过期。回答此问题可获得+50声望奖励。AJT希望引起更多人关注此问题。
我设置了两种自定义帖子类型-“书籍”和“作者”。我使用的是自定义元数据,允许您通过选择框将书籍链接到作者(通过从作者帖子类型查询帖子来创建选择选项)。
这很好用,但我也尝试在帖子屏幕上为books帖子类型创建一个自定义过滤器,允许您按作者过滤,这不是预期的行为。
function book_filter() {
global $typenow;
global $wp_query;
if ( $typenow == 'book' ) {
$authors = new WP_Query(
array(
'post_type' => 'author',
'nopaging' => true
)
);
wp_reset_postdata();
/*
$authors = get_posts( array(
'post_type' => 'author',
'numberposts' => -1
));
*/
$current_author = '';
if( isset( $_GET['author'] ) ) {
$current_author = $_GET['author'];
} ?>
<select name="author" id="author">
<option value="all" <?php selected( 'all', $current_author ); ?>>All authors</option>
<?php
if ($authors->have_posts()) {
while ($authors->have_posts()) {
$authors->the_post();
if ($current_author == get_the_ID()) {
echo '<option value="' . get_the_ID() . '" selected>' . get_the_title() . '</option>';
} else {
echo '<option value="' . get_the_ID() . '">' . get_the_title() . '</option>';
}
}
}
/* foreach( $authors as $author ) { ?>
<option value="<?php echo $author->ID; ?>" <?php selected( $author->ID, $current_author ); ?>><?php echo get_the_title($author->ID); ?></option>
<?php } */
?>
</select>
<?php }
}
add_action( 'restrict_manage_posts', 'book_filter' );
function do_book_filter( $query ) {
global $pagenow;
$post_type = isset( $_GET['post_type'] ) ? $_GET['post_type'] : '';
if ( is_admin() && $pagenow=='edit.php' && $post_type == 'book' ) {
if (isset( $_GET['author'] ) && $_GET['author'] !='all' ) {
$query->query_vars['meta_key'] = 'author';
$query->query_vars['meta_value'] = $_GET['author'];
$query->query_vars['meta_compare'] = '=';
}
}
}
add_filter( 'parse_query', 'do_book_filter' );
最初,所有的作者都显示在过滤器中,选择一个作者来过滤确实有效。问题是,一旦过滤了,作者就从选择框下拉列表中消失了。我试着在else
中添加一条else
语句,这证实了在设置了过滤器后,它不会从authors post类型中获取帖子。
我还使用了另一个自定义过滤器(为了简单起见,从代码中删除了),它只使用了一个标准的数组变量,而不是查询,而且那个过滤器工作得很好,所以我猜它一定与自定义的post类型查询有关。
您将在代码中看到,我尝试了get_posts
(注解)以及WP_Query
,但它们都存在相同的问题。
我到底哪里错了?
2条答案
按热度按时间bvpmtnay1#
我认为问题可能是你在初始查询后使用了wp_reset_postdata()函数,它将全局变量$post重置为初始状态,这就是查询结果丢失的原因,所以当你在应用过滤器后循环$authors变量时,你会发现它是空的。
试着从book_filter()函数中删除wp_reset_postdata()行,这应该允许作者在初始查询之后仍然保留在$authors变量中,这样你就可以继续迭代它们来创建选择框的选项。
另一件事是在query_posts之后重新分配$authors,这样您就可以继续在过滤函数中使用$authors变量:
iaqfqrcu2#
你还可以做一些其他的事情,把设置$authors变量的代码移到do_book_filter函数中,这样它在每次过滤器被应用时都会重新运行,然后你可以使用这个更新的作者列表来填充book_filter函数中的选择框。