这有点短,没有太多细节。我计划在某个时候再详细讨论这个问题。
然而,在短期内,这个解决方案应该完全满足您的需要。很明显,您需要对其进行扩展,但它做的是基础工作。
本例假设Post类型为mbe-members
Post类型的重写段塞为/member/
.
步骤1)添加自定义重写规则和查询变量
add_action( \'init\', function () {
add_rewrite_tag( \'%member-filter%\', \'members/filter/([a-zA-Z0-9-]{1,3})\', \'post_type=mbe-members&filter=\' );
add_permastruct( \'member-filter\', \'%member-filter%\', array( \'with_front\' => false ) );
} );
您需要确保在注册帖子类型之前执行此操作。
您还需要确保刷新重写规则。
Note: 为了目前非常简单,其余的任务将在Post-Type Archive主题模板文件中完成。(我以后会把这个部分做得更好)
步骤2)确定需要过滤的内容
$filter = get_query_var( \'filter\' );
$filter_start = null;
$filter_end = null;
if ( strpos( $filter, \'-\' ) !== false ) {
if ( $pieces = explode( \'-\', $filter ) ) {
if ( isset( $pieces[0] ) ) {
$filter_start = $pieces[0];
}
if ( isset( $pieces[1] ) ) {
$filter_end = $pieces[1];
}
}
} else {
$filter_start = substr( $filter, 0, 1 );
}
此筛选还允许一系列字母或数字。
答/答--您可以指定:/members/filter/a
或/members/filter/a-z/
步骤3)查询筛选匹配项的帖子ID
global $wpdb;
$post_ids = array();
if ( ! is_null( $filter_start ) && ! is_null( $filter_end ) ) {
$range = range( $filter_start, $filter_end );
foreach ( $range as $value ) {
$query_args = array(
\'SELECT\' => \'ID\',
\'FROM\' => $wpdb->posts,
\'WHERE\' => \'post_title\'
);
if ( $query = $wpdb->get_results( $wpdb->prepare( "
SELECT {$query_args[\'SELECT\']}
FROM {$query_args[\'FROM\']}
WHERE {$query_args[\'WHERE\']}
LIKE %s
AND post_type = %s
", "{$value}%", \'mbe-members\' ) ) ) {
foreach ( $query as $result ) {
if ( ! in_array( $result->ID, $post_ids ) ) {
$post_ids[] = $result->ID;
}
}
}
}
} else {
if ( ! is_null( $filter_start ) ) {
$value = $filter_start;
$query_args = array(
\'SELECT\' => \'ID\',
\'FROM\' => $wpdb->posts,
\'WHERE\' => \'post_title\',
);
if ( is_numeric( $value ) ) {
$query_args[\'LIKE\'] = \'%d\';
} else {
$query_args[\'LIKE\'] = \'%s\';
}
if ( $query = $wpdb->get_results( $wpdb->prepare( "
SELECT {$query_args[\'SELECT\']}
FROM {$query_args[\'FROM\']}
WHERE {$query_args[\'WHERE\']}
LIKE {$query_args[\'LIKE\']}
AND post_type = %s
", "{$value}%", "mbe-members" ) ) ) {
foreach ( $query as $result ) {
if ( ! in_array( $result->ID, $post_ids ) ) {
$post_ids[] = $result->ID;
}
}
}
}
}
步骤4)查询Post对象并输出显示
$content = \'\';
if ( ! empty( $post_ids ) ) {
$query = new \\WP_Query( array(
\'post_type\' => \'mbe-members\',
\'posts_per_page\' => absint( get_option( \'posts_per_page\' ) ),
\'post_status\' => \'publish\',
\'orderby\' => \'post_title\',
\'order\' => \'ASC\',
\'update_post_meta_cache\' => false,
\'update_post_term_cache\' => false,
\'suppress_filters\' => true,
\'post__in\' => $post_ids
) );
if ( $query->have_posts() ) {
foreach ( $query->posts as $post ) {
$content .= $post->post_title . \'<br />\';
}
}
}
echo \'<div>\' . PHP_EOL;
echo \'<ul class="nav nav-tabs" role="tablist">\' . PHP_EOL;
$class = \'\';
if ( $filter == \'0-9\' ) {
$class = \'active\';
}
echo \'<li role="presentation" class="\' . $class . \'"><a href="\' . site_url( \'/member/filter/0-9/\' ) . \'" aria-controls="0-9" role="tab">0-9</a></li>\' . PHP_EOL;
foreach ( range( \'a\', \'z\' ) as $letter ) {
$class = \'\';
if ( $letter == $filter_start ) {
$class = \'active\';
}
echo \'<li role="presentation" class="\' . $class . \'"><a href="\' . site_url( \'/member/filter/\' . $letter . \'/\' ) . \'" aria-controls="\' . $letter . \'" role="tab">\' . $letter . \'</a></li>\' . PHP_EOL;
}
echo \'</ul>\' . PHP_EOL;
echo \'<div class="tab-content">\' . PHP_EOL;
$class = \'\';
if ( $filter == \'0-9\' ) {
$class = \'active\';
}
echo \'<div role="tabpanel" class="tab-pane \' . $class . \'" id="0-9">\' . PHP_EOL;
if ( $filter == \'0-9\' ) {
echo $content;
}
echo \'</div>\' . PHP_EOL;
foreach ( range( \'a\', \'z\' ) as $letter ) {
$class = \'\';
if ( $letter == $filter_start ) {
$class = \'active\';
}
echo \'<div role="tabpanel" class="tab-pane \' . $class . \'" id="\' . $letter . \'">\' . PHP_EOL;
if ( $letter == $filter_start ) {
echo $content;
}
echo \'</div>\' . PHP_EOL;
}
echo \'</div>\' . PHP_EOL;
echo \'</div>\' . PHP_EOL;
结论就像我说的,这是一个很快的答案。这确实回答了你的问题。它非常粗糙和简单,但它能满足你的需要。我将尝试改进这个答案,使其更为优雅。