การแบ่งหน้าที่กำหนดเองสำหรับประเภทโพสต์ที่กำหนดเอง (ตามชื่อ)


10

ฉันมีโพสต์ที่กำหนดเองสองประเภทที่จัดการกับชื่อของผู้คน ตอนนี้ในมุมมองการเรียกดูมันจะแสดงรายการตามลำดับตัวอักษรทั้งหมดและการแบ่งหน้าแบ่งเป็นตัวเลขซึ่งไม่เป็นประโยชน์มากนักเมื่อคุณพยายามค้นหาบุคคลที่ต้องการ

โดยเฉพาะฉันถูกขอให้สร้างการเชื่อมโยงเลขหน้าสำหรับคนที่มีลักษณะเช่นนี้:

  • เอจี
  • HM
  • NQ
  • RQ

ปัญหาของฉัน - ฉันไม่สามารถหาวิธีที่ฉันสามารถสืบค้นประเภทโพสต์ที่กำหนดเองตามตัวอักษรตัวแรกของหนึ่งฟิลด์ จากนั้นฉันไม่แน่ใจว่าฉันจะสร้างการให้เลขหน้าด้วยวิธีนี้ได้อย่างไร ไม่มีใครมีข้อเสนอแนะใด ๆ ? ขอบคุณ!


ที่น่าสนใจ .. ฉันจะให้มันยิง แต่ไม่เร็วมาก ฉันมีช่องฟรีหลังจากสองสามวัน แชร์โซลูชันของคุณหากคุณพบสิ่งใดก่อนหน้านั้น เพียงเพื่อเริ่มดูตัวกรอง posts_where เพื่อปรับเปลี่ยนการค้นหาและเพื่อให้การแบ่งหน้าคุณต้องเล่นกับกฎการเขียนซ้ำให้ดูที่ query_vars, query_posts และ WP_Rewrite class ฉันแน่ใจว่าคุณจะจับมันด้วยสิ่งเหล่านี้
Hameedullah Khan

@ mckeodm3 งั้นเหรอ ??
ไกเซอร์

คำตอบ:


4

คำถามที่น่าสนใจ! ฉันแก้ไขมันด้วยการขยาย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)

เพิ่มลิงค์เลขหน้าจะเหลือเป็นแบบฝึกหัดสำหรับผู้อ่าน :-)


เพียงคำใบ้: like_escape():)
kaiser

3

สิ่งนี้จะช่วยคุณในการเริ่มต้น ฉันไม่รู้ว่าคุณจะแบ่งคำถามเป็นตัวอักษรที่เฉพาะเจาะจงแล้วบอก WP ว่ามีหน้าอื่นที่มีตัวอักษรมากขึ้น แต่ต่อไปนี้จะใช้เวลา 99% ของส่วนที่เหลือ

อย่าลืมโพสต์โซลูชั่นของคุณ!

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;

มันไม่ได้ทดสอบ
ไกเซอร์

2

คำตอบที่ใช้ตัวอย่างของ @ kaiser โดยมีประเภทโพสต์ที่กำหนดเองเป็นฟังก์ชั่นที่ยอมรับพารามิเตอร์เริ่มต้นและจุดสิ้นสุดของอัลฟา ตัวอย่างนี้ชัดเจนสำหรับรายการสั้น ๆ เนื่องจากไม่รวมเพจจิ้งรอง ฉันโพสต์ไว้เพื่อให้คุณสามารถรวมแนวคิดเข้ากับของคุณได้functions.phpหากคุณต้องการ

// 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

นี่คือวิธีในการทำเช่นนี้โดยใช้query_varsและposts_whereตัวกรอง:

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

นี่ไม่ใช่คำตอบที่มากนัก แต่จะมีตัวชี้ไปยังทิศทางที่ต้องการ สิ่งนี้อาจจะต้องเป็นแบบกำหนดเอง 100% และจะมีส่วนร่วมอย่างมาก คุณจะต้องสร้างข้อความค้นหา sql แบบกำหนดเอง (โดยใช้คลาส wpdb) จากนั้นสำหรับการแบ่งหน้าคุณจะต้องส่งพารามิเตอร์เหล่านี้ไปยังแบบสอบถามแบบกำหนดเองของคุณ คุณอาจต้องสร้างกฎการเขียนใหม่สำหรับสิ่งนี้เช่นกัน ฟังก์ชั่นบางอย่างที่ควรพิจารณา:

add_rewrite_tag( '%byletter%', '([^/]+)');
add_permastruct( 'byletter', 'byletter' . '/%byletter%' );
$wp_rewrite->flush_rules();
paginate_links()
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.