Bạn đã bao giờ nghĩ rằng category có thể có giao diện khác với giao diện chính ? Bạn có nghĩ rằng chúng sẽ dễ dàng được cấu hình được mỗi category của blog bạn bằng một gói giao diện đã có sẵn trong trang thậm chí chúng không cần phải active ? Nếu trước kia bạn chưa từng thử làm hoặc bạn đang muốn làm điều này mà chưa tìm được phương hướng để làm thì hãy đọc kỹ bài viết này của tôi, tôi sẽ chỉ cho các bạn cách đơn giản nhất để cấu hình mỗi category của bạn vào một bộ giao diện riêng biệt để blog hay website của bạn dễ dàng thiết kế hơn, hoặc đỡ “nhàm” hơn nhé.
Phần I: Phân tích vấn đề
Hệ thống của WordPress luôn gọi tới một gói giao diện để hiển thị website/blog của bạn, bạn có thể dễ dàng tìm thấy dữ liệu này tại bảng option của WordPress, và cụ thể là được lưu trữ trong option_name = template.
Vậy ta cần làm là phải tìm được hook can thiệp vào việc gọi giá trị này để thay đổi dựa theo category_id hoặc bất cứ cái gì chúng ta muốn.
Tiếp nữa là chúng ta cần phải hook vào category để lưu được giá trị của tên giao diện mà chúng ta muốn cho mỗi một category.
Và cuối cùng là bạn hãy chuẩn bị ba bốn gói giao diện đã chờ sẵn trong trang của bạn để cấu hình nhé !
Phần II: Thực hiện
1. Hiển thị danh sách của các gói giao diện trong trang của bạn
Trước hết, để hiển thị danh sách các gói giao diện hiện đang có trong website/blog của bạn thì cần phải gọi hàm có trong core của WordPress là “wp_get_themes”, nó sẽ tạo ra một danh sách các gói giao diện, ta có hàm sau:
function jamviet_edit_taxonomy( $tag ) {
$tagID = $tag->term_id;
$cat_theme = get_option("cat-$tagID-template");
$themes = wp_get_themes();
$theme_options = ‘<option value="">Default</option>’;
foreach ( $themes as $theme ) {
$selected = ($cat_theme == $theme->template) ? ‘ selected="selected"’ : ”;
$theme_options .= ‘<option value="’ . $theme->template . ‘"’.$selected.’>’ . $theme->Name . ‘</option>’;
}
?>
<tr>
<th scope="row" valign="top">Select the templates</th>
<td><div><select name="cat_theme"><?php echo $theme_options; ?></select>
<span>Select a template in your CMS</span></div>
</td>
</tr>
<?php
}
Với code trên ta đã có một danh sách các gói giao diện, code trên tôi đã để sẵn hàm get_option(“cat-$tagID-template”) để hiển thị chính xác gói giao diện mà bạn đã chọn trước đó nên bạn cứ để nguyên vậy không chỉnh sửa nhé, giờ ta sẽ kết hợp với phần 2.
2. Can thiệp vào edit category và new category trong admin
Để cho danh sách giao diện phần bên trên vào trong vùng edit hay add của category trong admin ta phải hook vào core, ta dùng hai hook sau:
add_action( ‘category_edit_form_fields’, ‘jamviet_edit_taxonomy’ );
add_action( ‘category_add_form_fields’, ‘jamviet_edit_taxonomy’ );
Vậy là cả hai vùng edit và add new category sẽ hiển thị một Dropdown Box để chúng ta lựa chọn gói giao diện rồi nhé, bây giờ chúng ta sẽ xem kết quả đầu tiên này:
3. Lưu giá trị bạn chọn
Để lưu giá trị mà bạn chọn ( tên gói giao diện ) vào trong category bạn cần dùng hàm sau:
function jamviet_save_taxonomy( $tagID ) {
if ( isset( $_POST ) ) {
update_option("cat-$tagID-template", $_POST);
}
}
add_action( ‘edited_category’, ‘jamviet_save_taxonomy’, 10, 2 );
Nếu bạn bấm nút Update hoặc Add new category thì hàm này sẽ nhận giá trị của category mới thêm vào và lưu vào vùng cat-ID-template để sau này chúng ta sẽ sử dụng giá trị và hiển thị đúng giao diện cho category vừa được set.
4. Hook vào core
Đoạn code sau đây dùng để kiểm tra xem đường dẫn là category hay là post, sau đó sẽ query ngược lại để tìm category ID, tiếp theo là tìm tên của giao diện mà chúng ta đã cài đặt từ trước và thay đổi giao diện, xin lưu ý với các bạn là code sau đây không được phép chỉnh sửa, tôi sẽ giải thích sau:
add_filter( ‘pre_option_template’, ‘jamviet_change_template’ );
add_filter( ‘pre_option_stylesheet’, ‘jamviet_change_template’ );
function jamviet_change_template( $template_name ) {
$pid=$cid=0;
$s=empty($_SERVER)?”:$_SERVER==’on’?’s’:”;
$protocol=’http’.$s;
$port=$_SERVER==’80’?”:’:’.$_SERVER;
$url=$protocol.’://’.$_SERVER.$port.$_SERVER;
list($url)=explode(‘?’,$url);
$pid=url_to_postid($url);
// fixed – lỗi khi phân trang …
list($url)=explode(‘/page/’,$url);
$cid=get_category_by_path($url,false);
$cid=$cid->cat_ID;
create_initial_taxonomies();
if($cid) {
$cat=$cid;
}
elseif ($pid !=0 && get_post_type($pid) != "page") {
list($cat)=wp_get_post_categories($pid);
}
else {
// giao diện về mặc định …
$cat = 0;
}
return get_option("cat-$cat-template") ? get_option("cat-$cat-template") : $template_name;
Đoạn code trên này lấy cho bằng được giá trị của Category ID để thay đổi giao diện, nếu không có chúng ta sẽ trả về giao diện mặc định, nhưng các bạn sẽ thấy chúng ta không dùng is_post hay is_category vì đơn giản là code này phải để vào plugin chứ không phải file function của giao diện nên phải tìm các post id và cat id qua đường dẫn ( plugin thực thi trước các hàm kiểm tra này ), vì sao lại để vào plugin mà không phải functions.php của giao diện ? Đơn giản là bạn phải thay đổi giao diện theo category ID nên bạn sẽ không thể để được trong file functions.
Đoạn code này có hàm “create_initial_taxonomies” để gọi taxonomy, nhưng với phiên bản mới nhất thì nó không hoạt động hiệu quả khi bạn muốn gọi taxonomy sớm trong plugin ( chính là category ).
Và kết quả là:
Phần III : Tổng kết
Vậy là trang của bạn đã chuyển giao diện một cách hoàn toàn tự động phụ thuộc và category rồi, không những thế – toàn bộ bài viết nằm trong category cũng sẽ theo giao diện chính của category, hãy cho tất cả các dòng code trên vào plugin và kích hoạt, bạn sẽ thấy điều dường như không thể biến thành có thể rồi !
Tôi có thấy rất nhiều bạn hỏi về vấn đề chuyển giao diện tự động phụ thuộc vào category nhưng không thấy có bài viết nào hướng dẫn cụ thể vấn đề này. Cũng có nhiều bạn nói rằng đây là điều không thể, nhưng với tôi WordPress có thể làm được mọi việc, hi vọng có ích cho các bạn, chúc các bạn thành công, hãy để lại nhận xét nếu có vướng mắc nhé !
* Tôi đã đóng gói các code trong bài viết này vào thành plugin, nếu các bạn cần chức năng này có thể Download plugin này trên WordPress.org.