Phân trang với truy vấn SQL tùy chỉnh


9

Tôi có chuỗi SQL riêng để chọn các bài đăng Loại bài tùy chỉnh với mệnh đề WHERE cụ thể. Tôi đã sử dụng phần bù và giới hạn để trả về các bài đăng phù hợp tùy thuộc vào một trang được hiển thị. Điều đó làm việc tốt.

Bây giờ, tôi muốn làm cho previous_posts_link()và các next_posts_link()chức năng hoạt động. Cả hai đều được gọi từ get_posts_nav_linkđó sử dụng global $wp_query.

Có cách nào tôi có thể gán lại global $wp_queryvới chuỗi SQL hoặc $wpdb->get_resultskết quả của tôi hoặc bất cứ điều gì khác không? Vì vậy, các chức năng gốc previous_posts_link()next_posts_link()WP sẽ hoạt động.

Nếu không, làm thế nào tôi có thể tái tạo các chức năng liên kết bài trước và tiếp theo?

Tôi thực sự sẽ đánh giá cao bất kỳ sự giúp đỡ và lời khuyên! Tôi hoàn toàn bế tắc với điều này.
Cảm ơn :)

LƯU Ý: Tôi vừa nhận thấy rằng previous_posts_link()nó hoạt động chính xác trên tất cả các trang, nhưng no idea whytrong trường hợp này, tại sao next_posts_linkkhông hoạt động: S

Đây là mã:

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$post_per_page = intval(get_query_var('posts_per_page'));
$offset = ($paged - 1)*$post_per_page;

$sql = "
SELECT SQL_CALC_FOUND_ROWS  wp_posts.*, wp_postmeta.* 
FROM wp_posts 
INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id)
INNER JOIN wp_postmeta AS mt1 ON (wp_posts.ID = mt1.post_id) 
WHERE 1=1  
    AND wp_posts.post_type = 'movie' 
    AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') 
    AND ((wp_postmeta.meta_key = '_expiry_date' AND CAST(wp_postmeta.meta_value AS DATE) >= '".$current_date."') 
        OR (mt1.meta_key = '_expiry_date' AND CAST(mt1.meta_value AS CHAR) = ''))
GROUP BY wp_posts.ID 
ORDER BY wp_posts.post_date DESC
LIMIT ".$offset.", ".$post_per_page;

$movies_all_current = $wpdb->get_results( $sql, OBJECT);

if($movies_all_current) {
global $post;

//loop
foreach( $movies_all_current as $key=>$post ) {
    setup_postdata($post);
    //display each post
    //...
} //end foreach ?>

    //navigation
<div class="navigation">
    <div class="previous panel"><?php previous_posts_link('&laquo; newer') ?></div>
    <div class="next panel"><?php next_posts_link('older &raquo;') ?></div>
</div>
}

Câu trả lời:


16

Ok, tôi đã đến đó vào cuối. Tôi không thể sử dụng WP_Querylớp vì tôi thực sự cần phải có SQL khá lớn và phức tạp của riêng mình. Đây là những gì tôi đã có:

Trong functions.phptôi có SQL và logic tùy chỉnh của tôi để đếm các giá trị cần thiết cho logic phân trang WP:

function vacancies_current( ){
    global $wpdb, $paged, $max_num_pages, $current_date;

    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    $post_per_page = intval(get_query_var('posts_per_page'));
    $offset = ($paged - 1)*$post_per_page;

    /* Custom sql here. I left out the important bits and deleted the body 
     as it will be specific when you have your own. */
    $sql = "
        SELECT SQL_CALC_FOUND_ROWS  {$wpdb->posts}.*
        FROM {$wpdb->posts}
        ....
        GROUP BY {$wpdb->posts}.ID 
        ORDER BY {$wpdb->posts}.post_date DESC
        LIMIT ".$offset.", ".$post_per_page."; ";   

    $sql_result = $wpdb->get_results( $sql, OBJECT);

    /* Determine the total of results found to calculate the max_num_pages
     for next_posts_link navigation */
    $sql_posts_total = $wpdb->get_var( "SELECT FOUND_ROWS();" );
    $max_num_pages = ceil($sql_posts_total / $post_per_page);

    return $sql_result;
}

Sau đó, trong tệp mẫu của tôi, tôi có:

<?php 
    $vacancies_current = vacancies_current();
    /*followed by a standart loop to display your results */ 
 ?>
<div class="navigation">
    <div class="previous panel"><?php previous_posts_link('&laquo; previous vacancies',$max_num_pages) ?></div>
    <div class="next panel"><?php next_posts_link('more vacancies &raquo;',$max_num_pages) ?></div>
</div>

Bí quyết là trong việc cung cấp previous_posts_link()next_posts_linkcác $max_num_pagesgiá trị và rõ ràng trong việc tính toán một cách chính xác.

Điều này hoạt động rất tốt. Hy vọng nó sẽ giúp được ai đó :)

Dasha


+1 công việc tốt đẹp. Tôi đã xem qua điều này (và mượn rất nhiều, cảm ơn) trong khi nghiên cứu câu trả lời của tôi cho stackoverflow.com/questions/16057059/ . Tôi đã tự hỏi nếu bạn biết một cách để sử dụng một câu lệnh SQL tùy chỉnh như thế này, nhưng trong một hành động pre_get_posts () theo codex.wordpress.org/, thì sao? Tôi thấy giải pháp này dễ bị ảnh hưởng bởi 404 về vấn đề trang cuối cùng, theo wordpress.org/support/topic/ mẹo . Làm thế nào bạn vượt qua điều này?
Sepster

1

Hãy xem Truy vấn tùy chỉnh - cho phép bạn sửa đổi cuộc gọi wp_query theo nhiều cách thú vị và hữu ích, và đẩy kết quả trở lại vào đối tượng truy vấn toàn cầu của bạn.


1

Mở rộng câu trả lời của Anu. Thay vì dựa vào truy vấn sql tùy chỉnh của bạn, bạn có thể sử dụng lớp WP_Query và để WordPress xử lý tất cả các nâng SQL nặng. Điều này chắc chắn sẽ giải quyết vấn đề điều hướng của bạn.

Ví dụ truy vấn cho loại bài đăng phim trong _Exiry_date meta_key của bạn:

$today = getdate();
$args = array(
    'post_type' => 'movie',
    'meta_query' => array(
            'meta_key' => '_expiry_date',
            'meta_value' => $today,
            'meta_compare' => '< '
                    ),
    'posts_per_page' => -1,
     'order'    => 'DESC'
    );

    $movie_query = new WP_Query( $args );

    while ( $movie_query->have_posts() ) : $movie_query->the_post(); 
    // Do stuff
   endwhile; ?>

 <div class="navigation">
<div class="previous panel"><?php previous_posts_link('&laquo; newer') ?></div>
<div class="next panel"><?php next_posts_link('older &raquo;') ?></div>
</div>

cảm ơn bạn đã trả lời, tuy nhiên, tôi không thể dựa vào WP_Querylớp vì tôi cần xây dựng SQL tùy chỉnh của riêng mình. Tôi đã đến đó vào cuối, xem câu trả lời của tôi nếu quan tâm :)
dashaluna

-2
<?php

global $wpdb, $paged;
query_posts($query_string . '&posts_per_page=9');
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$author = isset($_GET['author_name']) ? get_userdatabylogin($author_name) : get_userdata(intval($author));

query_posts($query_string . '&posts_per_page=9');

$args = array(
'post_type' => 'post',
'meta_query' => array(
        'meta_key' => 'autor',
    'post_status' => 'publish',
        'meta_value' => $author->id,
            ),
'paged' => $paged,
'posts_per_page' => 9,
'order'    => 'DESC'
);

$postsQuery = new WP_Query( $args );

?> 

Bản mẫu:

<h1lánky od <?php echo $author->display_name; ?></h1>
        <ul class="thumbnails">

            <?php while ( $postsQuery->have_posts() ) : $postsQuery->the_post();  ?>
                <li class="span3">
                <div class="thumbnail">
                    <a href="<?php the_permalink(); ?>">
                    <?php the_post_thumbnail(array(260, 259)); ?>
                    </a>
                    <?php
                    $class = '';
                    if (in_category('fashion')) {
                    $class = "link-fashion";
                    } else if (in_category('beauty')) {
                    $class = "link-beauty";
                    } else if (in_category('gourmet')) {
                    $class = "link-gourmet";
                    } else if (in_category('lifestyle')) {
                    $class = "link-lifestyle";
                    } else if (in_category('about-us')) {
                    $class = "link-about";
                    }
                    ?>
                    <a href="<?php the_permalink(); ?>">
                    <h2 class="<?=  $class ?>">
                        <span></span>
                        <?php
                        // short_title('...', 25); 
                        echo get_the_title();
                        ?>
                    </h2>
                    </a>
                    <?php the_excerpt(); ?>
                    <hr>
                </div>
                </li>
            <?php endwhile; ?>

        </ul>
        <?php wp_pagenavi(); ?>

2
Vui lòng thêm một lời giải thích cho mã của bạn, đồng thời, tại sao bạn lại chạy hai truy vấn, một với query_postsvà một vớiWP_Query
Pieter Goosen
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.