Skip to main content

Bỏ /category/ trong url Wordpress không cần plugin (áp dụng được cả cho category nhiều cấp)

Một trong những ưu điểm của wordpress (so với các nền tảng blog khác) là cho phép rewrite URL để có các URL thân thiện - điều này rất quan trọng trong SEO. Tuy nhiên, mặc định thì URL của Wordpress cũng không được ưng ý, bài viết này sẽ giúp bạn tùy biến URL tối ưu SEO và cũng đẹp mắt nữa.
Bỏ /category/ trong url Wordpress không cần plugin (áp dụng được cả category nhiều cấp)
Để tùy chỉnh lại URL, bạn có thể dùng plugin có sẵn, cài đặt vào và cấu hình là xong. Nhưng tác hại của việc cài nhiều plugin thì đã khá rõ, và tôi không khuyến khích việc phụ thuộc vào plugin (các blogger kỳ cựu về Wordpress cũng khuyên không nên dùng quá 10 plugin, với tôi, con số đó là 5) - thay vào đó, bạn chỉ cần vài thao tác đơn giản mà tôi hướng dẫn chi tiết bên dưới.

Có hai cấu trúc URL của Wordpress mà chúng ta cần tinh chỉnh lại:
1- URL của một post, mặc định sẽ có dạng: http://www.yourblog.com/?p=123 
2- URL của một category, mặc định sẽ có dạng: http://www.yourblog.com/category/category_name hoặc category hai cấp có dạng:  http://www.yourblog.com/category/category_name/sub_category_name 

=> Theo kinh nghiệm thì URL tối ưu của hai trường dạng này phải là: 
1- URL của một post: http://www.yourblog.com/category_name/post_name:
2- URL của một category: http://www.yourblog.com/category_name hoặc category hai cấp có dạng:  http://www.yourblog.com/category_name/sub_category_name 

Để chỉnh lại hai dạng URL này, chúng ta làm như sau:
1- Với URL của một post (topic), thì đơn giản, bạn vào trang quản trị blog của bạn => Vào Setting => Permalink. Đánh dấu vào Custom và paste vào dòng sau: /%category%/%postname%. Thế là xong.

Để chỉnh lại hai dạng URL này, chúng ta làm như sau:


2- Với URL của một category, bạn chỉ cần thêm function sau (copy và paste vào file FUNCTIONS.PHP của theme hiện tại) rồi lưu lại là xong, code này đã test OK đối với category hai cấp => bạn có thể download tại đây.
register_activation_hook(__FILE__, 'no_category_base_refresh_rules');
add_action('created_category', 'no_category_base_refresh_rules');
add_action('edited_category', 'no_category_base_refresh_rules');
add_action('delete_category', 'no_category_base_refresh_rules');
function no_category_base_refresh_rules() {
global $wp_rewrite;
$wp_rewrite -> flush_rules();
}
register_deactivation_hook(__FILE__, 'no_category_base_deactivate');
function no_category_base_deactivate() {
remove_filter('category_rewrite_rules', 'no_category_base_rewrite_rules');
// We don't want to insert our custom rules again
no_category_base_refresh_rules();
}
// Remove category base
add_action('init', 'no_category_base_permastruct');
function no_category_base_permastruct() {
global $wp_rewrite, $wp_version;
if (version_compare($wp_version, '3.4', '<')) {
// For pre-3.4 support
$wp_rewrite -> extra_permastructs['category'][0] = '%category%';
} else {
$wp_rewrite -> extra_permastructs['category']['struct'] = '%category%';
}
}
// Add our custom category rewrite rules
add_filter('category_rewrite_rules', 'no_category_base_rewrite_rules');
function no_category_base_rewrite_rules($category_rewrite) {
//var_dump($category_rewrite); // For Debugging
$category_rewrite = array();
$categories = get_categories(array('hide_empty' => false));
foreach ($categories as $category) {
$category_nicename = $category -> slug;
if ($category -> parent == $category -> cat_ID)// recursive recursion
$category -> parent = 0;
elseif ($category -> parent != 0)
$category_nicename = get_category_parents($category -> parent, false, '/', true) . $category_nicename;
$category_rewrite['(' . $category_nicename . ')/(?:feed/)?(feed|rdf|rss|rss2|atom)/?$'] = 'index.php?category_name=$matches[1]&feed=$matches[2]';
$category_rewrite['(' . $category_nicename . ')/page/?([0-9]{1,})/?$'] = 'index.php?category_name=$matches[1]&paged=$matches[2]';
$category_rewrite['(' . $category_nicename . ')/?$'] = 'index.php?category_name=$matches[1]';
}
// Redirect support from Old Category Base
global $wp_rewrite;
$old_category_base = get_option('category_base') ? get_option('category_base') : 'category';
$old_category_base = trim($old_category_base, '/');
$category_rewrite[$old_category_base . '/(.*)$'] = 'index.php?category_redirect=$matches[1]';
//var_dump($category_rewrite); // For Debugging
return $category_rewrite;
}
add_filter('query_vars', 'no_category_base_query_vars');
function no_category_base_query_vars($public_query_vars) {
$public_query_vars[] = 'category_redirect';
return $public_query_vars;
}
// Redirect if 'category_redirect' is set
add_filter('request', 'no_category_base_request');
function no_category_base_request($query_vars) {
//print_r($query_vars); // For Debugging
if (isset($query_vars['category_redirect'])) {
$catlink = trailingslashit(get_option('home')) . user_trailingslashit($query_vars['category_redirect'], 'category');
status_header(301);
header("Location: $catlink");
exit();
}
return $query_vars;
}

Và đây là kết quả:
Với URL của một category

Ghi chú thêm là: bạn có thể dùng plugin như: WP No Category Base, Remove Category Base, ... nhưng như tôi đã nói, dùng plugin là phương án cuối cùng thôi. Ngoài ra cũng có nhiều người hướng dẫn, ví dụ trên blog yeuwordpress, đoạn mã khá đơn giản, nhưng tôi đã test và code đó không dùng được cho category hai cấp (Chẳng hạn cấp 1 là blog, trong blog có wordpress và blogspot => wordpress và blogspot là cấp 2, khi đó link sau sẽ không hoạt động được: http://www.yourblog.com/blog/wordpress)

Chúc vui!

Comments