wave

Cách tạo mục lục WordPress không dùng plugin

Đối với một blogger chuyên nghiệp, mục lục là một thành phần quan trọng không thể thiếu trong bài viết. Việc tạo mục lục WordPress không chỉ giúp ích trong điều hướng nội dung trên trang mà còn đóng vai trò quan trọng trong SEO.

Tạo mục lục wordpress

Hiện nay có rất nhiều plugin wordpress giúp tạo mục lục tự động cho trang web. Tuy nhiên hầu hết các plugin này thường sử dụng Javascript để tạo mục lục cho bài viết. Việc cài quá nhiều plugin vào trang web có thể làm giảm hiệu năng và tốc độ của trang web và mục lục sẽ không hoạt động khi trình duyệt không hỗ trợ Javascript hoặc Javascript gặp lỗi.

Vậy nên bài viết này sẽ hướng dẫn các bạn tạo mục lục WordPresskhông cần dùng plugin. Tạo mục lục cho bài viết wordpress một cách gọn nhẹ và hoạt động mọi lúc, mọi nơi.

Giới thiệu

Mục lục bài viết (table of content) là gì? Mục lục là một danh sách tổng hợp các chương, đề mục của nội dung, các ý chính của một bài viết kèm với liên kết đến các mục này. Mục lục thường được đặt ở đầu bài viết, tài liệu, hoặc ở những trang cuối. Một số mục lục có các ghi chú, tóm tắt ở sau mỗi tiêu đề. Ở trong ngữ cảnh wordpress, mục lục của một bài viết đơn giản là danh sách liên kết tập hợp các ý chính của bài viết. Mục lục giúp người đọc nhanh chóng nắm bắt bố cục nội dung bài viết.

Mục lục WordPress đóng vai trò quan trọng trong SEO
Mục lục WordPress đóng vai trò quan trọng trong SEO

Tác dụng của mục lục là gì? Mục lục có tác dụng giúp người đọc trang web nhanh chóng nắm bắt bố cục nội dung và di chuyển đến các đề mục một cách nhanh chóng nhờ các liên kết nội bộ.

Tạo mục lục WordPress thủ công

Để tạo mục lục thủ công cho bài viết trong WordPress, chúng ta cần tạo và cập nhật 2 thành phần:

  • Tạo bảng mục lục
  • Cập nhật anchor link trong đề mục

Tạo bảng mục lục wordpress

Mục lục bài viết wordpress
Tạo bảng bảng mục lục cho bài viết WordPress

Bảng mục lục wordpress thực chất là một danh sách các liên kết nội bộ đến đề mục nội dung trong bài viết. Bạn có thể tạo bảng này và đặt ở bất kỳ vị trí nào trong bài viết (thường là ở đầu bài viết).

Trong WordPress, tại phần soạn thảo bài viết, chúng ta tiến hành tạo danh sách, ở nội dung các liên kết ở đây bạn nhập giá trị của anchor link cần dùng. Ví dụ với nội dung thuộc tính idtao-muc-luc-thu-cong thì nội dung liên kết sẽ là #tao-muc-luc-thu-cong. Ở đây chúng ta thêm dấu # vào trước để kích hoạt tính năng anchor link.

<h2 id="tao-muc-luc-thu-cong">Tạo mục lục wordpress thủ công - Vietrick</h2>
Tạo mục lục WordPress thủ công
Tạo bảng mục lục cho bài viết trong WordPress

Với mỗi thẻ đề mục (heading) sẽ có thuộc tính id tương ứng, được hướng dẫn cập nhật ở phần dưới.

Việc cập nhật anchor link cho các đề mục ở đây chính là thiết lập thuộc tính id cho các thẻ tiêu đề (heading) trong bài viết.

Ví dụ về một thẻ tiêu đề có sử dụng anchor:

<h2 id="tao-muc-luc-thu-cong">Tạo mục lục wordpress thủ công</h2>

Các bạn lưu ý là nội dung thuộc tính id được viết liền, phân cách có thể sử dụng - hoặc _, Tiếng Việt không dấu thì tốt cho SEO.

Để cập nhật anchor link trong WordPress, tại phần biên soạn bài viết, các bạn chọn thẻ heading cần sửa.

Tại cột Block bên tay phải, click menu Nâng cao > Điểm neo HTML. Sau đó nhập nội dung mong muốn. Thực hiện tương tự với các heading còn lại.

Cập nhật anchor link cho thẻ heading
Cập nhật anchor link cho thẻ heading

Sau khi cập nhật hoàn tất và xuất bản bài viết. Khi click vào thẻ tiêu đề ở bảng mục lục, trang web sẽ di chuyển đến phần nội dung đề mục tương ứng là thành công.

Tạo mục lục WordPress tự động

Với việc tạo mục lục thủ công tuy độ tùy biến cao, nhưng lại khá tốn thời gian biên soạn nội dung bài viết. Do đó Vietrick chia sẻ thêm đến các bạn cách tạo mục lục WordPress tự động không sử dụng plugin.

Ở phần này, đòi hỏi chúng ta cần chỉnh sửa theme một chút để chèn đoạn mã tạo mục lục WordPress tự động vào tệp functions.php:

  • Tạo và chèn bảng mục lục tự động
  • Tạo anchor link tự động cho heading
  • Trang trí cho bảng mục lục

Trong tệp functions.php, các bạn chèn thêm dòng sau vào dưới cùng:

include_once 'toc-func.php';

Sau đó bạn tạo thêm 1 tệp toc-func.php tại cùng thư mục giao diện đang sử dụng. Với việc tách riêng đoạn mã ra 1 tệp, chúng ta có thể dễ dàng tái sử dụng khi đổi template sau này.

Tạo và chèn bảng mục lục tự động

Trong tệp toc-func.php vừa tạo, các bạn chèn đoạn mã sau:

<?php
/**
*
* Vietrick Custom Functions
*
* @package Vietrick
*/
/**
* Vietrick custom TOC
*/
add_filter( 'the_content', function( $content ) {
// Adding ID slug for heading
$content = preg_replace_callback( '/(\<h[1-6](.*?))\>(.*)(<\/h[1-6]>)/i', function( $matches ) {
if ( ! stripos( $matches[0], 'id=' ) ) :
$matches[0] = $matches[1] . $matches[2] . ' id="' . sanitize_title( $matches[3] ) . '">' . $matches[3] . $matches[4];
endif;
return $matches[0];
}, $content );
//main TOC
$toc_title = "Xem nhanh";
$toc_content = "";
preg_match_all('/<(h[1-3])(?:.* id="(.*?)")?>((.*?))<\/h/',$content,$matches);
$levels = $matches[1];
$anchors = $matches[2];
$headings = $matches[3];
if ( $headings ) {
$toc_content = '<nav class="vietrick-auto-toc">';
$toc_content .= '<h3 class="toc-title">'.$toc_title.'</h3>';
if (!function_exists('collate_row')) {
function collate_row($depth, $anchor, $heading) {
$level = substr($depth, 1);
$heading = strip_tags($heading);
if ( $anchor ) {
return ["<a href='#{$anchor}' class='heading-{$depth} toc-link smooth-scroll'>{$heading}</a>", $level];
} else {
$slug = sanitize_title($heading);
return ["<a href='#{$slug}' class='heading-{$depth} toc-link smooth-scroll'>{$heading}</a>", $level];
}
}
}
$collated = array_map('collate_row', $levels, $anchors, $headings );
$previous_level = 2;
$toc_content .= '<ul class="toc-list">';
foreach ($collated as $row) {
$current_level = $row[1];
if ( $current_level == $previous_level ) {
$toc_content .= '<li>' . $row[0];
} else if ( $current_level < $previous_level ) {
$toc_content .= str_repeat('</ul>', $previous_level – $current_level) . '<li>'. $row[0];
} else {
$toc_content .= '<ul><li>' . $row[0];
}
$previous_level = $row[1];
}
$toc_content .= str_repeat('</ul>', $previous_level) . '</li></ul>';
$toc_content .= '</nav>';
}
//Add Toc before first heading
if (preg_match('/(\<h[1-6](.*?))\>(.*)(<\/h[1-6]>)/i',$content)){
$content = preg_replace('/(\<h[1-6](.*?))\>(.*)(<\/h[1-6]>)/i',$toc_content.'${0}',$content,1);
}else{
$content = $toc_content.$content;
}
return $content;
}, 0);
view raw toc-func.php hosted with ❤ by GitHub

Cảm ơn Jeroen Sormani đã cung cấp 1 đoạn mã convert heading sang slug dùng tại thuộc tính id.

Để tùy biến tiêu đề bảng mục lục, các bạn tìm và sửa dòng code sau:

    $toc_title = "Xem nhanh";

Ở đoạn mã trên, mặc định các thẻ heading h1,h2,h3 trong bài viết sẽ được chèn vào bảng mục lục. Nếu các bạn muốn sử dụng nhiều thẻ hơn thì tìm và chỉnh sửa đoạn mã sau:

preg_match_all('/<(h[1-3])(?: id="(.*?)")?>((.*?))<\/h/',$content,$matches);

Ở đoạn trên, bạn thay h[1-3] bằng số loại thẻ heading muốn sử dụng, ví dụ áp dụng TOC với heading h1->h5: h[1-5].

Mặc định, đoạn code sẽ chèn bảng mục lục vào đầu nội dung bài viết. Tuy nhiên nếu bạn muốn bảng mục lục được chèn vào trước thẻ heading đầu tiên thì sử đụng đoạn mã sau:

<?php
/**
*
* Vietrick Custom Functions
*
* @package Vietrick
*/
/**
* Vietrick custom TOC
*/
add_filter( 'the_content', function( $content ) {
// Adding ID slug for heading
$content = preg_replace_callback( '/(\<h[1-6](.*?))\>(.*)(<\/h[1-6]>)/i', function( $matches ) {
if ( ! stripos( $matches[0], 'id=' ) ) :
$matches[0] = $matches[1] . $matches[2] . ' id="' . sanitize_title( $matches[3] ) . '">' . $matches[3] . $matches[4];
endif;
return $matches[0];
}, $content );
//main TOC
$toc_title = "Xem nhanh";
$toc_content = "";
preg_match_all('/<(h[1-3])(?:.* id="(.*?)")?>((.*?))<\/h/',$content,$matches);
$levels = $matches[1];
$anchors = $matches[2];
$headings = $matches[3];
if ( $headings ) {
$toc_content = '<nav class="vietrick-auto-toc">';
$toc_content .= '<h3 class="toc-title">'.$toc_title.'</h3>';
if (!function_exists('collate_row')) {
function collate_row($depth, $anchor, $heading) {
$level = substr($depth, 1);
$heading = strip_tags($heading);
if ( $anchor ) {
return ["<a href='#{$anchor}' class='heading-{$depth} toc-link smooth-scroll'>{$heading}</a>", $level];
} else {
$slug = sanitize_title($heading);
return ["<a href='#{$slug}' class='heading-{$depth} toc-link smooth-scroll'>{$heading}</a>", $level];
}
}
}
$collated = array_map('collate_row', $levels, $anchors, $headings );
$previous_level = 2;
$toc_content .= '<ul class="toc-list">';
foreach ($collated as $row) {
$current_level = $row[1];
if ( $current_level == $previous_level ) {
$toc_content .= '<li>' . $row[0];
} else if ( $current_level < $previous_level ) {
$toc_content .= str_repeat('</ul>', $previous_level – $current_level) . '<li>'. $row[0];
} else {
$toc_content .= '<ul><li>' . $row[0];
}
$previous_level = $row[1];
}
$toc_content .= str_repeat('</ul>', $previous_level) . '</li></ul>';
$toc_content .= '</nav>';
}
//Add Toc before first heading
if (preg_match('/(\<h[1-6](.*?))\>(.*)(<\/h[1-6]>)/i',$content)){
$content = preg_replace('/(\<h[1-6](.*?))\>(.*)(<\/h[1-6]>)/i',$toc_content.'${0}',$content,1);
}else{
$content = $toc_content.$content;
}
return $content;
}, 0);
view raw toc-func.php hosted with ❤ by GitHub

Sau khi chỉnh sửa, các bạn lưu và kiểm tra lại bài viết. Lúc này đầu bài viết sẽ tự động được chèn thêm mục lục như ví dụ sau:

<h3 class="toc-title">Xem nhanh</h3>
<ul class="toc-list">
<li><a href="#giới-thiệu" class="heading-h2 toc-link smooth-scroll">Giới thiệu</a></li>
<li><a href="#tạo-mục-lục-wordpress-thủ-cong" class="heading-h2 toc-link smooth-scroll">Tạo mục lục WordPress thủ công</a>
<ul>
<li><a href="#tạo-bảng-mục-lục-wordpress" class="heading-h3 toc-link smooth-scroll">Tạo bảng mục lục wordpress</a></li>
<li><a href="#cap-nhat-anchor-link" class="heading-h3 toc-link smooth-scroll">Cập nhật anchor link</a></li>
</ul>
</li>
<li><a href="#tạo-mục-lục-wordpress-tự-dộng" class="heading-h2 toc-link smooth-scroll">Tạo mục lục WordPress tự động</a>
<ul>
<li><a href="#tạo-va-chen-bảng-mục-lục-tự-dộng" class="heading-h3 toc-link smooth-scroll">Tạo và chèn bảng mục lục tự động</a></li>
<li><a href="#trang-tri-css" class="heading-h3 toc-link smooth-scroll">Trang trí CSS</a></li>
</ul>
</li>
<li><a href="#kết-luận" class="heading-h2 toc-link smooth-scroll">Kết luận</a></li>
</ul>
</nav>

Đến đây thì cơ bản là tính năng mục lục đã hoàn thành. Phần tiếp theo chúng ta sẽ trang trí thêm 1 chút mã CSS để làm đẹp cho bảng mục lục.

Trang trí CSS

Để trang trí cho mục lục vừa tạo ở trên, các bạn hãy thêm đoạn mã CSS vào tệp style.css trong theme đang sử dụng hoặc phần additional CSS.

.vietrick-auto-toc{
padding:2rem 2rem 0.5rem 3rem;
margin-bottom:2rem;
background:#f5f7fa;
border-radius: 16px;
max-height:440px;
overflow:auto;
}
.vietrick-auto-toc .toc-list {
margin-left: 1.1rem;
}
.vietrick-auto-toc .toc-title{
font-size:24px;
font-weight:700;
margin: 0 0 1rem;
}
.toc-list li:not(:last-child) {
padding-bottom: 0.5rem;
}
.entry-content li::marker{color: #f56f46;}
.vietrick-auto-toc a{
font-size:16px;
font-weight: 500;
}

Các bạn có thể tùy biến lại CSS cho phù hợp với template của mình nhé.

Kết luận

Việc tạo mục lục bài viết theo cách thủ công thường rất tốn thời gian và công sức. Tuy nhiên với cách tạo thủ công, ta có thể đặt bảng mục lục tại bất cứ vị trí nào trong bài viết, thậm chí là thiết lập nhiều bảng mục lục cho từng thẻ heading trong bài viết.

Khi tạo mục lục WordPress tự động với vài dòng code đơn giản, trang web của bạn luôn hỗ trợ đầy đủ mục lục và hoạt động ổn định dù có hay không Javascript. Dù thực hiện theo cách thủ công hay tự động thì việc tạo mục lục WordPress không sử dụng plugin này sẽ không ảnh hưởng đến hiệu năng và tốc độ trang web của bạn, đặc biệt là khi kết hợp với kỹ thuật caching.

5/5 - (2 votes)
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
Xem tất cả bình luận