Phân trang bằng Ajax sử dụng paginate_links trong WordPress

Update lần cuối 24/11/2017 by Mr Toản trong WordPress vào 31/05/2017 có

Trong bài này tất cả chúng ta sẽ phân trang bằng Ajax sử dụng paginate_links – là 1 hàm có sẵn trong WordPress. Việc sử dụng hàm paginate_links có sẵn thì tất cả chúng ta không cần lo ngại về phân trang khi viết query bài viết nữa rồi.

Vấn đề & cách khắc phục

  • Vì sao cần phân trang bằng Ajax nhỉ?
  • Hàm paginate_links có độc đáo gì khi sử dụng với Ajax?

Tất cả chúng ta có 1 trang chủ gồm nhất nhiều bài viết (Slider, giới thiệu, partners, testimonial, tin tức …) nhưng mục tin tức lại nằm ở cuối cùng của trang chủ. Trong lúc này lại có phân trang. Vậy lúc này chẳng lẽ mỗi lần kích phân trang lại load lại trang & nhảy lên trước tiên ah? => Sử dụng Ajax tại mục tin tức.

Chẳng hạn khác như trên trang chủ gồm nhiều mục tin tức & mỗi mục tin tức lại có phân trang => trong trường hợp này cần sử dụng Ajax

Mặc định backlinks phân trang của hàm paginate_links sẽ có dạng: link_page_hiện_tại/page/2 nhưng khi load bằng Ajax backlinks phân trang sẽ có dạng /wp-admin/admin-ajax.php/?paged=2 . Backlink này là sai … Tất cả chúng ta chỉ cần để base dạng như sau là được.

'base' => trailingslashit( home_url() ) . "{$wp_rewrite->pagination_base}/%#%/",

Chẳng hạn thực tiễn về phân trang bằng Ajax sử dụng paginate_links

Hình ảnh cho chẳng hạn sau khoảng thời gian giải quyết. Dùng thử trực tiếp tại đây

Đầu tiên là đoạn php Query để lấy 4 tin tức tiên tiến nhất kèm theo phân trang. Đoạn code này để vào chỗ cần hiển thị trên trang chủ.

<?php
$news = new WP_Query(array(
    'post_type'         =>  'bài viết',
    'posts_per_page'    =>  4
));
if($news->have_posts()):
    $max_post_count = $news->post_count;
    ?>
    <div class="home_tintuc">
    <div class="container">
        <div class="home_news_main">
            <div class="home_news_wrap">
                <?php $stt = 1; while ($news->have_posts()):$news->the_post();?>
            <?php if($stt == 1):?><div class="home_news_col1"><?php endif;?>
                    <?php if($stt == 2):?><div class="home_news_col2"><?php endif;?>
                        <?php
                        $thumb = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'thumbnail' );
                        $urlThumb = $thumb['0'];
                        ?>
                        <div class="tintuc_box <?php if(has_post_thumbnail()):?>has_post_thumbnail<?php endif;?>">
                            <?php if(has_post_thumbnail()):?>
                                <div class="tintuc_box_thumb"><α href="<?php the_permalink();?>" title="<?php the_title()?>" style="background: url(<?php echo $urlThumb;?>) no-repeat center center"><?php the_post_thumbnail('thumbnail');?></avàgt;</divvàgt;
                            <?php endif;?>
                            <div class="tintuc_box_infor">
                                <h3vàgt;<α href="<?php the_permalink();?>" title="<?php the_title()?>"><?php the_title();?></avàgt;</h3vàgt;
                                <div class="news_infor_cat"><?php the_category(', ');?></divvàgt;
                                <div class="news_date"><?php echo get_the_date();?></divvàgt;
                                <div class="news_excerpt"><?php the_excerpt();?></divvàgt;
                                <α href="<?php echo get_the_permalink();?>" title="<?php the_title();?>" rel="nofollow" class="news_readmore"><?php _e('Tham khảo thêm >>','devvn')?></avàgt;
                            </divvàgt;
                        </divvàgt;
                        <?php if($stt == 1 || $stt == $max_post_count):?></divvàgt;<?php endif;?>
                    <?php $stt++; endwhile;?>
                </divvàgt;
                <?php devvn_corenavi_ajax($news);?>
            </divvàgt;
        </divvàgt;
    </divvàgt;
<?php endif; wp_reset_query();//End news?>

Còn đây là hàm phân trang. Sử dụng paginate_links – hàm mặc định của WordPress. Sao chép đoạn code sau vào file functions.php của theme đang sử dụng

function devvn_corenavi_ajax($custom_query = null, $paged = 1) {
    global $wp_query, $wp_rewrite;
    if($custom_query) $main_query = $custom_query;
    else $main_query = $wp_query;
    $big = 999999999;
    $total = isset($main_query->max_num_pages)?$main_query->max_num_pages:'';
    if($total > 1) echo '<div class="paginate_links">';
    echo paginate_links( array(
        'base'        => trailingslashit( home_url() ) . "{$wp_rewrite->pagination_base}/%#%/",
        'format'   => '?paged=%#%',
        'current'  => max( 1, $paged ),
        'total'    => $total,
        'mid_size' => '5',
        'prev_text'    => __('<<','devvn'),
        'next_text'    => __('>>','devvn'),
    ) );
    if($total > 1) echo '</divvàgt;';
}

Kế tiếp là hàm giải quyết Ajax thông qua admin-ajax.php. Sao chép đoạn code sau vào file functions.php của theme đang sử dụng (Để ngay sau đoạn code phân trang phía trên). Trong đoạn php này có hàm test nonce. nếu bạn không cần validate nonce (liên quan tới bảo mật) thì bỏ nó đi cũng được (từ dòng 5 – 7)

//Ajax load bài viết
add_action( 'wp_ajax_ajax_load_post', 'ajax_load_post_func' );
add_action( 'wp_ajax_nopriv_ajax_load_post', 'ajax_load_post_func' );
function ajax_load_post_func() {
    if ( !wp_verify_nonce( $_REQUEST['nonce'], "ajax_load_post_nonce")) {
        wp_send_json_error('None?');
    }
    $paged = isset($_POST['ajax_paged'])?intval($_POST['ajax_paged']):'';
    if($paged <= 0 || !$paged || !is_numeric($paged)) wp_send_json_error('Paged?');
    $news = new WP_Query(array(
        'post_type'         =>  'bài viết',
        'posts_per_page'    =>  4,
        'paged'             =>  $paged
    ));
    if($news->have_posts()):
        ob_start();
        $max_post_count = $news->post_count;
        ?>
        <div class="home_news_wrap">
        <?php $stt = 1; while ($news->have_posts()):$news->the_post();?>
        <?php if($stt == 1):?><div class="home_news_col1"><?php endif;?>
        <?php if($stt == 2):?><div class="home_news_col2"><?php endif;?>
        <?php
        $thumb = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'thumbnail' );
        $urlThumb = $thumb['0'];
        ?>
        <div class="tintuc_box <?php if(has_post_thumbnail()):?>has_post_thumbnail<?php endif;?>">
            <?php if(has_post_thumbnail()):?>
                <div class="tintuc_box_thumb"><α href="<?php the_permalink();?>" title="<?php the_title()?>" style="background: url(<?php echo $urlThumb;?>) no-repeat center center"><?php the_post_thumbnail('thumbnail');?></avàgt;</divvàgt;
            <?php endif;?>
            <div class="tintuc_box_infor">
                <h3vàgt;<α href="<?php the_permalink();?>" title="<?php the_title()?>"><?php the_title();?></avàgt;</h3vàgt;
                <div class="news_infor_cat"><?php the_category(', ');?></divvàgt;
                <div class="news_date"><?php echo get_the_date();?></divvàgt;
                <div class="news_excerpt"><?php the_excerpt();?></divvàgt;
                <α href="<?php echo get_the_permalink();?>" title="<?php the_title();?>" rel="nofollow" class="news_readmore"><?php _e('Tham khảo thêm >>','devvn')?></avàgt;
            </divvàgt;
        </divvàgt;
        <?php if($stt == 1 || $stt == $max_post_count):?></divvàgt;<?php endif;?>
        <?php $stt++; endwhile; wp_reset_query();?>
        </divvàgt;
        <?php devvn_corenavi_ajax($news,$paged);?>
        <?php $content = ob_get_clean();?>
    <?php else:?>
        <?php wp_send_json_error('No bài viết?');?>
    <?php endif; //End news
    wp_send_json_success($content);
    die();
}

Kế tiếp là đoạn script để thực hiện việc load ajax. Hãy tạo 1 file ajax-loadpost.js với bài viết bên dưới & để trong folder js của theme. Trong đoạn script dưới đây có thông số kỹ thuậtdevvn_array.load_post_nonce bạn có thể xóa  còn nếu như không dùng tới nonce  (dòng 16)

(function($) {
    $(document).ready(function() {
        $(".home_news_main").on('click','.paginate_links α',function(e){
            e.preventDefault();
            var hrefThis = $(this).attr('href');
            var paged = hrefThis.match(//{d}+//)[0];
            paged = paged.match(/{d}+/)[0];
            if(!paged) paged = 1;
            $.ajax({
                type : "post",
                dataType : "json",
                url : devvn_array.admin_ajax,
                data : {
                    action: "ajax_load_post", 
                    ajax_paged : paged, 
                    nonce: devvn_array.load_post_nonce
                },
                context: this,
                beforeSend: function(){
                    $('.home_news_main').addClass('active');
                },
                success: function(response) {

                    if(response.success) {
                        $(response.data).addClass('holder');
                        $(".home_news_main").empty();
                        $(".home_news_main").append($(response.data));
                    }
                    $('.home_news_main').removeClass('active');
                }
            });
        });
    });
})(jQuery);

Kế tiếp là đoạn code php sử dụng wp_enqueue_script để theme file ajax-loadpost.js bên trên vào theme. Tham khảo thêm cách thêm script vào theme WordPress 1 cách chuẩn nhất.

Xem Thêm  Công cụ trực tuyến miễn phí - góc tròn của hình ảnh

Hãy sao chép đoạn code sau vào file functions.php của theme đang sử dụng

add_action( 'wp_enqueue_scripts', 'devvn_enqueue_UseAjaxInWp' );
function devvn_enqueue_UseAjaxInWp(){
    wp_enqueue_script( 'devvn-ajaxload', esc_url( trailingslashit( get_template_directory_uri() ) . 'js/ajax-loadpost.js' ), array( 'jquery' ), '1.0', true );
    $php_array = array(
        'admin_ajax'      => admin_url( 'admin-ajax.php'),
        'load_post_nonce'   =>  wp_create_nonce('ajax_load_post_nonce'),
    );
    wp_localize_script( 'devvn-ajaxload', 'devvn_array', $php_array );
}

Cuối cùng là đoạn style chăm sóc sắc đẹp cho đoạn code trên ?

.home_news_main {
    position: relative;
}
.home_news_main:before {
    display: inline-block;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
    -webkit-transform: translate(-50%,-50%);
    font-size: 2em;
    visibility: hidden;
    opacity: 0;
    width: 64px;
    height: 64px;
    background: url(../images/Preloader_2.gif) no-repeat center;
    z-index: 2;
    content: '';
}
.home_news_main.active:before, .home_news_main.active:after {
    opacity: 1;
    visibility: visible;
}
.home_news_wrap {
    margin: 10px 0;
}
.home_news_col1 {
    width: 63.55%;
    float: left;
}
.tintuc_box {
    overflow: hidden;
    margin: 0 0 10px;
}
.home_news_col1 .tintuc_box {
    box-shadow: 0 1px 6px 0px rgba(0,0,0,0.3);
}
.tintuc_box_thumb {
    width: 127px;
    float: left;
}
.home_news_col1 .tintuc_box_thumb {
    width: 60%;
}
.tintuc_box_thumb α {
    display: block;
    height: 0;
    padding-top: 100%;
    width: 100%;
    background-size: cover !important;
    -moz-background-size: cover !important;
    -webkit-background-size: cover !important;
}
.tintuc_box_thumb img {
    opacity: 0;
    visibility: hidden;
    display: inline-block;
    opacity: 0;
    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
    filter: alpha(opacity=100);
    -moz-opacity: 0;
    -khtml-opacity: 0;
    position: absolute;
    top: 0;
    left: 0;
}
.tintuc_box_infor {
    padding: 0 0 0 20px;
    color: #6d6e71;
}
.has_post_thumbnail .tintuc_box_infor {
    margin-left: 127px;
}
.home_news_col1 .tintuc_box_infor {
    padding: 20px;
}
.home_news_wrap:after, .tintuc_box:after {
    content: "";
    clear: both;
    display: table;
}
.tintuc_box_infor h3 {
    max-height: 39px;
    overflow: hidden;
}
.home_news_col1 .tintuc_box_infor h3 {
    margin: 0 0 5px;
}
.tintuc_box_infor h3 α {
    font-size: 16px;
    color: #6d6e71;
    line-height: 20px;
    display: block;
}
.home_news_col1 .news_infor_cat {
    margin: 0 0 5px;
}
.news_infor_cat:before {
    content: ">>";
    margin: 0 2px 0 0;
}
.news_infor_cat α {
    font-size: 12px;
    display: inline-block;
    color: #6d6e71;
}
.news_date {
    font-size: 12px;
    margin: 5px 0;
    display: block;
}
.news_date:before {
    content: "f073";
    display: inline-block;
    font: normal normal normal 12px/1 FontAwesome;
    font-size: inherit;
    text-rendering: tự động;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    display: inline-block;
    margin: 0 5px 0 0;
    color: #f48120;
    font-size: 12px;
    position: relative;
}
.news_excerpt {
    margin: 0;
    max-height: 45px;
    overflow: hidden;
    text-align: justify;
}
.home_news_col1 .news_excerpt {
    margin: 0 0 30px;
    max-height: 211px;
    text-align: justify;
}
.tintuc_box_infor .news_readmore {
    color: #f48120;
    font-size: 16px;
    font-weight: 700;
}
.home_news_col2 {
    width: 33.18%;
    float: right;
}

/*Css phân trang*/
.paginate_links {
    text-align: left;
    color: #FF9B00;
}
.paginate_links .page-numbers {
    padding: 4px 10px;
    margin: 0 2px 5px 0;
    text-align: center;
    background: #e1e1e1;
    color: #6d6e71;
    text-decoration: none;
    display: inline-block;
}
.paginate_links .current, .paginate_links .page-numbers:hover {
    background: #f48120;
    color: #fff;
}

Trong tiến trình làm có bất kỳ khúc mắc gì hãy phản hồi bên dưới nội dung. Mình sẽ phấn đấu lời giải ?

Xem Thêm  Ràng buộc Drop SQL - làm thế nào để loại bỏ ràng buộc trong máy chủ sql

Tải bộ code trên tại đây

 

4.9/5 – (12 votes)

Nội dung có lợi cho bạn? Hãy chia sẻ ngay:

Viết một bình luận