有趣的问题!我通过扩展WHERE
使用一组post_title LIKE \'A%\' OR post_title LIKE \'B%\' ...
条款。您也可以使用正则表达式进行范围搜索,但我相信数据库届时将无法使用索引。
这是解决方案的核心:在WHERE
条款:
add_filter( \'posts_where\', \'wpse18703_posts_where\', 10, 2 );
function wpse18703_posts_where( $where, &$wp_query )
{
if ( $letter_range = $wp_query->get( \'wpse18703_range\' ) ) {
global $wpdb;
$letter_clauses = array();
foreach ( $letter_range as $letter ) {
$letter_clauses[] = $wpdb->posts. \'.post_title LIKE \\\'\' . $letter . \'%\\\'\';
}
$where .= \' AND (\' . implode( \' OR \', $letter_clauses ) . \') \';
}
return $where;
}
当然,您不希望在查询中允许随机的外部输入。这就是为什么我有一个输入净化步骤
pre_get_posts
, 将两个查询变量转换为有效范围。(如果你想办法打破这一点,请留下评论,以便我可以更正)
add_action( \'pre_get_posts\', \'wpse18703_pre_get_posts\' );
function wpse18703_pre_get_posts( &$wp_query )
{
// Sanitize input
$first_letter = $wp_query->get( \'wpse18725_first_letter\' );
$last_letter = $wp_query->get( \'wpse18725_last_letter\' );
if ( $first_letter || $last_letter ) {
$first_letter = substr( strtoupper( $first_letter ), 0, 1 );
$last_letter = substr( strtoupper( $last_letter ), 0, 1 );
// Make sure the letters are valid
// If only one letter is valid use only that letter, not a range
if ( ! ( \'A\' <= $first_letter && $first_letter <= \'Z\' ) ) {
$first_letter = $last_letter;
}
if ( ! ( \'A\' <= $last_letter && $last_letter <= \'Z\' ) ) {
if ( $first_letter == $last_letter ) {
// None of the letters are valid, don\'t do a range query
return;
}
$last_letter = $first_letter;
}
$wp_query->set( \'posts_per_page\', -1 );
$wp_query->set( \'wpse18703_range\', range( $first_letter, $last_letter ) );
}
}
最后一步是创建一个非常好的重写规则,以便
example.com/posts/a-g/
或
example.com/posts/a
查看所有以此(一系列)字母开头的帖子。
add_action( \'init\', \'wpse18725_init\' );
function wpse18725_init()
{
add_rewrite_rule( \'posts/(\\w)(-(\\w))?/?\', \'index.php?wpse18725_first_letter=$matches[1]&wpse18725_last_letter=$matches[3]\', \'top\' );
}
add_filter( \'query_vars\', \'wpse18725_query_vars\' );
function wpse18725_query_vars( $query_vars )
{
$query_vars[] = \'wpse18725_first_letter\';
$query_vars[] = \'wpse18725_last_letter\';
return $query_vars;
}
您可以更改重写规则模式以从其他内容开始。如果这是自定义帖子类型,请确保添加
&post_type=your_custom_post_type
替换(第二个字符串,以开头
index.php
).
添加分页链接留作读者练习:-)