Mục lục tự động cho các bài đăng trên WordPress

Tạo một tập hợp các liên kết nhảy dạng pop-put dựa trên <h2>các thẻ bài đăng của bạn - một mục lục đáp ứng, được tạo tự động cho các bài đăng WordPress của bạn. Đó là một cách tuyệt vời để nâng cao trải nghiệm người dùng của một trang blog có nhiều tiêu đề phụ (như tiêu đề này)… bởi vì nó tự động thực hiện. Bạn có thể thấy nó hoạt động trên trang web này ngay bây giờ.

Chúng tôi sẽ ẩn nó trên thiết bị di động để không làm lộn xộn màn hình, nhưng trên máy tính xách tay và máy tính để bàn, bạn có thể thấy nó ở góc dưới bên phải.

Chúng tôi đã thiết lập nó để nó hoạt động tốt cùng với hướng dẫn cuộn lên đầu trang của chúng tôi.

Chìa khóa của điều này là chúng tôi không muốn phải quay lại tất cả các bài đăng trên blog của mình và điền thuộc tính “id” của <h2>phần tử vào mỗi bài đăng. Điều đó sẽ mất nhiều thời gian. Vì vậy, chúng tôi sẽ tự động hóa nó.

Trước khi bạn bắt đầu hướng dẫn này, hãy đảm bảo rằng bạn đang sử dụng một chủ đề con tùy chỉnh để bạn có thể chỉnh sửa functions.php.

Nó sẽ hoạt động như thế nào: Logic

Logic cốt lõi cho tiện ích mở rộng này sẽ xảy ra trong trình duyệt, sử dụng JavaScript (jQuery)…
  • Chờ cho đến khi cửa sổ được tải.
  • Quét tất cả các .entry-content h2phần tử có bộ thuộc tính id.
  • Nếu không có phần tử h2 nào…
    • Quét tất cả các phần tử .entry-content h2 có hoặc không có thuộc tính id.
  • Tạo một <div>phần tử vùng chứa kéo ra và đính kèm một tab / nút để chúng ta có thể kéo nó ra và thu gọn nó.
  • Đối với mỗi phần tử tiêu đề phù hợp (nếu có)…
    • Tạo một mục danh sách với một <a>phần tử bên trong có cùng văn bản với phần tử tiêu đề phù hợp. Đây là liên kết nhảy của chúng tôi.
    • Lưu một chốt vào đầu đề phù hợp trong nút bằng cách sử dụng thuộc tính dữ liệu tùy chỉnh ( data-target=...).
    • Thêm mục danh sách mới vào vùng chứa kéo ra.
  • Đính kèm vùng chứa kéo ra <div>vào <body>phần tử chính , đặt cho nó một vị trí CSS là “cố định” và chỉ số z cao (để làm cho nó luôn ở trên cùng).

Bắt đầu với mã giàn giáo

Bắt đầu bằng cách tạo một số tệp trống và đặt một số cấu trúc cơ bản vào đúng vị trí. Trong chủ đề con tùy chỉnh của bạn, hãy tạo một tệp mới có tên wpt-auto-toc.php . Tạo một thư mục có tên “wpt-auto-toc” và tạo hai tệp văn bản trống trong thư mục mới có tên “auto-toc-frontend.css” và “auto-toc-frontend.js”. Cấu trúc thư mục của chủ đề con của bạn sẽ trông giống như sau:
  • chủ đề gốc /
  • chủ đề của bạn /
    • functions.php
    • style.css
    • wpt-auto-toc /
      • auto-toc-frontend.css
      • auto-toc-frontend.js
    • wpt-auto-toc.php
Mở wpt-auto-toc.php và dán thông tin sau vào đó.
/**
 * WP Tutorials Auto Table of Contents
 *
 * https://wp-tutorials.tech/refine-wordpress/auto-toc/
 */
// Block direct access.
if (!defined('WPINC')) {
   exit('Do NOT access this file directly.');
}
// Which post types should have table-of-contents?
const WPTTOC_POST_TYPES = array('post', 'page');
const WPTTOC_SELECTOR_WITH_ANCHORS = '#main .entry-content h2[id]';
const WPTTOC_SELECTOR_ALL_HEADINGS = '#main .entry-content > h2';
const WPTTOC_ANIM_DURATION = 1000; // ms.
function wpttoc_enqueue_scripts() {
   if (!is_single()) {
      // Don't show TOCs on archive/search/taxonomy pages.
   } elseif (empty($post_type = get_post_type())) {
      // Error.
   } elseif (!in_array($post_type, WPTTOC_POST_TYPES)) {
      // Don't show TOCs on post-types that aren't configured
      // in WPTTOC_POST_TYPES.
   } else {
      $base_url = get_stylesheet_directory_uri() . '/' . pathinfo(__FILE__, PATHINFO_FILENAME) . '/';
      $version = wp_get_theme()->get('Version');
      $frontend_args = array(
         'heading' => __('Quick Jump', 'wp-tutorials'),
         'anchorHeadingsSelector' => WPTTOC_SELECTOR_WITH_ANCHORS,
         'allHeadingsSelector' => WPTTOC_SELECTOR_ALL_HEADINGS,
         'scrollAnimDuration' => WPTTOC_ANIM_DURATION,
      );
      wp_enqueue_script('wpt-auto-toc', $base_url . 'auto-toc-frontend.js', null, $version, true);
      wp_localize_script(
         'wpt-auto-toc',
         'autoToc',
         $frontend_args
      );
      wp_enqueue_style('wpt-auto-toc', $base_url . 'auto-toc-frontend.css', null, $version);
   }
}
add_action('wp_enqueue_scripts', 'wpttoc_enqueue_scripts');
Mã phải đủ dễ đọc và hàm thú vị chính là wp_localize_script (). Đây là cách được khuyến nghị để gửi các biến PHP sang JavaScript giao diện người dùng. Trong trường hợp này, chúng tôi yêu cầu WordPress tạo một biến JavaScript có tên autoToc, biến này sẽ là một biểu diễn đối tượng của $frontend_argsmảng.

Phong cách

Mở wpt-auto-toc / auto-toc-frontend.css và dán thông tin sau vào đó để bắt đầu. Rõ ràng là nó được thiết lập cho trang web này, nhưng nó đủ dễ dàng để cấu hình nó cho dự án của bạn.
/**
 * WP Tutorials Auto Table of Contents
 *
 * https://wp-tutorials.tech/refine-wordpress/auto-toc/
 */
.wpttoc-container {
    display: none; /* Hide on mobile */
    position: fixed;
    bottom: 7.5em;
    font-size: 20pt;
    transition: 0.3s;
    z-index: 100;
    right: 0.5em;
    width: 7em;
}
@media(min-width: 920px) {
    .wpttoc-container {
        display: block; /* Show on desktop */
    }
}
.wpttoc-container.hidden {
    transform: translateX(6em);
}
.wpttoc-tab {
    font-size: 14pt;
    position: absolute;
    width: 2em;
    height: 3em;
    left: -2.5em;
    bottom: 0;
    border-radius: 0.25em;
    background-color: #1d2bbe;
    border: 2px solid black;
    cursor: pointer;
    transition: 0.3s;
}
.wpttoc-container .wpttoc-tab .show,
.wpttoc-container .wpttoc-tab .hide {
    display: block;
}
.wpttoc-container.visible .wpttoc-tab .show {
    display: none;
}
.wpttoc-container.hidden .wpttoc-tab .hide {
    display: none;
}
.wpttoc-tab i {
    position: absolute;
    color: white;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
.wpttoc-container h2 {
    font-size: 14pt;
    text-align: center;
    background-color: #ffffff80;
    padding: 0.5em 0;
    border-radius: 0.5em;
}
.wpttoc-container ul {
    font-size: 11pt;
    list-style-type: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5em;
}
.wpttoc-container li a {
    display: block;
    font-weight: bold;
    background-color: #1d2bbe;
    width: 100%;
    padding: 0.5em 1em;
    text-align: center;
    border-radius: 0.5em;
    border: 2px solid black;
    color: white;
}
.wpttoc-tab:hover,
.wpttoc-container li a:hover {
    filter: brightness(130%);
}

Mã JavaScript - Bit lớn

Đây là một vấn đề lớn… Dán phần sau vào wpt-auto-toc / auto-toc-frontend.js và xem qua các nhận xét / phần để xem điều gì đang xảy ra.
/**
* WP Tutorials Auto Table of Contents
* 
* https://wp-tutorials.tech/refine-wordpress/table-of-contents-for-wordpress-posts/
*/
(function($) {
'use strict';
$(window).on('load', function() {
if (typeof autoToc != 'undefined') {
console.log('WPT Auto-TOC : load');
const scrollPercentageThreshold = 0.10;
const scrollPixelThreshold = 300;
autoToc.container = null;
autoToc.list = null;
autoToc.isAutoHideEnabled = true;
var headings = null;
var anchorHeadings = $(autoToc.anchorHeadingsSelector);
if (anchorHeadings.length > 0) {
headings = anchorHeadings;
}
else {
headings = $(autoToc.allHeadingsSelector);
}
/**
* For each of the heading elements we've got, create
* '<li><a>LABEL</a></li>' and add it to a <ul> within our pull-out
* container.
*/
headings.each(function(index, element) {
// If the pullout container doesn't exist, create it now.
if (!autoToc.container) {
autoToc.container = createTocContainer(autoToc.heading);
autoToc.list = $(`<ul></ul>`);
}
var labelText = $(element).text();
var listItem = $('<li></li>');
var button = $(`<a href="javascript:void(0);">${labelText}</a>`);
// Store a handle the the discovered h2 in our button, so we
// can scroll to it in the click handler.
$(button).data('target', element);
button.click(function() {
var heading = $(this).data('target');

autoToc.isAutoHideEnabled = false;
$(‘html, body’).animate({
scrollTop: $(heading).offset().top - $(heading).height()
},
autoToc.scrollAnimDuration
);
});
$(listItem).append(button);
$(autoToc.list).append(listItem);
});
/**

  • If we have created a pull-out container then add it to the body
  • element now, and listen for the window’s scroll event.
    /
    if (autoToc.container) {
    $(autoToc.container).append(autoToc.list);
    $(“body”).append(autoToc.container);
    // Auto-hide the TOC if we scroll down the page without
    // interacting with it. Keep out of the way.
    $(window).on(‘scroll’, function() {
    var offset = $(this).scrollTop();
    var total = document.body.scrollHeight;
    if (!autoToc.isAutoHideEnabled) {
    // Do nothing.
    } else {
    var isPastThreshold = false;
    if ((1.0 * offset / total) > scrollPercentageThreshold) {
    isPastThreshold = true;
    } else if (offset > scrollPixelThreshold) {
    isPastThreshold = true;
    } else {
    // …
    }
    if( isPastThreshold ) {
    hideAutoToc();
    }
    }
    });
    }
    /
    *
  • Create the slide-out container, with a “tab” to toggle its state,
  • and a h2 heading element.
    /
    function createTocContainer(heading) {
    var container = $(&lt;div class="wpttoc-container visible"&gt;&lt;/div&gt;);
    var tab = $(&lt;div class="wpttoc-tab"&gt;&lt;i class="fas fa-chevron-left show"&gt;&lt;/i&gt;&lt;i class="fas fa-chevron-right hide"&gt;&lt;/i&gt;&lt;/div&gt;);
    tab.click(function() {
    toggleAutoToc();
    });
    $(container).append(tab);
    $(container).append(&lt;h2&gt;${heading}&lt;/h2);
    return container;
    }
    /
    *
  • Toggle the pull-out panels’ visibility.
    */
    function toggleAutoToc() {
    if ($(autoToc.container).hasClass(‘hidden’)) {
    showAutoToc();
    } else {
    hideAutoToc();
    }
    }
    function showAutoToc() {
    $(autoToc.container).removeClass(‘hidden’);
    $(autoToc.container).addClass(‘visible’);

autoToc.isAutoHideEnabled = false;
}
function hideAutoToc() {
$(autoToc.container).removeClass(‘visible’);
$(autoToc.container).addClass(‘hidden’);

autoToc.isAutoHideEnabled = false;
}
}
});
})(jQuery);

Phá vỡ nó

Ở gần phía trên cùng, chúng tôi kiểm tra xem nó autoTocđã được chuyển từ back-end sang front-end chưa. Đó là một kiểm tra chỉ trong trường hợp, bởi vì nó phải luôn có mặt.

Sau đó, chúng tôi thiết lập một số hằng số và biến và bắt đầu tìm kiếm các tiêu đề. Đầu tiên, chúng tôi truy vấn tất cả các tiêu đề bằng thuộc tính id. Nếu truy vấn đó không trả về độ dài lớn hơn 0 (tức là không có tiêu đề nào có neo) thì chúng tôi chạy truy vấn thứ hai để kiểm tra tất cả các tiêu đề (có hoặc không có neo).

Sau đó, chúng tôi chỉ lặp qua các tiêu đề phù hợp và trong lần chạy đầu tiên qua vòng lặp, chúng tôi kiểm tra xem chúng tôi có cần tạo vùng chứa kéo ra hay không <div>. Bằng cách này, nếu headings.lengthbằng 0 (vì vậy chúng ta không chạy qua vòng lặp dù chỉ một lần), chúng ta không cần thiết phải tạo vùng chứa kéo ra.

Sau vòng lặp chính, chúng tôi kiểm tra xem chúng tôi đã tạo vùng chứa <div>và lưu trữ nó vào chưa autoToc.container. Nếu vậy, chúng tôi đính kèm nó vào <body>phần tử gốc và thiết lập trình xử lý cuộn để chúng tôi có thể tự động ẩn TOC khi chúng tôi cuộn xuống.

Nó có thể trông giống như một khối mã lớn, nhưng nó được chia thành các phần và chức năng dễ theo dõi.

Kiểm tra & Triển khai

Lưu mọi thứ và tải một số nội dung trên trang web của bạn có nhiều <h2>yếu tố trên đó. Bạn sẽ thấy một mục lục kéo ra mới sáng bóng. Đẹp.

Nếu không có gì xảy ra, hãy mở Công cụ dành cho nhà phát triển của trình duyệt của bạn và kiểm tra Bảng điều khiển JavaScript để tìm thông báo. Ít nhất bạn sẽ thấy kết quả của cuộc gọi đến console.log () của chúng tôi ngay sau khi mã của chúng tôi bắt đầu chạy.

Thực hiện thay đổi

Những thứ chính bạn sẽ muốn tìm hiểu là các bộ chọn phần tử jQuery. Chúng nằm trong wpt-auto-toc.php , được giữ trong WPTTOC_SELECTOR_WITH_ANCHORSWPTTOC_SELECTOR_ALL_HEADINGS. Chúng được thêm vào $frontend_argsvà chuyển vào giao diện người dùng như một phần của autoTocđối tượng.

Các ngưỡng cuộn từ trên xuống để tự động ẩn vùng chứa TOC được giữ ở gần đầu auto-toc-frontend.js nhưng bạn có thể di chuyển ngưỡng này vào wpt-auto-toc.php và chuyển chúng vào giao diện người dùng autoToc, để giữ mọi thứ tốt đẹp và ngăn nắp.

Có các TOC tự động tạo thú vị cho các blog WordPress của bạn!