[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.
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 và $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 !