Tự code chức năng đếm lượt xem và top bài xem nhiều [NEW]

Trong thời gian vừa qua có nhiều bạn thắc mắc về thêm chức năng tự đếm lượt xem bài đăngnhư xem một lần, lượt xem sẽ tăng một giá trị và kết hợp với chức năng đếm lượt xem đó để tạo thành một tính năng tiện ích con Hiển thị các bài đăng được xem nhiều nhất. Vấn đề mà mình hay gặp ở đây là nhiều người tìm plugin nhưng không có đủ các chức năng cần thiết, plugin có đủ tính năng nhưng hoạt động không tốt, không như ý muốn.

Thì trong bài này mình sẽ hướng dẫn các bạn tự viết một plugin có chức năng đếm lượt xem cho bài viết hay bất cứ thứ gì và còn hướng dẫn bạn cách viết code để tạo widget hiển thị bài viết bao nhiêu tuần, tháng hay bao nhiêu ngày tùy thích.

Tổng quan về kỹ thuật

Trong hướng dẫn này, chúng ta sẽ làm việc với hai tính năng khá quan trọng và thú vị trong WordPress: Custom Post Field để tạo khóa (meta key) chứa dữ liệu xem (meta data) cho mỗi bài đăng và tính năng tạo widget để widget hiển thị danh sách các bài viết theo thứ tự từ được xem nhiều nhất đến thấp nhất, với hình thu nhỏ và lượt xem nếu bạn thích.

Lý do ở đây chúng ta nên sử dụng Custom Post Field cho chức năng đếm lượt xem là vì số lượt xem chúng ta có thể hiểu đó là dữ liệu bổ sung của mỗi bài đăng, trong WordPress đã có Custom Post. Field có nhiệm vụ cho phép chúng ta tạo các khóa tùy ý và mỗi khóa sẽ có giá trị riêng. Sau đó, sử dụng Trường bài đăng tùy chỉnh để tạo khóa riêng tư nhằm xác định và sử dụng giá trị của nó vì số lượt xem có ý nghĩa nhất và rút ngắn thời gian triển khai vì chỉ mất một vài dòng mã. .

Còn với tính năng tạo widget hiển thị danh sách các bài viết được xem nhiều nhất, chắc chắn chúng ta sẽ sử dụng Query & Loop để liệt kê các bài viết được xem nhiều nhất. Nhưng làm thế nào để có được những bài báo được xem nhiều nhất, và làm thế nào để có được dữ liệu đó trong một khoảng thời gian nhất định (7 ngày chẳng hạn)? May mắn thay, WordPress cho phép chúng ta truy vấn và lấy dữ liệu dựa trên khóa meta (khóa của Trường bài đăng tùy chỉnh) và chúng ta có thể sắp xếp lại kiểu dữ liệu này theo thứ tự giá trị giảm dần, vì vậy chúng ta sẽ có một danh sách các bài viết được xem nhiều nhất.

Hướng dẫn chi tiết

1. Thiết lập plugin

Bước này quá dễ, chúng ta sẽ tạo một thư mục có tên là topview trong thư mục / wp-content / plugins để chứa plugin và trong thư mục này sẽ có 2 tệp tên là plugins.php styles.css như hình bên dưới.

Tự code chức năng đếm lượt xem và top bài xem nhiều [NEW]

Và trong tệp plugins.php Chúng tôi có một vài đoạn thông tin cho plugin như sau:


<?php
/*
Plugin Name: PostView
Plugin Author: ThachPham
Description: Plugin đếm lượt xem bài viết và hiển thị top bài xem nhiều
Version: 1.0
Author URI: https://thachpham.com
*/

Sau đó, chúng tôi sẽ viết mã bên dưới. Bây giờ chúng ta hãy tạm thời nhập Plugin -> Plugin đã cài đặt và bật nó lên.

2. Viết mã để đếm lượt xem

Mã đếm lượt xem ở đây khá ngắn vì nó là một tính năng đơn giản chỉ có các dòng sau:


function postview_set($postID) {
$count_key = ‘postview_number’;
$count = get_post_meta($postID, $count_key, true);
if($count==”){
$count = 0;
delete_post_meta($postID, $count_key);
add_post_meta($postID, $count_key, ‘0’);
}else{
$count++;
update_post_meta($postID, $count_key, $count);
}
}

Trong đoạn mã này, chúng ta sẽ tạo một hàm có tên là postview_set() với ý nghĩa cụ thể của:

  • Số dòng 02 – 03: Đặt biến của riêng bạn để kiểm tra dữ liệu trong khóa meta, $count_key nghĩa là, đặt tên metakey được lưu trữ trong bảng wp_postmeta. Lưu ý rằng sau này nếu bạn đổi tên khóa này, tất cả các giá trị sẽ được đặt lại.
  • Số dòng 04 – 08: Kiểm tra khóa meta postview_number có dữ liệu, nếu dữ liệu của nó trống, nó sẽ tiến hành tạo meta key mới cho nó với tên postview_number ở trên. Đồng thời đặt biến $count về giá trị là 0.
  • Số dòng 08 – 11: Nếu khóa meta postview_number đã có dữ liệu (phủ định của không có dữ liệu có nghĩa là đã có dữ liệu) thì biến $count sẽ được tăng thêm một giá trị.

Vậy hàm này sẽ thực thi như thế nào? Để chức năng này hoạt động, bạn phải nhập mã sau vào tệp single.php trong chủ đề đang được sử dụng, và phải được chèn vào vòng lặp (trong trong khi):


<?php postview_set(get_the_ID()); ?>

chức năng topview-setview

Tức là mỗi khi khách truy cập vào website thì chức năng này sẽ được lặp lại một lần nữa và cập nhật vào cơ sở dữ liệu, cứ như vậy, cứ như vậy sau mỗi lần truy cập, đó là lý do tại sao nếu website của bạn đông người truy cập. truy cập, tính năng này có thể chiếm nhiều tài nguyên vì phải chỉnh sửa dữ liệu liên tục.

3. Viết mã để hiển thị các chế độ xem

Đoạn code trên chúng ta chỉ viết code cập nhật lượt xem chứ không hiển thị, nếu bạn cần hiển thị lượt xem trên trang nội dung bài viết thì hãy thêm đoạn mã sau vào file. plugins.php


function postview_get($postID){
$count_key = ‘postview_number’;
$count = get_post_meta($postID, $count_key, true);
if($count==”){
delete_post_meta($postID, $count_key);
add_post_meta($postID, $count_key, ‘0’);
return "0 lượt xem";
}
return $count.’ lượt xem’;
}

Đồng thời chèn đoạn này bên dưới để tránh trường hợp một lượt truy cập có tới 2 lượt xem:

remove_action( ‘wp_head’, ‘adjacent_posts_rel_link_wp_head’, 10, 0);

Mã này tương tự như mã đếm lượt xem, điểm khác biệt duy nhất là nó trả về một biến phụ $count ra để hiển thị giá trị của khóa meta postview_number, tức là các khung nhìn. Sau đó, bạn chèn phần sau vào tệp single.php ở vị trí hiển thị khung nhìn, tất nhiên, phải được đặt trong cặp while:

<?php echo postview_get(get_the_ID()); ?>

chức năng topview-getview

Tất nhiên bạn có thể chèn ở bất kỳ vị trí nào nếu thích trong cặp while vì mỗi chủ đề có cấu trúc khác nhau và ý tưởng của mọi người cũng khác nhau nên mình không thể chỉ ra vị trí cụ thể để chèn. Nhưng đẹp nhất là chèn bên cạnh đoạn mã hiển thị bình luận, thể loại, tên tác giả. Nếu bạn thấy tệp single.php của mình có đoạn get_template_part('content',....) sau đó chỉ cần tìm tệp content.php và content-xxx.php trong chủ đề và sau đó chèn mã vào tất cả các tệp đó.

Kết quả sau khi chèn:

topview-getview Chức năng-phía trước

Lưu ý rằng khi sử dụng các plugin tạo bộ nhớ đệm cho website như WP Super Cache, W3 Total Cache sẽ hiển thị các khung nhìn không chính xác và chức năng này cũng không hiệu quả. Lý do là bộ nhớ đệm sẽ được lưu trữ dưới dạng tệp .html tĩnh nên giá trị sẽ không thay đổi khi họ truy cập cho đến khi bộ nhớ đệm được xóa. Nhưng bộ đệm cơ sở dữ liệu và bộ đệm đối tượng vẫn hoạt động, tôi đã kiểm tra và thấy rằng, nhưng đối với bạn thì tôi không chắc lắm.

4. Viết widget để hiển thị bài đăng được xem nhiều nhất

Trước hết, để hiểu toàn bộ code, nếu bạn chưa biết thì nên đọc qua hai bài viết sau:

  • Hướng dẫn Hoàn chỉnh về Truy vấn & Vòng lặp trong WordPress
  • Hướng dẫn tạo widget trong 6 bước

Còn đoạn mã tạo widget hiển thị các bài viết được xem nhiều nhất, chúng ta sẽ có như sau, chèn vào file plugins.php luôn luôn:


/* Tạo widget hiển thị bài xem nhiều
* @tham khảo tại http://bit.ly/1tY8TFn
*/

function create_topview_widget() {
register_widget( ‘TopView_Widget’ );
}
add_action( ‘widgets_init’, ‘create_topview_widget’ );

class TopView_Widget extends WP_Widget {

/*
* Thiết lập tên widget và description của nó (Appearance -> Widgets)
*/
function TopView_Widget() {
$options = array(
‘classname’ => ‘topview’,
‘description’ => ‘Xem bài viết xem nhiều nhất’
);
$this->WP_Widget(‘topview’, ‘Top View’, $options);
}

/*
* Tạo form điền tham số cho widget
* ở đây ta có 3 form là title, postnum (số lượng bài) và postdate (tuổi của bài
*/
function form($instance) {
$default = array(
‘title’ => ‘Bài xem nhiều nhất’,
‘postnum’ => 5,
‘postdate’ => 30
);
$instance = wp_parse_args( (array) $instance, $default );
$title = esc_attr( $instance[‘title’] );
$postnum = esc_attr( $instance[‘postnum’] );
$postdate = esc_attr( $instance[‘postdate’] );

echo "<label>Tiêu đề:</label> <input class=’widefat’ type=’text’ name=’".$this->get_field_name(‘title’)."’ value=’".$title."’ />";
echo "<label>Số lượng bài viết:</label> <input class=’widefat’ type=’number’ name=’".$this->get_field_name(‘postnum’)."’ value=’".$postnum."’ />";
echo "<label>Độ tuổi của bài viết (ngày)</label> <input class=’widefat’ type=’number’ name=’".$this->get_field_name(‘postdate’)."’ value=’".$postdate."’ />";
}

/*
* Cập nhật dữ liệu nhập vào form tùy chọn trong database
*/
function update($new_instance, $old_instance) {
$instance = $old_instance;
$instance[‘title’] = strip_tags($new_instance[‘title’]);
$instance[‘postnum’] = strip_tags($new_instance[‘postnum’]);
$instance[‘postdate’] = strip_tags($new_instance[‘postdate’]);
return $instance;
}

function widget($args, $instance) {
global $postdate; // Thiết lập biến $postdate là biến toàn cục để dùng ở hàm filter_where
extract( $args );
$title = apply_filters( ‘widget_title’, $instance[‘title’] );
$postnum = $instance[‘postnum’];
$postdate = $instance[‘postdate’];

echo $before_widget;
echo $before_title.$title.$after_title;

$query_args = array(
‘posts_per_page’ => $postnum,
‘meta_key’ => ‘postview_number’,
‘orderby’ => ‘meta_value_num’,
‘order’ => ‘DESC’,
‘ignore_sticky_posts’ => -1
);

/*
* Cách lấy bài viết theo độ tuổi (-30 days = lấy bài được 30 ngày tuổi)
* @tham khảo tại http://bit.ly/1y7WXFp
*/
function filter_where( $where = ” ) {
global $postdate;
$where .= " AND post_date > ‘" . date(‘Y-m-d’, strtotime(‘-‘.$postdate.’ days’)) . "’";
return $where;
}
add_filter( ‘posts_where’, ‘filter_where’ );

$postview_query = new WP_Query( $query_args );

remove_filter( ‘posts_where’, ‘filter_where’ ); // Xóa filter để tránh ảnh hưởng đến query khác

if ($postview_query->have_posts() ) :
echo "<ul>";
while ( $postview_query->have_posts() ) :
$postview_query->the_post(); ?>

<li>
<?php /* Bỏ comment nếu muốn hiện thumbnail
if ( has_post_thumbnail() )
the_post_thumbnail( ‘thumbnail’ );
else
echo "</br><img src=’http://dummyimage.com/50/000/fff&text=thach’>";
*/
?>
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
</li>

<?php endwhile;
echo "</ul>";
endif;
echo $after_widget;
}
}

Và bây giờ bạn đi vào Giao diện -> Tiện ích và kéo tiện ích có tên Top View vào thanh bên và đặt các tùy chọn cho nó.

topview-widget

Nếu bạn đang sử dụng plugin WP-PostViews và muốn sử dụng tiện ích này cho plugin đó, chỉ cần thay đổi 'meta_key' => 'postview_number' Pháo đài 'meta_key' => 'views'.

5. Thêm CSS cho các widget

Để widget mặc định thì củ chuối quá, sau đây mình có một vài đoạn CSS ngắn để các bạn làm widget đầu bài, nó có cái gì đó đặc biệt hơn một chút. Tuy nhiên, vì nó chỉ là bản demo nên tôi không thể làm gì nhiều ngoài việc đánh số danh sách các bài viết, vì vậy hãy viết thêm CSS nếu cần.

Chèn phần sau vào tệp styles.css


.topview ul {
counter-reset: my-badass-counter;
}
.topview li:before {
content: counter(my-badass-counter);
counter-increment: my-badass-counter;
padding: 5px 15px 8px 0;
line-height: 1em;
color: #7f7f7f;
font-weight: bold;
font-family: Arial!important;
color: #A6A6A6;
float: left;
}
.topview li {
clear: both;
margin: 10px 0;
overflow: hidden;
}
.topview img {
float: left;
margin-right: 5px;
width: 50px;
height: 50px;
}

Cũng chèn phần sau vào tệp plugins.php để nó chèn tệp styles.css của plugin vào chủ đề.


/*
* Chèn CSS của plugin vào theme
*/
function custom_styles() {

wp_register_style( ‘topview-css’, plugins_url( ‘styles.css’, __FILE__ ) , false, false, ‘all’ );
wp_enqueue_style( ‘topview-css’ );

}
add_action( ‘wp_enqueue_scripts’, ‘custom_styles’ );

Bây giờ chúng ta có kết quả:

topview-widget-front

Vậy là xong việc. : D

6. Toàn bộ mã trong bài

Tập tin plugins.php


<?php
/*
Plugin Name: PostView
Plugin Author: ThachPham
Description: Plugin đếm lượt xem bài viết và hiển thị top bài xem nhiều
Version: 1.0
Author URI: https://thachpham.com
*/

// Set post view
function postview_set($postID) {
$count_key = ‘postview_number’;
$count = get_post_meta($postID, $count_key, true);
if($count==”){
$count = 0;
delete_post_meta($postID, $count_key);
add_post_meta($postID, $count_key, ‘0’);
}else{
$count++;
update_post_meta($postID, $count_key, $count);
}
}
// Get post view
function postview_get($postID){
$count_key = ‘postview_number’;
$count = get_post_meta($postID, $count_key, true);
if($count==”){
delete_post_meta($postID, $count_key);
add_post_meta($postID, $count_key, ‘0’);
return "0 lượt xem";
}
return $count.’ lượt xem’;
}

remove_action( ‘wp_head’, ‘adjacent_posts_rel_link_wp_head’, 10, 0);

/* Tạo widget hiển thị bài xem nhiều
* @tham khảo tại http://bit.ly/1tY8TFn
*/

function create_topview_widget() {
register_widget( ‘TopView_Widget’ );
}
add_action( ‘widgets_init’, ‘create_topview_widget’ );

class TopView_Widget extends WP_Widget {

/*
* Thiết lập tên widget và description của nó (Appearance -> Widgets)
*/
function TopView_Widget() {
$options = array(
‘classname’ => ‘topview’,
‘description’ => ‘Xem bài viết xem nhiều nhất’
);
$this->WP_Widget(‘topview’, ‘Top View’, $options);
}

/*
* Tạo form điền tham số cho widget
* ở đây ta có 3 form là title, postnum (số lượng bài) và postdate (tuổi của bài
*/
function form($instance) {
$default = array(
‘title’ => ‘Bài xem nhiều nhất’,
‘postnum’ => 5,
‘postdate’ => 30
);
$instance = wp_parse_args( (array) $instance, $default );
$title = esc_attr( $instance[‘title’] );
$postnum = esc_attr( $instance[‘postnum’] );
$postdate = esc_attr( $instance[‘postdate’] );

echo "<label>Tiêu đề:</label> <input class=’widefat’ type=’text’ name=’".$this->get_field_name(‘title’)."’ value=’".$title."’ />";
echo "<label>Số lượng bài viết:</label> <input class=’widefat’ type=’number’ name=’".$this->get_field_name(‘postnum’)."’ value=’".$postnum."’ />";
echo "<label>Độ tuổi của bài viết (ngày)</label> <input class=’widefat’ type=’number’ name=’".$this->get_field_name(‘postdate’)."’ value=’".$postdate."’ />";
}

/*
* Cập nhật dữ liệu nhập vào form tùy chọn trong database
*/
function update($new_instance, $old_instance) {
$instance = $old_instance;
$instance[‘title’] = strip_tags($new_instance[‘title’]);
$instance[‘postnum’] = strip_tags($new_instance[‘postnum’]);
$instance[‘postdate’] = strip_tags($new_instance[‘postdate’]);
return $instance;
}

function widget($args, $instance) {
global $postdate; // Thiết lập biến $postdate là biến toàn cục để dùng ở hàm filter_where
extract( $args );
$title = apply_filters( ‘widget_title’, $instance[‘title’] );
$postnum = $instance[‘postnum’];
$postdate = $instance[‘postdate’];

echo $before_widget;
echo $before_title.$title.$after_title;

$query_args = array(
‘posts_per_page’ => $postnum,
‘meta_key’ => ‘postview_number’,
‘orderby’ => ‘meta_value_num’,
‘order’ => ‘DESC’,
‘ignore_sticky_posts’ => -1
);

/*
* Cách lấy bài viết theo độ tuổi (-30 days = lấy bài được 30 ngày tuổi)
* @tham khảo tại http://bit.ly/1y7WXFp
*/
function filter_where( $where = ” ) {
global $postdate;
$where .= " AND post_date > ‘" . date(‘Y-m-d’, strtotime(‘-‘.$postdate.’ days’)) . "’";
return $where;
}
add_filter( ‘posts_where’, ‘filter_where’ );

$postview_query = new WP_Query( $query_args );

remove_filter( ‘posts_where’, ‘filter_where’ ); // Xóa filter để tránh ảnh hưởng đến query khác

if ($postview_query->have_posts() ) :
echo "<ul>";
while ( $postview_query->have_posts() ) :
$postview_query->the_post(); ?>

<li>
<?php /* Bỏ comment nếu muốn hiện thumbnail
if ( has_post_thumbnail() )
the_post_thumbnail( ‘thumbnail’ );
else
echo "</br><img src=’http://dummyimage.com/50/000/fff&text=thach’>";
*/
?>
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
</li>

<?php endwhile;
echo "</ul>";
endif;
echo $after_widget;
}
}

/*
* Chèn CSS của plugin vào theme
*/
function custom_styles() {

wp_register_style( ‘topview-css’, plugins_url( ‘styles.css’, __FILE__ ) , false, false, ‘all’ );
wp_enqueue_style( ‘topview-css’ );

}
add_action( ‘wp_enqueue_scripts’, ‘custom_styles’ );

Tập tin style.css


.topview ul {
counter-reset: my-badass-counter;
}
.topview li:before {
content: counter(my-badass-counter);
counter-increment: my-badass-counter;
padding: 5px 15px 8px 0;
line-height: 1em;
color: #7f7f7f;
font-weight: bold;
font-family: Arial!important;
color: #A6A6A6;
float: left;
}
.topview li {
clear: both;
margin: 10px 0;
overflow: hidden;
}
.topview img {
float: left;
margin-right: 5px;
width: 50px;
height: 50px;
}

Giải pháp đếm lượt xem và khả năng tương thích với bộ nhớ cache

Ở bài viết này mình chỉ hướng dẫn các bạn làm một tính năng đếm lượt xem đơn giản nên sẽ không tương thích với cache nguyên nhân mà mình đã giải thích trong bài. Nhưng tôi nghĩ có một giải pháp khác có thể làm cho lượt xem này được đếm rất tốt và tương thích với bộ nhớ cache, đó là sử dụng AJAX để sửa đổi giá trị khóa meta và sử dụng AJAX để lấy dữ liệu trong cơ sở dữ liệu để hiển thị.

Lý do sử dụng AJAX có thể được cache là dù trang của bạn có được cache hay không thì các tệp Javascript vẫn được xử lý bình thường, vì vậy sử dụng AJAX bạn có thể hiểu rằng nó sẽ chỉ lấy dữ liệu. Sau khi trang tải xong, không quan trọng nó có được lưu vào bộ nhớ đệm hay không. Còn cụ thể cái gì thì mình sẽ test thêm rồi viết hướng dẫn sau.

Có thể bạn thích: Plugin đếm lượt xem AJAX hoạt động với bộ nhớ cache.

Phần kết

Bài tiếp theo này có vẻ dài và hy vọng với phần giải thích của tôi, bạn có thể hiểu cách hoạt động của tính năng này và quan trọng nhất là cách xây dựng bộ tính năng này. Bài viết vẫn còn cơ bản nên sẽ có những ý kiến ​​chưa tốt, nếu bạn có thêm ý tưởng nào để phát triển code tối ưu hơn, hãy chia sẻ thêm ở phần bình luận.

Đánh giá nội dung này