Pagination khusus untuk jenis posting khusus (berdasarkan nama)

10

Saya memiliki dua jenis pos kustom yang berhubungan dengan nama orang. Saat ini, dalam tampilan penelusuran, itu hanya mencantumkan semuanya secara alfabet dan pagination memecahnya berdasarkan angka, yang tidak terlalu membantu ketika Anda mencoba menemukan orang tertentu.

Secara khusus, saya diminta membuat tautan pagination untuk orang-orang yang terlihat seperti ini:

  • AG
  • HM
  • NQ
  • RQ

Masalah saya - Saya tidak tahu bagaimana saya bisa menanyakan jenis posting khusus dengan huruf pertama dari satu bidang. Kemudian, saya tidak yakin bagaimana cara membuat pagination dengan cara ini. Adakah yang punya saran? Terima kasih!

mcleodm3
sumber
Menarik .. Saya akan mencobanya tetapi tidak segera. Saya memiliki slot gratis setelah beberapa hari. Bagikan solusi Anda jika Anda menemukan sesuatu sebelum itu. Hanya untuk mulai melihat filter posts_where untuk memodifikasi pencarian dan untuk melakukan pagination yang Anda perlu mainkan dengan aturan penulisan ulang, lihatlah query_vars, query_posts dan kelas WP_Rewrite. Saya yakin Anda akan mengatasinya dengan hal-hal ini.
Hameedullah Khan
@ mckeodm3 Jadi apa ??
kaiser

Jawaban:

4

Pertanyaan menarik! Saya menyelesaikannya dengan memperluas WHEREkueri dengan sekelompok post_title LIKE 'A%' OR post_title LIKE 'B%' ...klausa. Anda juga dapat menggunakan ekspresi reguler untuk melakukan pencarian rentang, tetapi saya yakin database tidak akan dapat menggunakan indeks.

Ini adalah inti dari solusinya: filter pada WHEREklausa:

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

Tentu saja Anda tidak ingin mengizinkan input eksternal acak dalam permintaan Anda. Itulah sebabnya saya memiliki langkah sanitasi input pre_get_posts, yang mengubah dua variabel kueri menjadi rentang yang valid. (Jika Anda menemukan cara untuk memecahkan ini, silakan tinggalkan komentar sehingga saya dapat memperbaikinya)

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

Langkah terakhir adalah membuat aturan penulisan ulang yang cantik sehingga Anda dapat pergi ke example.com/posts/a-g/atau example.com/posts/auntuk melihat semua posting yang dimulai dengan huruf (kisaran) ini.

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

Anda dapat mengubah pola aturan penulisan ulang untuk memulai dengan hal lain. Jika ini untuk jenis posting kustom, pastikan untuk menambah &post_type=your_custom_post_typesubstitusi (string kedua, yang dimulai dengan index.php).

Menambahkan tautan pagination dibiarkan sebagai latihan untuk pembaca :-)

Jan Fabry
sumber
Sekedar petunjuk: like_escape():)
kaiser
3

Ini akan membantu Anda memulai. Saya tidak tahu bagaimana Anda akan memecah kueri pada surat tertentu dan kemudian memberi tahu WP bahwa ada halaman lain dengan lebih banyak surat, tetapi yang berikut mengambil 99% sisanya.

Jangan lupa untuk memposting solusi Anda!

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;
kaisar
sumber
Itu tidak diuji.
kaiser
2

Sebuah jawaban menggunakan contoh @ kaiser, dengan tipe posting khusus sebagai fungsi yang menerima alfa awal dan akhir params. Contoh ini jelas untuk daftar item pendek, karena tidak termasuk paging sekunder. Saya mempostingnya sehingga Anda dapat memasukkan konsep ke dalam Anda functions.phpjika Anda mau.

// 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;
    }
}
Tyrus
sumber
1

Ini cara untuk melakukannya dengan menggunakan query_varsdan posts_wherefilter:

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

Styledev
sumber
0

Ini bukan jawaban, tapi lebih ke arah yang harus diambil. Ini mungkin harus 100% khusus - dan akan sangat terlibat. Anda harus membuat kueri sql khusus (menggunakan kelas wpdb) dan kemudian untuk pagination Anda akan meneruskan parameter ini ke kueri khusus Anda. Anda mungkin juga perlu membuat aturan penulisan ulang baru untuk ini. Beberapa fungsi yang perlu diperhatikan:

add_rewrite_tag( '%byletter%', '([^/]+)');
add_permastruct( 'byletter', 'byletter' . '/%byletter%' );
$wp_rewrite->flush_rules();
paginate_links()
dwenaus
sumber