WP_Query Pagination บน single-custom.php


16

สิ่งที่ฉันต้องการทำ:

ตั้งค่าการให้WP_Queryเลขหน้าในไฟล์เทมเพลต

สิ่งที่ฉันทำ

1) สร้างประเภทโพสต์ชื่อ "ผู้เขียน" แต่ละโพสต์ภายในประเภทโพสต์นั้นเป็นผู้เขียนแต่ละคน

2) หน้าจอแก้ไขโพสต์มาตรฐานประกอบด้วยดรอปดาวน์ซึ่งแสดงรายการโพสต์ทั้งหมด (ผู้เขียน) จากประเภทโพสต์ที่กำหนดเองของผู้เขียน

3) สร้างเทมเพลตเดียว author.php ซึ่งแบบสอบถามทั้งหมดของโพสต์กับผู้เขียนเมตาดาต้าจากดรอปดาวน์ดังนั้นผลลัพธ์คือรายการของโพสต์ที่มีผู้เขียนคนเดียวกันที่กำหนดให้กับพวกเขา

<?php

// set the "paged" parameter (use 'page' if the query is on a static front page)
global $paged;

/*We need this here to add and maintain Pagination if Template is assigned to Front Page*/
if ( get_query_var( 'paged' ) ) {
    $paged = get_query_var('paged');
} elseif ( get_query_var( 'page' ) ) {
    $paged = get_query_var( 'page' );
} else {
    $paged = 1;
}

$args = array(
    'posts_per_page'    =>  10,
    'meta_key'          => 'author_select',
    'meta_value'        => $author_id,
    'paged'             => $paged,
);

$temp = $wp_query;
$wp_query = NULL;

$wp_query = new WP_Query($args);

?>

<?php if( $wp_query->have_posts() ) : ?>    
    <?php while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>
    <?php // Successfully outputs the results of the above query, so I've omitted the code from this example. ?>

    <?php endwhile; ?>

<div class="single_navigation"> 
    <?php if( get_adjacent_post( false, '', true ) ) { ?>
        <span class="prev"><?php previous_post_link( '&lt; %link' ) ?></span>
    <?php } ?>

    <?php if( get_adjacent_post( false, '', false ) ) { ?>
        <span class="next"><?php next_post_link( '%link &gt;' ) ?></span>
    <?php } ?>
    </div><!--/single navigation-->
<?php endif; ?>

<?php
    $wp_query = null;
    $wp_query = $temp;
    wp_reset_query();
?>

สิ่งที่ฉันติดอยู่

ลิงค์เลขหน้าไม่ปรากฏขึ้น ฉันได้ทำการวิจัยแล้วและพบว่าพวกเขาใช้$wp_queryตัวแปรอย่างไรก็ตามเมื่อฉันเปลี่ยนตัวแปรคิว$wp_queryรีเป็นลิงก์ปรากฏขึ้น แต่เมื่อคลิกแล้วก็ไม่ได้ทำอะไรเลย

ความคิดใดที่ฉันจะผิด

แก้ไข:

เพื่อตอบคำถามของคุณแบบสอบถามของฉันส่งออกโพสต์ที่ฉันกำลังสืบค้นเรียบร้อยแล้ว $ author_id มีค่าที่ฉันไม่ได้รวมไว้ในข้อมูลโค้ดนี้แล้ว ฉันออกจากเนื้อหาจริงในขณะที่วนรอบเพราะส่วนนั้นไม่ใช่ปัญหา ปัญหาคือฉันต้องแบ่งหน้าเนื้อหาที่มีอยู่แล้วในโพสต์เดียวนี้

วัตถุประสงค์ของฟังก์ชั่นนี้คืออนุญาตให้โพสต์มีผู้แต่งเอง (นอกระบบผู้ใช้) และจุดประสงค์ของเทมเพลตนี้คือส่งออกโพสต์ทั้งหมดสำหรับผู้แต่งที่กำหนด (ซึ่งทำงานแล้ว)


3
upvote สำหรับคำถามที่มีรูปแบบที่ดีแม้ว่าคุณจะไม่ได้อธิบายว่าทำไมคุณถึงทำเช่นนี้มันเป็นบทความที่เกี่ยวข้องโดยกล่องผู้เขียนปัจจุบันหรือไม่?
Tom J Nowell

1
ฉันเห็นด้วยกับ @TomJNowell จริงๆ +1
Pieter Goosen

2
ไม่เกี่ยวข้อง แต่ไม่จำเป็นที่จะต้องสะท้อนthe_title()
Pieter Goosen

2
เป็น'meta_value' => $author_idกำลังเต็มไปจากเมนูแบบเลื่อนดังกล่าว? และเมื่อเลือกผู้แต่งแต่ละคนผ่านทางดรอปดาวน์สิบโพสต์แรกจะแสดงอย่างถูกต้องหรือไม่
สตีเฟ่นเอส

1
คุณแน่ใจหรือไม่ว่าการ$author_query->have_posts()ส่งคืนtrueและการ$author_queryโพสต์นั้นมีจริงหรือไม่?
ไกเซอร์

คำตอบ:


17

คุณมี 2 ปัญหา

ปัญหาแรก

เส้น

$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;

จะล้มเหลวเพราะในมุมมองโพสต์เอกพจน์เมื่อ URL ที่มี'/page/XX/'ตัวแปรชุด WordPress เป็นและไม่ได้'page''paged'

คุณอาจคิดว่าจะใช้'page'แทน'paged'แต่นั่นจะไม่ได้ผลเช่นกันเพราะเมื่อ'page'ตัวแปรนี้มีวัตถุประสงค์เพื่อใช้สำหรับโพสต์เอกพจน์หลายหน้า (การแยกหน้าโดยใช้<!--nextpage-->) และเมื่อโพสต์นั้นไม่ใช่หลายหน้า WordPress จะเปลี่ยนเส้นทางคำขอ ไปยัง URL '/page/XX/'โดยไม่ต้อง

นี่คือสิ่งที่เกิดขึ้นเมื่อคุณตั้งชื่อตัวแปรคิวรีของ$wp_queryคุณ

วิธีแก้ไขคือป้องกันการเปลี่ยนเส้นทางนั้นโดยการลบฟังก์ชั่นที่รับผิดชอบซึ่ง'redirect_canonical'ติดไว้ใน'template_redirect':

ดังนั้นในการfunctions.phpเพิ่มของคุณ:

add_action( 'template_redirect', function() {
    if ( is_singular( 'authors' ) ) {
        global $wp_query;
        $page = ( int ) $wp_query->get( 'page' );
        if ( $page > 1 ) {
            // convert 'page' to 'paged'
            $wp_query->set( 'page', 1 );
            $wp_query->set( 'paged', $page );
        }
        // prevent redirect
        remove_action( 'template_redirect', 'redirect_canonical' );
    }
}, 0 ); // on priority 0 to remove 'redirect_canonical' added with priority 10

ตอนนี้ WordPress จะไม่เปลี่ยนเส้นทางอีกต่อไปและจะตั้งค่า'paged'var แบบสอบถามอย่างถูกต้อง

ปัญหาที่สอง

next_posts_link()และprevious_posts_link()ตรวจสอบทั้งคู่if ( ! is_single() )เพื่อแสดงเลขหน้า

ตอนนี้is_single()เป็นจริงในกรณีของคุณเพราะคุณอยู่ในโพสต์เดียวของประเภท 'ผู้เขียน' ดังนั้นฟังก์ชั่นเหล่านั้นไม่สามารถทำงานได้ตามที่คุณคาดหวัง

คุณมี 3 ความเป็นไปได้:

  1. ใช้query_postsเพื่อแทนที่การสืบค้นหลัก ( ไม่แนะนำจริงๆ)
  2. ใช้เทมเพลตหน้าเว็บที่กำหนดเองแทนประเภทโพสต์ที่กำหนดเองเพราะis_single()เป็นเท็จสำหรับหน้าและรหัสของคุณจะทำงานที่นั่น
  3. เขียนฟังก์ชันการให้เลขหน้าของคุณเองและใช้สิ่งนั้น

นั่นคือรหัสสำหรับหมายเลขโซลูชัน # 3:

function my_pagination_link( $label = NULL, $dir = 'next', WP_Query $query = NULL ) {
    if ( is_null( $query ) ) {
        $query = $GLOBALS['wp_query'];
    }
    $max_page = ( int ) $query->max_num_pages;
    // only one page for the query, do nothing
    if ( $max_page <= 1 ) {
        return;
    }
    $paged = ( int ) $query->get( 'paged' );
    if ( empty( $paged ) ) {
        $paged = 1;
    }
    $target_page = $dir === 'next' ?  $paged + 1 : $paged - 1;
    // if 1st page requiring previous or last page requiring next, do nothing
    if ( $target_page < 1 || $target_page > $max_page ) {
        return;
    }
    if ( null === $label ) {
        $label = __( 'Next Page &raquo;' );
    }

    $label = preg_replace( '/&([^#])(?![a-z]{1,8};)/i', '&#038;$1', $label );
    printf( '<a href="%s">%s</a>', get_pagenum_link( $target_page ), esc_html( $label ) );
}

และใช้มันอย่างนั้นในsingle-authors.php:

my_pagination_link( 'Older Entries', 'next', $author_query );
my_pagination_link( 'Newer Entries', 'prev', $author_query );

คำตอบโดยละเอียดมากขอบคุณ! สิ่งนี้ใช้ได้กับไซต์ภาษาอังกฤษ แต่ในภาษาฝรั่งเศสลิงก์การแบ่งหน้าไม่ได้ทำอะไรพวกเขาจะรีเฟรชหน้าเท่านั้น ฉันใช้ WPML
เชน

1
@Shane ดูเหมือนว่า WPML จะเรียกใช้ตัวกรองบางอย่างที่ป้องกันไม่ให้โค้ดทำงาน แต่เป็นปลั๊กอินที่มีขนาดใหญ่มากดังนั้นฉันจึงไม่สามารถขุดโค้ดหลายพันบรรทัดเพื่อทำความเข้าใจว่าคำสารภาพนั้นอยู่ที่ไหน ลองถามฝ่ายสนับสนุน WPML
gmazzap

@Shane ฟอรัมสนับสนุน WPML - และหากด้านบนใช้งานได้ (ซึ่งฉันถือว่า) โปรดทำเครื่องหมายเป็นวิธีแก้ปัญหา ความขัดแย้ง WPML อยู่นอกหัวข้อ / ไม่อยู่ในขอบเขตของไซต์นี้อยู่แล้ว
ไกเซอร์

คำตอบที่ยอดเยี่ยมส่วนใหญ่เป็นเพราะมันช่วยให้ฉันแก้ไขปัญหาเลขหน้าของฉัน ฉันทำงานที่คล้ายกันและสร้าง WP_Query อันที่สองเพื่อวนซ้ำ ฉันโทรthe_posts_paginationแต่ต้องนำสำเนาต้นฉบับ wp_query ตามที่ระบุไว้ในคำถามนี้: wordpress.stackexchange.com/questions/216821/ …
Alexander Holsgrove

1
คุณถูกต้อง @HongPong คงที่ขอบคุณ
gmazzap

0

จากคำถาม WPSE อื่นที่คล้ายกัน "การแบ่งหน้าไม่ทำงานค่าฟิลด์ที่กำหนดเอง wp_query " ฉันขอแนะนำให้เพิ่มglobal $paged;ไปยังจุดเริ่มต้นของไฟล์เทมเพลตของคุณ:

global $paged;
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;

1
ขอบคุณสำหรับคำตอบ! น่าเสียดายที่มันไม่ได้สร้างความแตกต่าง ลิงค์เลขหน้าไม่ปรากฏ
เชน

1
สตีเฟ่นทำไมจึงต้องช่วย ใช่สิ่งนี้จะนำมาจากบริบทของโลก แต่จนถึงขณะนี้คุณไม่ได้ทำอะไรกับมัน $GLOBALS['paged'] = get_query_var( 'paged' );หากคุณต้องการที่จะแทนที่ทั่วโลกใช้แล้ว อื่นเพียงใช้เนื้อหากลม
ไกเซอร์

@Shane Hmm หน้าเทมเพลตที่ใช้เป็นหน้าคงที่หรือไม่
สตีเฟ่นเอส

ไม่มันถูกใช้เป็นเทมเพลตโพสต์เดียวสำหรับประเภทโพสต์ที่กำหนดเอง ฉันลองเปลี่ยนคำถามจากเป็น$author_queryเป็น$wp_queryและดูเหมือนว่าการแบ่งหน้าปรากฏ แต่เมื่อฉันคลิกที่หน้าเพจจะรีเฟรชและไม่ได้ไปที่หน้าถัดไปแม้ว่าจะมีหลายหน้าก็ตาม ฉันได้อัปเดตคำตอบเพื่อให้สอดคล้องกับการเปลี่ยนแปลงเหล่านั้นแล้ว
เชน

1
คำอธิบาย php.netไม่ได้เลวร้ายที่ ผมขอแนะนำให้เป็นเพียงการเล่นรอบด้วยและglobal $GLOBALSบิตของvar_dump()ฟังก์ชั่นบางอย่างและคุณกำลังดี หากต้องการทำความเข้าใจกับลอง / ข้อผิดพลาดเล็กน้อยคุณจะต้องลอง ต้องการครึ่งชั่วโมง สิ่งนี้จะช่วยให้คุณเข้าใจฟังก์ชันและคลาสได้ดียิ่งขึ้นรวมถึงวิธี OOP โดยรวมด้วย และจะนำคุณเข้าใกล้การทำความเข้าใจกับเนมสเปซได้อย่างชัดเจน :)
ไกเซอร์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.