Bài này mình sẽ hướng dẫn cho các bạn cách thay đổi tiêu đề cho trang của WordPress thông qua các bộ lọc có sẵn. Mục đích là để bạn viết lại thẻ title phù hợp với SEO hoặc bạn cập nhật thêm những thông tin liên quan khác trong này ngoài tiêu đề mặc định của đối tượng.
Đầu tiên thì bạn sẽ xem qua các hàm mà WordPress hỗ trợ từ phiên bản 4.4 trở về sau. Trong phiên bản WordPress 4.4 thì WordPress đã hỗ trợ giao diện support title-tag, nếu giao diện có sử dụng add_theme_supports('title-tag');
để thêm tính năng tự động tạo thẻ title ở phần head thì bạn sẽ áp dụng được các bộ lọc liên quan.
/** * Displays title tag with content. * * @ignore * @since 4.1.0 * @since 4.4.0 Improved title output replaced `wp_title()`. * @access private */ function _wp_render_title_tag() { if ( ! current_theme_supports( 'title-tag' ) ) { return; } echo '<title>' . wp_get_document_title() . '</title>' . "\n"; }
Hàm bên trên sẽ có chức năng xuất thẻ title ra giữa thẻ head nếu giao diện có hỗ trợ tính năng title-tag. Như bạn thấy trong đoạn code bên trên thì WordPress sử dụng hàm wp_get_document_title()
để lấy thông tin tiêu đề trang hiện tại.
/** * Returns document title for the current page. * * @since 4.4.0 * * @global int $page Page number of a single post. * @global int $paged Page number of a list of posts. * * @return string Tag with the document title. */ function wp_get_document_title() { /** * Filter the document title before it is generated. * * Passing a non-empty value will short-circuit wp_get_document_title(), * returning that value instead. * * @since 4.4.0 * * @param string $title The document title. Default empty string. */ $title = apply_filters( 'pre_get_document_title', '' ); if ( ! empty( $title ) ) { return $title; } global $page, $paged; $title = array( 'title' => '', ); // If it's a 404 page, use a "Page not found" title. if ( is_404() ) { $title['title'] = __( 'Page not found' ); // If it's a search, use a dynamic search results title. } elseif ( is_search() ) { /* translators: %s: search phrase */ $title['title'] = sprintf( __( 'Search Results for “%s”' ), get_search_query() ); // If on the front page, use the site title. } elseif ( is_front_page() ) { $title['title'] = get_bloginfo( 'name', 'display' ); // If on a post type archive, use the post type archive title. } elseif ( is_post_type_archive() ) { $title['title'] = post_type_archive_title( '', false ); // If on a taxonomy archive, use the term title. } elseif ( is_tax() ) { $title['title'] = single_term_title( '', false ); /* * If we're on the blog page that is not the homepage or * a single post of any post type, use the post title. */ } elseif ( is_home() || is_singular() ) { $title['title'] = single_post_title( '', false ); // If on a category or tag archive, use the term title. } elseif ( is_category() || is_tag() ) { $title['title'] = single_term_title( '', false ); // If on an author archive, use the author's display name. } elseif ( is_author() && $author = get_queried_object() ) { $title['title'] = $author->display_name; // If it's a date archive, use the date as the title. } elseif ( is_year() ) { $title['title'] = get_the_date( _x( 'Y', 'yearly archives date format' ) ); } elseif ( is_month() ) { $title['title'] = get_the_date( _x( 'F Y', 'monthly archives date format' ) ); } elseif ( is_day() ) { $title['title'] = get_the_date(); } // Add a page number if necessary. if ( ( $paged >= 2 || $page >= 2 ) && ! is_404() ) { $title['page'] = sprintf( __( 'Page %s' ), max( $paged, $page ) ); } // Append the description or site title to give context. if ( is_front_page() ) { $title['tagline'] = get_bloginfo( 'description', 'display' ); } else { $title['site'] = get_bloginfo( 'name', 'display' ); } /** * Filter the separator for the document title. * * @since 4.4.0 * * @param string $sep Document title separator. Default '-'. */ $sep = apply_filters( 'document_title_separator', '-' ); /** * Filter the parts of the document title. * * @since 4.4.0 * * @param array $title { * The document title parts. * * @type string $title Title of the viewed page. * @type string $page Optional. Page number if paginated. * @type string $tagline Optional. Site description when on home page. * @type string $site Optional. Site title when not on home page. * } */ $title = apply_filters( 'document_title_parts', $title ); $title = implode( " $sep ", array_filter( $title ) ); $title = wptexturize( $title ); $title = convert_chars( $title ); $title = esc_html( $title ); $title = capital_P_dangit( $title ); return $title; }
Như vậy, cái bạn cần thay đổi đó là kết quả trả về của hàm wp_get_document_title()
, trong hàm này thì WordPress sử dụng 2 bộ lọc, cho phép bạn lọc kết quả trước và sau khi lấy title.
1. pre_get_document_title: Đây là bộ lọc trước khi WordPress lấy thẻ title, nếu sau khi dùng bộ lọc này mà kết quả trả về là có giá trị khác rỗng thì hàm sẽ lấy giá trị trả về từ bộ lọc.
2. document_title_parts: Đây là bộ lọc sau khi thẻ title và các thành phần khác liên quan được lấy, kết quả sẽ là một mảng các giá trị, nếu bạn thay đổi nội dung của tiêu đề thì bạn sẽ dùng theo kiểu truy xuất mảng $title['title']
.
Ngoài ra, trong hàm còn có sử dụng bộ lọc document_title_separator
để thay đổi ký tự phân cách giữa các thành phần trong thẻ tiêu đề.
Bây giờ bạn sẽ thử dùng bộ lọc document_title_parts
trước:
function hocwp_theme_custom_title_date( $title ) { if ( ! is_home() ) { if ( is_tax( 'store' ) ) { $title['title'] .= ' ' . date( 'F Y' ); } } return $title; } add_filter( 'document_title_parts', 'hocwp_theme_custom_title_date', 99 );
Trong hàm bên trên, mình tạo bộ lọc để lọc thẻ tiêu đề, tự động thêm tháng năm vào sau tiêu đề cho trang lưu trữ các chuyên mục thuộc taxonomy store. Như bạn thấy trong đoạn code này, giá trị đầu vào là một mảng chứa các thành phần của tiêu đề, bạn chỉ cần chỉnh sửa nội dung chữ ở key title
trong mảng.
function hocwp_theme_custom_pre_document_title( $title ) { if ( ! is_home() ) { if ( is_tax( 'store' ) ) { $title = single_term_title( '', false ) . ' ' . date( 'F Y' ); } } return $title; } add_filter( 'pre_get_document_title', 'hocwp_theme_custom_pre_document_title', 99 );
Trong đoạn code ví dụ thứ 2 bên trên, bạn sẽ trả về một giá trị là chuỗi tiêu đề bằng cách sử dụng bộ lọc pre_get_document_title
, lúc đầu tiêu đề đầu vào là giá trị rỗng nếu chưa có bộ lọc nào khác phía trước thay đổi nội dung của biến. Và dĩ nhiên thì bạn phải kiểm tra các hàm điều kiện của WordPress để biết trang hiện tại là gì, từ đó mới lấy thông tin thích hợp gán cho thẻ tiêu đề.
Lọc tiêu đề đối với phiên bản WordPress cũ
Trong phiên bản WordPress 4.3 trở về trước thì WordPress sẽ sử dụng hàm wp_title
để xuất tiêu đề. Để thay đổi được thông tin tiêu đề ở các phiên bản cũ này thì bạn phải xem qua nội dung của hàm wp_title
trước nhé.
/** * Display or retrieve page title for all areas of blog. * * By default, the page title will display the separator before the page title, * so that the blog title will be before the page title. This is not good for * title display, since the blog title shows up on most tabs and not what is * important, which is the page that the user is looking at. * * There are also SEO benefits to having the blog title after or to the 'right' * or the page title. However, it is mostly common sense to have the blog title * to the right with most browsers supporting tabs. You can achieve this by * using the seplocation parameter and setting the value to 'right'. This change * was introduced around 2.5.0, in case backwards compatibility of themes is * important. * * @since 1.0.0 * * @global WP_Locale $wp_locale * * @param string $sep Optional, default is '»'. How to separate the various items * within the page title. * @param bool $display Optional, default is true. Whether to display or retrieve title. * @param string $seplocation Optional. Direction to display title, 'right'. * @return string|null String on retrieve, null when displaying. */ function wp_title( $sep = '»', $display = true, $seplocation = '' ) { global $wp_locale; $m = get_query_var( 'm' ); $year = get_query_var( 'year' ); $monthnum = get_query_var( 'monthnum' ); $day = get_query_var( 'day' ); $search = get_query_var( 's' ); $title = ''; $t_sep = '%WP_TITLE_SEP%'; // Temporary separator, for accurate flipping, if necessary // If there is a post if ( is_single() || ( is_home() && ! is_front_page() ) || ( is_page() && ! is_front_page() ) ) { $title = single_post_title( '', false ); } // If there's a post type archive if ( is_post_type_archive() ) { $post_type = get_query_var( 'post_type' ); if ( is_array( $post_type ) ) { $post_type = reset( $post_type ); } $post_type_object = get_post_type_object( $post_type ); if ( ! $post_type_object->has_archive ) { $title = post_type_archive_title( '', false ); } } // If there's a category or tag if ( is_category() || is_tag() ) { $title = single_term_title( '', false ); } // If there's a taxonomy if ( is_tax() ) { $term = get_queried_object(); if ( $term ) { $tax = get_taxonomy( $term->taxonomy ); $title = single_term_title( $tax->labels->name . $t_sep, false ); } } // If there's an author if ( is_author() && ! is_post_type_archive() ) { $author = get_queried_object(); if ( $author ) { $title = $author->display_name; } } // Post type archives with has_archive should override terms. if ( is_post_type_archive() && $post_type_object->has_archive ) { $title = post_type_archive_title( '', false ); } // If there's a month if ( is_archive() && ! empty( $m ) ) { $my_year = substr( $m, 0, 4 ); $my_month = $wp_locale->get_month( substr( $m, 4, 2 ) ); $my_day = intval( substr( $m, 6, 2 ) ); $title = $my_year . ( $my_month ? $t_sep . $my_month : '' ) . ( $my_day ? $t_sep . $my_day : '' ); } // If there's a year if ( is_archive() && ! empty( $year ) ) { $title = $year; if ( ! empty( $monthnum ) ) { $title .= $t_sep . $wp_locale->get_month( $monthnum ); } if ( ! empty( $day ) ) { $title .= $t_sep . zeroise( $day, 2 ); } } // If it's a search if ( is_search() ) { /* translators: 1: separator, 2: search phrase */ $title = sprintf( __( 'Search Results %1$s %2$s' ), $t_sep, strip_tags( $search ) ); } // If it's a 404 page if ( is_404() ) { $title = __( 'Page not found' ); } $prefix = ''; if ( ! empty( $title ) ) { $prefix = " $sep "; } /** * Filter the parts of the page title. * * @since 4.0.0 * * @param array $title_array Parts of the page title. */ $title_array = apply_filters( 'wp_title_parts', explode( $t_sep, $title ) ); // Determines position of the separator and direction of the breadcrumb if ( 'right' == $seplocation ) { // sep on right, so reverse the order $title_array = array_reverse( $title_array ); $title = implode( " $sep ", $title_array ) . $prefix; } else { $title = $prefix . implode( " $sep ", $title_array ); } /** * Filter the text of the page title. * * @since 2.0.0 * * @param string $title Page title. * @param string $sep Title separator. * @param string $seplocation Location of the separator (left or right). */ $title = apply_filters( 'wp_title', $title, $sep, $seplocation ); // Send it out if ( $display ) { echo $title; } else { return $title; } }
Trong hàm bên trên sẽ có 2 bộ lọc chính cho bạn sử dụng đó là: wp_title_parts
và wp_title
. Cách sử dụng cũng tương tự như các ví dụ mình gửi ở đầu bài. Với bộ lọc wp_title_parts
thì giá trị đầu vào và kết quả đầu ra là một mảng, còn bộ lọc wp_title
thì cả đầu vào và đầu tra đều là giá trị kiểu chuỗi.
Khi áp dụng các bộ lọc để thay đổi thẻ tiêu đề của trang WordPress thì bạn sẽ kiểm tra xem phiên bản WordPress đang dùng là bao nhiêu, có hỗ trợ filter bạn định dùng hay không, từ đó mới áp dụng chọn bộ lọc nào cho thích hợp. Chúc bạn thành công.
bài chia sẻ rất hay. cảm ơn bạn
Cảm ơn bạn đã ghé thăm.
thay đổi tiêu đề cũng khá phưc tạp đối với người mới như mình, mình sẽ nghiên cứu thêm nữa rồi sẽ áp dụng xem sao.
đúng cái mình đang cần, thank ad nhé