재미있는 질문! 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
.
페이지 매김 링크 추가는 독자의 연습으로 남아 있습니다 :-)