[CakePHP] Tạo lưu trữ bài viết hằng tháng (Monthly Archives)

Hôm nay tôi sẽ mang đến cho các bạn một thủ thuật nhỏ, áp dụng cho các website cá nhân được phát triển với nền tảng CakePHP. Đó là hướng dẫn cách tạo mục lưu trữ bài viết hằng tháng (monthly archives). Với 1 trang web cá nhân thì không nên thiếu mục lưu trữ bài viết vì nó giúp bạn đọc tiện xem lại các bài viết cũ theo năm tháng.

[CakePHP] Lưu trữ bài viết

1, Tạo cơ sở dữ liệu

Đầu tiên các bạn cần tạo 1 bảng để chứa nội dung các bài viết, ở đây tôi sẽ tạo bảng posts để lưu bài viết.

CREATE TABLE IF NOT EXISTS `posts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) DEFAULT NULL,
`content` text,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

2, Tạo mục lưu trữ bài viết

Việc tiếp theo là thao tác trong Controller để lấy dữ liệu, các bạn mở file app/controllers/posts_controller.php và chèn 2 hàm dưới đây:

<?php
class PostsController extends AppController {
// Lấy danh sách lưu trữ hằng tháng
function list_archive() {
$archives = $this->Post->find('all', array(
'fields' => array('DATE_FORMAT(Post.created, \'%M %Y\') AS dd', 'count(Post.id) AS numblogs'),
'conditions' => array('Post.active' => 1),
'order' => array('dd ASC'),
'group' => array('dd')
)
);
return $archives;
}
// Hiển thị danh sách các bài viết khi người dùng click 1 tháng nào đó (bài viết được phân trang)
function archive($year = null, $month = null) {
$first = date('Y-m-d', mktime(0, 0, 0, $month, 1, $year));
$last = date('Y-m-t', mktime(0, 0, 0, $month, 1, $year));
$cond = array(
'AND' => array(
'Post.created >=' => $first,
'Post.created <=' => $last
),
);
switch($month) {
case "01" : $archive = "January ".$year; break;
case "02" : $archive = "February ".$year; break;
case "03" : $archive = "March ".$year; break;
case "04" : $archive = "April ".$year; break;
case "05" : $archive = "May ".$year; break;
case "06" : $archive = "June ".$year; break;
case "07" : $archive = "July ".$year; break;
case "08" : $archive = "August ".$year; break;
case "09" : $archive = "September ".$year; break;
case "10" : $archive = "October ".$year; break;
case "11" : $archive = "November ".$year; break;
case "12" : $archive = "December ".$year; break;
}
// Đặt tiêu đề cho trang lưu trữ
$this->set('title_for_layout', 'Monthly Archive '.$archive);
// Phân trang cho bài viết
$this->Post->recursive = 1;
$this->set('posts', $this->paginate('Post', $cond));
}
}
?>
  • Hàm list_archive() sẽ lấy danh sách các tháng dựa vào ngày mà các bài viết được tạo ra. Giả sử bài viết đầu tiên được tạo vào ngày 01/02/2012 và bài viết cuối cùng tạo ra vào ngày 09/09/2012 thì hàm list_archive() sẽ in ra danh sách từ tháng 1 đến tháng 9 và đồng thời sẽ đếm trong mỗi tháng có bao nhiêu bài viết.
  • Hàm archive() với 2 tham số là $year$month sẽ liệt kê và phân trang các bài viết trong 1 tháng nào đó.

3, Hiển thị lưu trữ bài viết

Cuối cùng, các bạn chỉ cần hiển thị danh sách mục lưu trữ ra ngoài View. Bạn nên chọn hiển thị ra ngoài 1 element vì element linh hoạt hơn.

+ Tạo file archive_blog.ctp trong thư mục app/views/elements với nội dung như sau:

<?php
$archives = $this->requestAction('/posts/list_archive');
if (!empty($archives)) {
foreach($archives as $archive) {
$arr = array();
$arr = explode(" ", $archive[0]['dd']);</ul>
$year = $arr[1];
switch($arr[0]) {
case "January" : $month = "01"; break;
case "February" : $month = "02"; break;
case "March" : $month = "03"; break;
case "April" : $month = "04"; break;
case "May" : $month = "05"; break;
case "June" : $month = "06"; break;
case "July" : $month = "07"; break;
case "August" : $month = "08"; break;
case "September" : $month = "09"; break;
case "October" : $month = "10"; break;
case "November" : $month = "11"; break;
case "December" : $month = "12"; break;
}
echo '
<ul>
<li>'.$this->Html->link($archive[0]['dd'].' ('.$archive[0]['numblogs'].')', array('controller' => 'posts', 'action' => 'archive', $year.'/'.$month)).'</li>
</ul>';
}
}
?>

Nếu bạn muốn chèn element này vào 1 layout bất kì thì chỉ cần dùng dòng lệnh sau:

<?php echo $this->element('archive_blog'); ?>

+ Tiếp theo bạn cần phải tạo 1 trang kết quả để liệt kê các bài viết khi người dùng click vào 1 tháng nào đó. Tạo file archive.ctp trong thư mục app/views/posts với nội dung mà bạn muốn hiển thị. Ở đây tôi sẽ làm một trang đơn giản như sau:

<?php
if (!empty($posts)) {
foreach($posts as $post) {
echo $this>Html>link($post['Post']['title'], array('controller' => 'posts', 'action' => 'view', 'id' => $post['Post']['id']));
}
} else {
echo '<strong>No posts found.</strong>';
}
?>
// Phân trang bài viết
<div>
<?php
echo 'Page '.$this>Paginator>counter(array('separator'=>' / '));
echo $this>Paginator>first(__('First', true), array(), null, array('class' => 'disabled'));
echo $this>Paginator>numbers(array('separator'=>''));
echo $this>Paginator>last(__('Last', true), array(), null, array('class' => 'disabled'));
?>
</div>

Hi vọng bài viết này giúp ích các bạn. Thân !

Tấn Việt

Tôi lập trang web này để thỏa mãn sở thích viết cái gì đó vui vui khi rãnh rỗi và đồng thời cũng chia sẻ những gì tôi biết hoặc đọc đâu đó trên mạng về Lập trình web. Tôi hi vọng những bài viết này sẽ giúp ích cho các bạn. Thân ái!

You may also like…