Hướng dẫn làm trang đọc truyện bằng WordPress hoàn chỉnh từ A tới Z

Như các bạn đã biết, hiện nay có rất nhiều blog đăng tải truyện để các bạn có nhu cầu đọc trực tuyến, các trang blog này rất ăn khách và cũng đương nhiên là thu về được rất nhiều giá trị, nhưng các blog đăng tải truyện này có một giới hạn nhất định, giới hạn đó chính là độ tiện dụng cũng như điều hướng người đọc truyện sang các chương tiếp theo mỗi khi hết một trang truyện, ngoài ra vì đăng tải theo dạng blog nên người đọc gặp khó khăn khi theo dõi các tập tiếp theo. Người dùng thường bị lẫn giữa blog của tác giả và câu chuyện mình đang theo dõi.

Hiện tại tôi chưa thấy một thông tin nào của cộng đồng WordPress hướng dẫn làm một trang web chuyên đăng tải truyện cho người đọc trực tuyến nào, nên hôm nay tôi sẽ dành chút thời gian cùng các bạn làm một trang blog kiêm luôn trang đăng tải truyện, câu chuyện ngày hôm nay sẽ xoay quanh giao diện Twenty Twelve mặc định của core và file function của giao diện này.

Cuối câu chuyện sẽ là bản QuickStart gồm: Cơ sở dữ liệu tôi tạo sẵn, code giao diện tôi đóng gói sẵn, các bạn chỉ cần giải nén và cài vào blog của mình là được.

Bước 1: Phân tích dữ liệu

Một trang đọc truyện trực tuyến sẽ có các đơn vị như sau:

  1. Thể loại truyện ( Truyện kinh dị, truyện ngôn tình, khoa học viễn tưởng … )
  2. Các Serie tập truyện ( Quyển truyện A, truyện B …)
  3. Truyện ( chương 1, chương 2 … )

Trong đơn vị Truyện sẽ có các phần nhỏ hơn bao gồm:

  1. Ảnh bìa của truyện ( poster )
  2. Giới thiệu ( lời tác giả )
  3. Các chương
  4. Các trang

Vậy là đến đây các bạn có thể hình dung được khối lượng công việc mà chúng ta cần phải giải quyết rồi đúng không? Tiếp theo sẽ là phân tích các đơn vị và mối liên hệ giữa các đơn vị với core của WordPress:

1. Thể loại truyện: vấn đề này được giải quyết bằng các category mặc định, dùng để nhóm các câu chuyện lại theo thể loại.

2. Các serie tập truyện: Chính là Post mặc định của WordPress, trong đó có nội dung ( content ) ta sẽ dùng nó để chứa giới thiệu, ảnh bìa.

Lưu ý! Nếu truyện của bạn không có các chapter, hay không có serie truyện thì bạn có thể dừng lại ở đoạn này, thay vì giới thiệu truyện sẽ là câu truyện ngắn luôn, thích hợp cho truyện cười và các thể loại tâm sự tình cảm

3. Truyện: Truyện sẽ được đưa sang một post_type mới được đặt tên là “story”, tôi đặt thế còn các bạn cũng có thể dùng một cái tên bất kỳ nào khác, chút nữa sẽ có code trực quan để các bạn hiểu hơn.

4. Ảnh bìa và giới thiệu đã được giải quyết ở phần trên, giờ ta giải quyết đơn vị nhỏ hơn nữa là các chương khác nhau và có phân trang, vậy các chương phải nằm trong đơn vị truyện, các trang phải là của các chương, vậy ta sẽ xem sơ đồ sau để hiểu hơn:

Bước 2: Đăng ký Custom Post Type mang tên “story”

Trong WordPress từ phiên bản 3.0 trở đi có hỗ trợ custom post type, các bạn có thể tham khảo trên blog thạch phạm đã đăng tải serie hướng dẫn custom post type để có thêm thông tin nhé.

Bắt đầu:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
add_action( 'init', 'create_post_type' );
function create_post_type() {
register_post_type( 'story',
array(
'labels' => array(
'name' => 'Story',
'singular_name' => 'Story'
),
'show_ui' => true,
'public' => true,
'has_archive' => true,
'taxonomies'    => array('post_tag'), // nếu các bạn muốn tag cho các chương của mình <img src="http://thachpham.com/wp-includes/images/smilies/icon_razz.gif" alt=":P">
'rewrite' => array('slug' => 'story', 'with_front' => FALSE),
'supports' => array( 'title', 'editor', 'author', 'excerpt', 'comments' )
)
);
}

Cho đoạn mã này vào file functions.php của giao diện, ta sẽ được một kết quả là một menu hoàn toàn mới trong admin của WordPress:

Sau khi đăng ký xong sẽ có thêm một rewrite_rules được thêm vào core dưới dạng domain/story/blablblab.html nên các bạn cần phải vào Settings -> Permalink và bấm vào cập nhật để refresh lại rewrite_rules, nếu không mọi thứ sẽ về 404 đó.

Bước 3: Kết nối story với Post

Story hiện giờ chúng ta tạo ra chỉ là “người ngoài cuộc” của câu chuyện, vì tất cả các truyện và poster sẽ được lưu tại Post, nên các bạn cần phải cho chúng một mối liên hệ nào đó, ở đây tôi chọn là post_parent làm mối.

Đầu tiên bạn tạo một ô nhỏ dưới tựa đề của story dùng để điền tên của truyện:

Bạn sử dụng code như sau:

01
02
03
04
05
06
07
08
09
10
11
12
add_action( 'edit_form_after_title', 'mystoryparrent' );
function mystoryparrent( $post_data = false ) {
$scr = get_current_screen();
$value = '';
if ( $post_data ) {
$t = get_post($post_data);
$a = get_post($t->post_parent);
$value = $a->post_title;
}
if ($scr->id == 'story')
echo '<label>Thuộc truyện: <input type="text" name="parent" value="'.$value.'" /></label> (Tên của cuốn truyện gốc)<br /><br />';
}

Bạn cũng lưu ý giùm mình là chỉnh sửa vào code trên cẩn thận nhé, yêu cầu là giải quyết cái trường hợp khi edit lại bài viết vẫn phải tồn tại giá trị mà đã thêm vào trước đó, ví dụ: bạn edit một chap trong truyện “tân tây du kí” thì parent vẫn phải còn ở đó chứ không phải là ô trắng.

Tiếp theo nào, ta cần “hứng” lấy giá trị của Parent khi thêm vào để cho vào chính bài viết này, code này các bạn không nên chỉnh sửa lại nhé:

Có thể bạn muốn xem:   Thể hiện cảm xúc trên FB
01
02
03
04
05
06
07
08
09
10
11
12
13
14
add_action( 'save_post', 'save_mystory' );
function save_mystory( $post_id ) {
$story = isset( $_POST['parent'] ) ? get_page_by_title($_POST['parent'], 'OBJECT', 'post') : false ;
if ( ! wp_is_post_revision( $post_id ) && $story ){
remove_action('save_post', 'save_mystory');
$postdata = array(
'ID' => $_POST['ID'],
'post_parent' => $story->ID
);
wp_update_post( $postdata );
 
add_action('save_post', 'save_mystory');
}
}

Mình dùng hàm wp_is_post_revision để kiểm tra rồi mới cho chạy. Đơn giản là thế này: core WordPress sẽ có các bản revision và các bản nháp lưu liên tục tránh mất dữ liệu, nhưng nếu là revision thì core của WordPress sẽ bị lặp lại một vòng tuần hoàn vô tận, điều đó cũng giải thích cho việc mình dùng 2 hook đối nhau trong hàm này là remove_actionadd_action, đơn giản là tránh lỗi …

Bây giờ chúng ta có thể thử như sau: tạo một truyện tên là “anh yêu em” nằm bên post, cho nó vào category là truyện tình yêu, tiếp theo ta sang bên story và đăng chap đầu tiên là “làm quen” và thêm vào input “thuộc truyện” là anh yêu em, vậy là ta đã cho story biết chúng là chap thuộc truyện “anh yêu em” rồi đúng không ?

Bước 4: Phân trang cho chapter/chương

Để phân trang thì cách tốt nhất và đơn giản nhất là đăng tiêu đề trùng nhau, thêm hậu tố page-x vào đường dẫn của story, mình lấy ví dụ thế này:

Như vậy sau này khi hiển thị mình chỉ cần kiểm tra hậu tố này là có thể phân thành trang cho chương của mình một cách nhanh chóng và an toàn, thậm chí là dễ làm nhất, bạn có thể đăng bất kỳ một trang nào trước, trang nào sau, không cần phải sắp xếp phức tạp.

Bước 5: Hiển thị

Vậy là chúng ta đã giải quyết hết bài toán của phần phân tích dữ liệu, giờ đây chúng ta chuyển sang phần hiển thị, theo tôi thì phần này khá đơn giản tùy vào nhu cầu/năng khiếu thẩm mỹ của các bạn thôi.

Tôi lấy ví dụ như sau:

Code như sau:

01
02
03
04
05
06
07
08
09
10
11
12
13
function get_dropdown_part( $id ) {
global $post, $wpdb;
$query = $wpdb->get_results(sprintf('<wbr />select * from %s where post_type = \'%s\' and post_parent = %d and post_status = \'%s\'', $wpdb->posts, 'story', $id, 'publish'));
if ($query) {
echo '<ul>';
foreach ( $query as $k ) {
$uri = get_permalink($k->ID);
if ( ! preg_match('/.*page-[0-9].*/', $uri))
echo '<li><a href="'.$uri.'">'.$k->post_<wbr />title .'</a></li>';
}
echo '</ul>';
}
}

Bỏ đoạn mã trên vào file functions.php của giao diện, tiếp theo ta gọi chúng ra tại file single.php, bất cứ chỗ nào trong vòng lặp while mà bạn muốn, mở file lên tìm hàm: get_template_part sau đó thêm get_dropdown_part(get_the_ID()); vào ngay phía trên, sẽ xuất hiện một hình chọn các chương như ảnh trên.

Mình đã trang trí xong được phần vào đọc các chương rồi nè, giống y như wattpad.com nhé:

Code trong file single.php

01
02
03
04
05
06
07
08
09
10
11
<?php while ( have_posts() ) : the_post(); ?>
 
<?php if ( get_post_type() == 'story') {
printf( '<p>Thuộc truyện: <a href="%s">%s</a></p><br />', get_permalink($post->post_parent), get_the_title($post->post_parent));
get_dropdown_part($post->post_parent);
} ?>
<?php get_dropdown_part(get_the_ID()); ?>
 
<?php get_template_part( 'content', get_post_format() ); ?>
 
...( vân vân bên dưới nữa ...)

Phân trang cho chương:

Mình đã phân trang cho các chương của mình như ảnh minh họa sau đây:

Tùy vào khiếu thẩm mỹ mà các bạn làm cho đẹp hơn nhé

Còn đây là code mình làm:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
function get_page_chapter_list() {
global $post, $wpdb;
$slug = preg_replace('#-page-[0-9]#', '', $post->post_name);
$data = $wpdb->get_results( "select * from $wpdb->posts where post_name LIKE '%$slug%' order by post_name asc");
if ( $data ) {
$i = 0;
echo '<ul>';
echo '<li><a href="'.get_permalink($post->post_parent).'">Trở về: '.get_the_title($post->post_parent).'</a></li>';
foreach ( $data as $k ) {
++$i;
$e .= '<li><a href="'.get_permalink($k->ID).'">'.$i.'</a></li>';
}
echo $e;
echo '</ul>';
}
}

Tới đây thì trang blog đọc truyện của bạn đã “đáng gườm” như wattpad rồi đấy !

Tổng kết

Với mong muốn giúp các bạn tự tạo được một trang đọc truyện trực tuyến đơn giản và nhanh nhất có thể, tôi đã chia sẻ và giúp các bạn hiểu nguyên tắc tạo ra một trang đọc truyện, qua bài này các bạn cũng đã được tôi chia sẻ cách phân tích dữ liệu cho một website, đây là trang đọc truyện nên còn đơn giản đấy, nhưng hãy bắt đầu một cái đơn giản bằng việc tạo cho mình một trang đọc truyện trực tuyến thật đắt khách nhé.

Qua đây các bạn cũng được tham khảo thêm các cách để tạo ra Custom Post Type trong WordPress phù hợp với trang của mình rồi, đây mới chỉ là một cách tạo trang đọc truyện đơn giản nhất thôi, nếu các bạn có yêu cầu phức tạp hơn thì cần phải tối ưu rất nhiều điểm nữa. Mình xin dừng bài viết tại đây và chúc mọi người vui vẻ. Nếu có bất kỳ một vấn đề vướng mắc nào các bạn hãy để lại comment để cộng đồng trợ giúp.

* Đính kèm: QuickStart ( bao gồm giao diện và cơ sở dữ liệu demo của Tut )