我们曾经讲了如何制作短码(查看),今天我们就通过短码实现一个带有无刷新动态分类筛选以及分页的文章列表。
该文章列表带有单选筛选功能,筛选条件可以是分类、标签或者其他自定义分类,采用ajax技术,文章列表可以通过数字分页。演示效果,猛戳这里>>> 该演示效果没有特定CSS修饰,需自行添加
1.编写短码函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
function jsonvue_filter_posts_sc($atts) { $a = shortcode_atts( array( 'tax' => 'category', //可以改为post_tag 'terms' => false, //排除某个分类 'active' => false, //设定默认加载哪个分类 'per_page' => 12 //设定每页文章数量 ), $atts ); $result = NULL; $terms = get_terms($a['tax']); //排除某个分类就用下面一句,在短码添加terms='分类id'就可以排除 //$terms = get_terms($a['tax'],array('exclude' =>$a['terms'])); if (count($terms)) : ob_start(); ?> <div id="container-async" data-paged="<?php echo $a['per_page']; ?>" class="sc-ajax-filter"> <ul class="nav-filter"> <li> <a href="#" data-filter="post_tag" data-term="all-terms" data-page="1"> 所有 </a> </li> <?php foreach ($terms as $term) : ?> <li<?php if ($term->term_id == $a['active']) :?> class="active"<?php endif; ?>> <a href="<?php echo get_term_link( $term, $term->taxonomy ); ?>" data-filter="<?php echo $term->taxonomy; ?>" data-term="<?php echo $term->slug; ?>" data-page="1"> <?php echo $term->name; ?> </a> </li> <?php endforeach; ?> </ul> <div class="status"></div> <div class="content"></div> </div> <?php $result = ob_get_clean(); endif; return $result; } |
注册该短码:
1 |
add_shortcode( 'jsonvue_posts', 'jsonvue_ajax_posts_sc'); |
2.其他函数
第一步的短码函数并没有带有具体的处理逻辑,比如:发送ajax请求,php处理请求,分页数据等功能,那么现在我们就开始构建这些函数。
首先是 发送ajax请求的JS代码,这个是通过jquery实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
$('#container-async').on('click', 'a[data-filter], .pagination a', function(event) { if(event.preventDefault) { event.preventDefault(); } $this = $(this); if ($this.data('filter')) { $this.closest('ul').find('.active').removeClass('active'); $this.parent('li').addClass('active'); $page = $this.data('page'); } else { $page = parseInt($this.attr('href').replace(/\D/g,'')); $this = $('.nav-filter .active a'); } $params = { 'page' : $page, 'tax' : $this.data('filter'), 'term' : $this.data('term'), 'qty' : $this.closest('#container-async').data('paged'), }; get_posts($params); }); $('a[data-term="all-terms"]').trigger('click'); |
Ajax请求后台php获取数据的JS代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
function get_posts($params) { $container = $('#container-async'); $content = $container.find('.content'); $status = $container.find('.status'); $status.text('正在加载 ...'); $.ajax({ url: jsonvue.ajax_url, data: { action: 'do_filter_posts', nonce: jsonvue.nonce, params: $params }, type: 'post', dataType: 'json', success: function(data, textStatus, XMLHttpRequest) { if (data.status === 200) { $content.html(data.content); } else if (data.status === 201) { $content.html(data.message); } else { $status.html(data.message); } }, error: function(MLHttpRequest, textStatus, errorThrown) { $status.html(textStatus); /*console.log(MLHttpRequest); console.log(textStatus); console.log(errorThrown);*/ }, complete: function(data, textStatus) { msg = textStatus; if (textStatus === 'success') { msg = data.responseJSON.found; } $status.text('已显示: ' + msg+'篇文章'); /*console.log(data); console.log(textStatus);*/ } }); } |
php函数处理ajax请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
function jsonvue_filter_posts() { if( !isset( $_POST['nonce'] ) || !wp_verify_nonce( $_POST['nonce'], 'jsonvue' ) ) die('Permission denied'); $response = [ 'status' => 500, 'message' => '貌似有错误,请稍后再试 ...', 'content' => false, 'found' => 0 ]; $tax = sanitize_text_field($_POST['params']['tax']); $term = sanitize_text_field($_POST['params']['term']); $page = intval($_POST['params']['page']); $qty = intval($_POST['params']['qty']); if (!term_exists( $term, $tax) && $term != 'all-terms') : $response = [ 'status' => 501, 'message' => '没找到分类', 'content' => 0 ]; die(json_encode($response)); endif; if ($term == 'all-terms') : $tax_qry[] = [ 'taxonomy' => $tax, 'field' => 'slug', 'terms' => $term, 'operator' => 'NOT IN' ]; else : $tax_qry[] = [ 'taxonomy' => $tax, 'field' => 'slug', 'terms' => $term, ]; endif; $args = [ 'paged' => $page, 'post_type' => 'post', 'post_status' => 'publish', 'posts_per_page' => $qty, 'tax_query' => $tax_qry ]; $qry = new WP_Query($args); ob_start(); if ($qry->have_posts()) : while ($qry->have_posts()) : $qry->the_post(); ?> <article class="loop-item"> <header> <h2 class="entry-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2> </header> <div class="entry-summary"> <?php the_excerpt(); ?> </div> </article> <?php endwhile; jsonvue_ajax_pager($qry,$page); $response = [ 'status'=> 200, 'found' => $qry->found_posts ]; else : $response = [ 'status' => 201, 'message' => '没有文章' ]; endif; $response['content'] = ob_get_clean(); die(json_encode($response)); } add_action('wp_ajax_do_filter_posts', 'jsonvue_filter_posts'); add_action('wp_ajax_nopriv_do_filter_posts', 'jsonvue_filter_posts'); |
分页函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
function jsonvue_ajax_pager( $query = null, $paged = 1 ) { if (!$query) return; $paginate = paginate_links([ 'base' => '%_%', 'type' => 'array', 'total' => $query->max_num_pages, 'format' => '#page=%#%', 'current' => max( 1, $paged ), 'prev_text' => 'Prev', 'next_text' => 'Next' ]); if ($query->max_num_pages > 1) : ?> <ul class="pagination"> <?php foreach ( $paginate as $page ) :?> <li><?php echo $page; ?></li> <?php endforeach; ?> </ul> <?php endif; } |
最后,将上述代码整合,并加载进wordpress :
1 2 3 4 5 6 7 8 9 10 |
function assets() { wp_enqueue_script( 'bootcdn', 'http://cdn.bootcss.com/jquery/2.2.3/jquery.min.js">' ); wp_enqueue_script('jsonvue/js', get_template_directory_uri().'/js/custom.js'); //php想向js传递变量 wp_localize_script( 'jsonvue/js', 'jsonvue', array( 'nonce' => wp_create_nonce( 'jsonvue' ),//ajax请求安全处理 'ajax_url' => admin_url( 'admin-ajax.php' )//调用wordpress自带ajax处理程序 )); } add_action('wp_enqueue_scripts', 'assets', 100 |
注意:上述代码除了js文件,都要放在主题文件夹下function.php文件里面,默认短码调用方式:
[jsonvue_posts]
可配置属性有:
‘tax’ => ‘post_tag’, // 分类方式 category 或者post_tag
‘terms’ => false, // 自定义分类比如排除某个分类
‘active’ => false, //默认加载分类默认加载全部分类
‘per_page’ => 12 // 每页显示文章数,