Phân trang WP_Query trên một tùy chỉnh.php


16

Những gì tôi đang tìm kiếm để làm:

Thiết lập WP_Queryphân trang trong tệp mẫu đơn tùy chỉnh-post-type.php

Những gì tôi đã làm xong

1) Tạo một loại bài được gọi là "tác giả". Mỗi bài viết trong loại bài đăng đó là một tác giả.

2) Các trang màn hình bài chỉnh sửa tiêu chuẩn chứa danh sách thả xuống liệt kê tất cả các bài đăng (tác giả) từ loại bài đăng tùy chỉnh của tác giả.

3) Tạo một mẫu tác giả duy nhất truy vấn tất cả các bài đăng với siêu dữ liệu của tác giả từ danh sách thả xuống, do đó, kết quả là một danh sách các bài đăng có cùng tác giả được gán cho chúng (giống như một kho lưu trữ):

<?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();
?>

Những gì tôi đang bị mắc kẹt trên

Các liên kết phân trang không xuất hiện. Tôi đã thực hiện một số nghiên cứu và nhận thấy rằng họ sử dụng $wp_querybiến này, tuy nhiên khi tôi thay đổi biến truy vấn của mình thành $wp_query, các liên kết xuất hiện, nhưng khi nhấp vào không làm gì cả.

Bất cứ ý tưởng nơi tôi đang đi sai?

Biên tập:

Để trả lời một số câu hỏi của bạn, truy vấn của tôi xuất thành công các bài đăng mà tôi đang truy vấn, $ Author_id đã có một giá trị mà tôi không bao gồm trong đoạn mã này. Tương tự, tôi bỏ qua đầu ra nội dung thực tế trong vòng lặp while vì phần đó không phải là vấn đề. Vấn đề là tôi cần phân trang nội dung đã tồn tại trên bài đăng này.

Mục đích của chức năng này là cho phép các bài đăng có tác giả tùy chỉnh (bên ngoài hệ thống Người dùng tích hợp) và mục đích của mẫu này là để xuất tất cả các bài đăng cho một tác giả nhất định (hiện đang hoạt động).


3
Một upvote cho một câu hỏi được định dạng tốt, mặc dù bạn không mô tả lý do tại sao bạn làm điều này, nó có phải là một bài viết liên quan của hộp tác giả hiện tại không?
Tom J Nowell

1
Tôi thực sự đồng ý với @TomJNowell. +1
Pieter Goosen

2
Không liên quan, nhưng không cần thiết phải lặp lạithe_title()
Pieter Goosen

2
'meta_value' => $author_idđược điền từ thả xuống được đề cập? Và khi chọn từng tác giả thông qua danh sách thả xuống, mười bài đăng đầu tiên có hiển thị chính xác không?
Stephen S.

1
Bạn đã chắc chắn rằng $author_query->have_posts()trả về true$author_querythực sự có chứa bất kỳ bài viết?
kaiser

Câu trả lời:


17

Bạn có 2 vấn đề.

Vấn đề đầu tiên

Dòng

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

sẽ thất bại, bởi vì trên chế độ xem bài đăng đơn lẻ, khi URL chứa '/page/XX/', các bộ WordPress biến 'page'và không 'paged'.

Bạn có thể nghĩ sử dụng 'page'thay vì 'paged', nhưng điều đó cũng không hoạt động, bởi vì một khi 'page'biến được dự định sẽ được sử dụng cho bài đăng đơn lẻ nhiều trang (sử dụng phân tách trang <!--nextpage-->) và một khi bài đăng không có nhiều trang, WordPress sẽ chuyển hướng yêu cầu đến URL mà không có '/page/XX/'.

Đây là những gì xảy ra khi bạn đặt tên cho biến truy vấn của bạn $wp_query.

Giải pháp là ngăn chặn sự chuyển hướng đó bằng cách loại bỏ chức năng chịu trách nhiệm cho nó, được 'redirect_canonical'nối vào 'template_redirect':

Vì vậy, trong functions.phpadd của bạn :

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

Bây giờ WordPress sẽ không chuyển hướng nữa và sẽ đặt chính xác 'paged'var truy vấn.

Vấn đề thứ hai

next_posts_link()previous_posts_link()cả hai kiểm tra if ( ! is_single() )để hiển thị phân trang.

Bây giờ, is_single()là đúng trong trường hợp của bạn, bởi vì bạn đang ở trong một bài đăng thuộc loại 'tác giả', vì vậy những chức năng đó không thể hoạt động như bạn mong đợi.

Bạn có 3 khả năng:

  1. Sử dụng query_postsđể ghi đè truy vấn chính (thực sự không được đề xuất)
  2. Sử dụng mẫu trang tùy chỉnh thay vì loại bài đăng tùy chỉnh, vì is_single()sai cho các trang và mã của bạn sẽ hoạt động ở đó.
  3. Viết hàm phân trang của riêng bạn và sử dụng hàm đó

Đó là mã cho giải pháp số 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 ) );
}

và sử dụng nó như vậy trong single-authors.php:

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

Câu trả lời rất chi tiết, cảm ơn bạn! Điều này đang làm việc cho phía tiếng Anh của trang web, nhưng về phía Pháp, các liên kết phân trang không làm gì cả, họ chỉ làm mới trang. Tôi đang sử dụng WPML.
Shane

1
@Shane có vẻ như WPML chạy một số bộ lọc ngăn mã hoạt động. Nhưng là một plugin rất lớn và vì vậy tôi không thể đào hàng ngàn dòng mã để hiểu đâu là bản cáo trạng. Hãy thử hỏi hỗ trợ WPML.
gmazzap

@Shane Các diễn đàn Hỗ trợ WPML - và nếu ở trên hoạt động cho (mà tôi giả sử), thì vui lòng đánh dấu nó là giải pháp. Xung đột WPML không có chủ đề / ngoài phạm vi của trang web này.
kaiser

Câu trả lời tuyệt vời, chủ yếu là vì nó giúp tôi khắc phục vấn đề phân trang. Tôi đã làm một nhiệm vụ tương tự và đã tạo một WP_Query thứ hai để lặp lại. Tôi đã gọi the_posts_paginationnhưng phải lấy một bản sao của wp_query ban đầu như được nêu trong câu hỏi này: wordpress.stackexchange.com/questions/216821/
Alexander Holsgrove

1
Bạn đã đúng @HongPong, đã sửa, cảm ơn.
gmazzap

0

Dựa trên một câu hỏi tương tự khác của WPSE "Phân trang không hoạt động với các giá trị trường tùy chỉnh wp_query ", tôi khuyên bạn nên thêm global $paged;vào phần đầu của tệp mẫu của bạn:

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

1
Cảm ơn vì sự trả lời! Thật không may, nó dường như không làm cho bất kỳ sự khác biệt. Các liên kết phân trang không xuất hiện
Shane

1
Stephen, tại sao phải giúp đỡ? Vâng, điều này sẽ mang nó đến từ bối cảnh toàn cầu, nhưng cho đến nay bạn không làm gì với nó. Nếu bạn muốn ghi đè toàn cầu, sau đó sử dụng $GLOBALS['paged'] = get_query_var( 'paged' );. Khác chỉ sử dụng nội dung toàn cầu.
kaiser

@Shane Hmm, trang mẫu có được sử dụng làm trang trước tĩnh không?
Stephen S.

Không, nó chỉ được sử dụng như một mẫu bài đăng duy nhất cho loại bài đăng tùy chỉnh. Tôi đã thử thay đổi truy vấn của tôi từ $author_queryđến $wp_queryvà đó dường như làm cho pagination xuất hiện, nhưng khi tôi bấm vào nó làm mới trang và không thực sự đi đến trang tiếp theo, mặc dù có rất nhiều trang. Tôi đã cập nhật câu trả lời của mình để phản ánh những thay đổi đó.
Shane

1
Giải thích về php.net không phải là xấu. Tôi khuyên bạn chỉ nên chơi xung quanh với global$GLOBALS. Một chút var_dump(), một số chức năng và bạn ổn. Để thực sự hiểu nó với một chút thử / lỗi, bạn sẽ xấp xỉ. Cần nửa tiếng. Điều này sẽ giúp bạn hiểu rõ hơn về các chức năng so với các lớp và toàn bộ cách tiếp cận OOP. Và rõ ràng nó sẽ đưa bạn đến gần hơn để hiểu các không gian tên :)
kaiser
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.