Phân trang tùy chỉnh cho các loại bài tùy chỉnh (theo tên)


10

Tôi có hai loại bài đăng tùy chỉnh liên quan đến tên của mọi người. Ngay bây giờ, trong các chế độ xem, nó chỉ liệt kê tất cả theo thứ tự bảng chữ cái và phân trang chia nhỏ chúng theo số, điều này không hữu ích lắm khi bạn đang cố gắng tìm một người cụ thể.

Cụ thể, tôi đã được yêu cầu tạo liên kết phân trang cho những người trông như thế này:

  • AG
  • HM
  • NQ
  • RQ

Vấn đề của tôi - Tôi không thể tìm ra cách tôi có thể truy vấn các loại bài đăng tùy chỉnh bằng chữ cái đầu tiên của một trường. Sau đó, tôi không chắc làm thế nào tôi có thể tạo ra phân trang theo cách này. Không ai có bất cứ đề nghị? Cảm ơn bạn!


Thật thú vị .. Tôi sẽ cho nó một shot nhưng không sớm. Tôi có một khe miễn phí sau vài ngày. Hãy chia sẻ giải pháp của bạn nếu bạn tìm thấy bất cứ điều gì trước đó. Chỉ cần bắt đầu nhìn vào bộ lọc records_where để sửa đổi tra cứu và thực hiện phân trang, bạn cần chơi với các quy tắc viết lại, hãy xem truy vấn truy vấn, query_posts và lớp WP_Rewrite. Tôi chắc chắn bạn sẽ đóng đinh nó với những điều này.
Hameedullah Khan

@ mckeodm3 Vậy sao ??
kaiser

Câu trả lời:


4

Câu hỏi thú vị! Tôi đã giải quyết nó bằng cách mở rộng WHEREtruy vấn bằng một loạt các post_title LIKE 'A%' OR post_title LIKE 'B%' ...mệnh đề. Bạn cũng có thể sử dụng biểu thức chính quy để thực hiện tìm kiếm phạm vi, nhưng tôi tin rằng cơ sở dữ liệu sẽ không thể sử dụng một chỉ mục sau đó.

Đây là cốt lõi của giải pháp: một bộ lọc về WHEREmệnh đề:

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;
}

Tất nhiên bạn không muốn cho phép đầu vào bên ngoài ngẫu nhiên trong truy vấn của mình. Đó là lý do tại sao tôi có một bước khử trùng đầu vào pre_get_posts, trong đó chuyển đổi hai biến truy vấn thành một phạm vi hợp lệ. (Nếu bạn tìm được cách phá vỡ điều này, vui lòng để lại nhận xét để tôi có thể sửa nó)

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 ) );
    }
}

Bước cuối cùng là tạo một quy tắc viết lại khá đẹp để bạn có thể đi đến example.com/posts/a-g/hoặc example.com/posts/axem tất cả các bài đăng bắt đầu bằng (phạm vi) chữ cái này.

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;
}

Bạn có thể thay đổi mẫu quy tắc viết lại để bắt đầu với một cái gì đó khác. Nếu đây là loại bài đăng tùy chỉnh, hãy chắc chắn để thêm &post_type=your_custom_post_typevào thay thế (chuỗi thứ hai, bắt đầu bằng index.php).

Thêm liên kết phân trang được để lại như một bài tập cho người đọc :-)


Chỉ là một gợi ý: like_escape():)
kaiser

3

Điều này sẽ giúp bạn bắt đầu. Tôi không biết làm thế nào bạn có thể phá vỡ truy vấn tại một chữ cái cụ thể và sau đó nói với WP rằng có một trang khác có nhiều chữ cái hơn, nhưng phần sau chiếm 99% phần còn lại.

Đừng quên đăng giải pháp của bạn!

query_posts( array( 'orderby' => 'title' ) );

// Build an alphabet array
foreach( range( 'A', 'G' ) as $letter )
    $alphabet[] = $letter;

foreach( range( 'H', 'M' ) as $letter )
    $alphabet[] = $letter;

foreach( range( 'N', 'Q' ) as $letter )
    $alphabet[] = $letter;

foreach( range( 'R', 'Z' ) as $letter )
    $alphabet[] = $letter;

if ( have_posts() ) 
{
    while ( have_posts() )
    {
        global $wp_query, $post;
        $max_paged = $wp_query->query_vars['max_num_pages'];
        $paged = $wp_query->query_vars['paged'];
        if ( ! $paged )
            $paged = (int) 1;

        the_post();

        $first_title_letter = (string) substr( $post->post_title, 1 );

        if ( in_array( $first_title_letter, $alphabet ) )
        {
            // DO STUFF
        }

        // Pagination
        if ( $paged !== (int) 1 )
        {
            echo 'First: '._wp_link_page( 1 );
            echo 'Prev: '._wp_link_page( $paged - 1 );
        }
        while ( $i = 1; count($alphabet) < $max_paged; i++; )
        {
            echo $i._wp_link_page( $i );
        }
        if ( $paged !== $max_paged )
        {
            echo 'Next: '._wp_link_page( $paged + 1 );
            echo 'Last: '._wp_link_page( $max_paged );
        }
    } // endwhile;
} // endif;

Nó không được thử nghiệm.
kaiser

2

Câu trả lời sử dụng ví dụ của @ kaiser, với loại bài đăng tùy chỉnh làm chức năng chấp nhận thông số bắt đầu và kết thúc alpha. Ví dụ này rõ ràng là cho một danh sách ngắn các mục, vì nó không bao gồm phân trang phụ. Tôi đang đăng nó để bạn có thể kết hợp khái niệm này vào functions.phpnếu bạn muốn.

// Dr Alpha Paging
// Tyrus Christiana, Senior Developer, BFGInteractive.com
// Call like alphaPageDr( "A","d" );
function alphaPageDr( $start, $end ) {
    echo "Alpha Start";
    $loop = new WP_Query( 'post_type=physician&orderby=title&order=asc' );      
    // Build an alphabet array of capitalized letters from params
    foreach ( range( $start, $end ) as $letter )
        $alphabet[] = strtoupper( $letter );    
    if ( $loop->have_posts() ) {
        echo "Has Posts";
        while ( $loop->have_posts() ) : $loop->the_post();              
            // Filter by the first letter of the last name
            $first_last_name_letter = ( string ) substr( get_field( "last_name" ), 0, 1 );
            if ( in_array( $first_last_name_letter, $alphabet ) ) {         
                //Show things
                echo  "<img class='sidebar_main_thumb' src= '" . 
                    get_field( "thumbnail" ) . "' />";
                echo  "<div class='sidesbar_dr_name'>" . 
                    get_field( "salutation" ) . " " . 
                    get_field( 'first_name' ) . " " . 
                    get_field( 'last_name' ) . "</div>";
                echo  "<div class='sidesbar_primary_specialty ' > Primary Specialty : " . 
                    get_field( "primary_specialty" ) . "</div>";                
            }
        endwhile;
    }
}

1

Đây là một cách để làm điều này bằng cách sử dụng query_varsposts_wherecác bộ lọc:

public  function range_add($aVars) {
    $aVars[] = "range";
    return $aVars;
}
public  function range_where( $where, $args ) {
    if( !is_admin() ) {
        $range = ( isset($args->query_vars['range']) ? $args->query_vars['range'] : false );
        if( $range ) {
            $range = split(',',$range);
            $where .= "AND LEFT(wp_posts.post_title,1) BETWEEN '$range[0]' AND '$range[1]'";
        }
    }
    return $where;
}
add_filter( 'query_vars', array('atk','range_add') );
add_filter( 'posts_where' , array('atk','range_where') );

Souce: https://gist.github.com/3904986


0

Đây không phải là một câu trả lời, nhưng nhiều hơn một con trỏ đến một hướng để thực hiện. Điều này có thể sẽ phải được tùy chỉnh 100% - và sẽ được tham gia rất nhiều. Bạn sẽ cần tạo một truy vấn sql tùy chỉnh (sử dụng các lớp wpdb) và sau đó để phân trang, bạn sẽ chuyển các tham số này cho truy vấn tùy chỉnh của mình. Có lẽ bạn cũng cần phải tạo quy tắc viết lại mới cho việc này. Một số chức năng để xem xét:

add_rewrite_tag( '%byletter%', '([^/]+)');
add_permastruct( 'byletter', 'byletter' . '/%byletter%' );
$wp_rewrite->flush_rules();
paginate_links()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.