我們曾經(jīng)講了如何制作短碼(查看),今天我們就通過短碼實(shí)現(xiàn)一個帶有無刷新動態(tài)分類篩選以及分頁的文章列表。
該文章列表帶有單選篩選功能,篩選條件可以是分類、標(biāo)簽或者其他自定義分類,采用ajax技術(shù),文章列表可以通過數(shù)字分頁。演示效果,猛戳這里>>> 該演示效果沒有特定CSS修飾,需自行添加
1.編寫短碼函數(shù)
function jsonvue_filter_posts_sc($atts) {
$a = shortcode_atts( array(
'tax' => 'category', //可以改為post_tag
'terms' => false, //排除某個分類
'active' => false, //設(shè)定默認(rèn)加載哪個分類
'per_page' => 12 //設(shè)定每頁文章數(shù)量
), $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;
}
注冊該短碼:
add_shortcode( 'jsonvue_posts', 'jsonvue_ajax_posts_sc');
2.其他函數(shù)
第一步的短碼函數(shù)并沒有帶有具體的處理邏輯,比如:發(fā)送ajax請求,php處理請求,分頁數(shù)據(jù)等功能,那么現(xiàn)在我們就開始構(gòu)建這些函數(shù)。
首先是 發(fā)送ajax請求的JS代碼,這個是通過jquery實(shí)現(xiàn)。
$('#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獲取數(shù)據(jù)的JS代碼
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函數(shù)處理ajax請求
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');
分頁函數(shù):
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;
}
最后,將上述代碼整合,并加載進(jìn)wordpress :
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' )//調(diào)用wordpress自帶ajax處理程序
));
}
add_action('wp_enqueue_scripts', 'assets', 100);
注意:上述代碼除了js文件,都要放在主題文件夾下function.php文件里面,默認(rèn)短碼調(diào)用方式:
[jsonvue_posts]
可配置屬性有:
‘tax’ => ‘post_tag’, // 分類方式 category 或者post_tag
‘terms’ => false, // 自定義分類比如排除某個分類
‘active’ => false, //默認(rèn)加載分類默認(rèn)加載全部分類
‘per_page’ => 12 // 每頁顯示文章數(shù),
另外,該代碼運(yùn)行需要PHP5.4或者以上環(huán)境。
源碼下載:code






…