Cách thêm mục lục cho mô tả danh mục sản phẩm

Admin Blog 01/11/23

Đến thời điểm hiện tại vẫn chưa có Plugin nào tạo mục lục cho mô tả danh mục. Trong các plugin mục lục như: Table of content, Toc+ cũng chỉ mới hỗ trợ mục lục cho bài viết, trang và mô tả sản phẩm. Vậy mình viết bài này chia sẻ với bạn về cách thêm mục lục cho mô tả danh mục sản phẩm.

Cách thêm mục lục cho mô tả danh mục sản phẩm

Các bạn chỉ cần copy đoạn code sau vào functions.php của theme đang sử dụng (wp-content/themes/{your-theme}/functions.php) là được. Áp dụng cho mô tả danh mục sản phẩm với mọi theme có sử dụng Woocommerce

add_action('wp_footer', 'woo_add_heading_style');
function woo_add_heading_style(){
    ?>
    <style>
        .woo_heading_wrap {
            background: rgba(243,243,243,0.95);
            border: 1px solid rgb(197 197 197);
            width: 100%;
            color: #333;
            margin: 0 0 20px 0;
            padding: 0;
        }
        .woo_heading_title {
            padding: 10px 15px;
            background: #c5c5c5;
            position: relative;
            cursor: pointer;
        }
        .woo_heading_wrap > ol {
            margin: 10px 0 10px 33px;
        }
        .woo_heading_wrap > ol > li {
            margin: 0;
            padding: 0;
        }
        .woo_heading_wrap > ol > li ul {
            margin: 0;
            padding: 0;
        }
        .woo_heading_wrap > ol > li ul li {
            margin: 0;
            padding: 0;
            list-style: none;
        }
        .woo_heading_wrap > ol {
            counter-reset: List;
        }
        .woo_heading_wrap > ol > li {
            counter-increment: List;
        }
        .woo_heading_wrap > ol > li ul {
            counter-reset: List;
        }
        .woo_heading_wrap > ol > li ul li {
            counter-increment: List;
        }
        .woo_heading_wrap > ol > li ul li:before {
            content: counters(List,".");
        }
        .woo_heading_title strong {
            background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgEAQAAACJ4248AAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAACYktHRAAAqo0jMgAAAAlwSFlzAAAAYAAAAGAA8GtCzwAAAAd0SU1FB+cJBA8RMDu7ID0AAAKXSURBVFjD7ZVNSBtBGIa/mV1Nfw6BtgoVidp6KPbSZj20CppCL6WHeqhgTDZGCIJSUGOQlGiagElIicHUQ+qaQGx0D+mp0EOhPyAoQssuCqXXUkIoVKWtFamszfQQTKKbg4fJyTynmXkG3vmGbxiACqcd1PxMo9EmfD4Y6+kBRlGIThDktmAQIJsFAGhJVVef/eHxkOs8jxz19VRS7ZkM3BfF3y8mJ5H+y/Q04u32Yk+CIyPy3UgEAED/aGoKrblcZSnfEgphaO7tVV3LX7M5P+lSe1qQQbMZw+rBgcowipI/zM8SntoJFAUjQzyuuoFALJaf7Kk9NTZiMdTdzTBf342NEavJRAz7+8grCJIcjwMQktuFcWvd8HBWsFjQdkMDleD1dJp8W1y8yoTDZSuuwklBnL6qCgYmJuCi0QiMohBhfl5+E4kc9kAnYdnduNNJdDyPvtfUUEk9t7UFD0UROJ8PcVwgAOB0Ht0xNCRJ0SgAgP6j240Gvd6ylL/q92OAvr7j6+SD1Zqf7BSNadPe34/h9uFzK4DuFNbQeO5PKAv2bBbDtYUFlXiSSBROU8JTgqwlErkmlFwu8tZohH+KglyCIMmzs8VN+IcfHwfBYkEva2upBF/e3ISUKCLZ7y9XcRVODOokLLvb6nBAh9EIWFFIx9yc/CAWK/6MOG50FNw8D790Oiqp6+k03BDFK69DIcQ993ph3u0+smHKZpPu5b5hjnM6AQKBclRPbno8GD7bbCrzvmiNlPC0MNlsmIQxVgkDy+bzn5bwtGhnWYxuLS2phDuZzI8vlPCUQHvJJHP+8fLymbBGA5caG0nX9jZqCQal6MzMYRPWfVpZIW0YQ6qpCcW1WirJ9kyGDESjO6+O9V6FU8l/eGH2Ze896egAAAAASUVORK5CYII=) no-repeat left center;
            background-size: 22px 22px !important;
            padding-left: 32px;
            text-transform: uppercase;
        }
        .woo_heading_title::after {
            background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgEAQAAACJ4248AAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAACYktHRAAAqo0jMgAAAAlwSFlzAAAAYAAAAGAA8GtCzwAAAAd0SU1FB+cJBA8REu7bYdkAAAHLSURBVFjD7ZS9S8NAGId/l0a0QaiuDl3cXIScg2CrRQhSuruKf4GggthSN1P6KYKTi7vtVmIpQehgFzHFycmPQfBjakGpIsI5SEtr05qmaQXJD27J+949T94jAezYsQNggfE8FV2uQfGm2djYAuN5AOBoRZJeis/PIJWK+JBOUyoI/QJTKgjiYSbDz5TLL59PT7QiSYSK19cgk5O1JqYWCkQKBDStWrUazlRFIZLPV3/Ibm44oHn0RPL5mKooVk5CFw4AcLk4cheP/9xgpUR7OIC1RIK7KMdiKMqyngSQz08dj472AoeUzerB2dLenrYSjZJ68/vuLuaCwdZjzs7etvz+q+XXVzNwqIuLevCSvL4OAKRpk0USRuEtAlZIdAPXFehFolt4WwEzEmbgAMC1E9BGQiGsRiKtFY/HGc3lGr8Os3AAcKBDHk9OTydCw8O49HqbK273UHF+fnw/nXbf8rxZeMcraBqvmEiAbGy0ANRCAaj9M34Wk0mttLn529mGBACAHsgyjra3jfQaefNaHEaagE7XYR7elYARiW7hpkMPZJlSxhqXGEyl+g5ujHi+s0Ppx8f3CocHCq9PggrC7L3T+SdwO3b+Tb4AHn8FI1FdY6oAAAAASUVORK5CYII=) no-repeat center center;
            width: 12px;
            height: 12px;
            background-size: 100% 100%;
            right: 15px;
            top: 50%;
            margin-top: -6px;
            content: "";
            position: absolute;
            transition: all .3s linear;
            -moz-transition: all .3s linear;
            -webkit-transition: all .3s linear;
        }
        .woo_heading_wrap.active .woo_heading_title::after {
            transform: rotate(180deg);
            -moz-transform: rotate(180deg);
            -webkit-transform: rotate(180deg);
        }
    </style>
    <script>
        (function ($){
            $('body').on('click', '.woo_heading_title', function (){
                let thisBox = $(this).closest('.woo_heading_wrap');
                if(thisBox.hasClass('active')){
                    $('> ol', thisBox).slideUp();
                }else{
                    $('> ol', thisBox).slideDown();
                }
                thisBox.toggleClass('active');
            });
            $('.woo_heading_wrap a').on('click', function (){
                let idElement = $(this).attr("href");
                let top = $(idElement).offset().top;
                $('html, body').animate({scrollTop:top-44}, 500 );
                return false;
            })
        })(jQuery);
    </script>
    <?php
}
add_filter('woocommerce_taxonomy_archive_description_raw', 'woo_auto_add_heading_ids');
function woo_auto_add_heading_ids($content) {
    $content = wp_kses_post( $content );
    $dom = new DOMDocument();
    if(!$content) return $content;
    $dom->loadHTML(mb_convert_encoding( $content, 'HTML-ENTITIES', 'UTF-8'));
    $xpath = new DOMXPath($dom);
    $headings = $xpath->query('//h2|//h3');
    $table_content = array();
    $h2 = 0;
    foreach ($headings as $index => $heading) {
        $headingText = $heading->textContent;
        $id = sanitize_title($headingText);
        $id = ensure_unique_id($id, $xpath, $index);
        $heading->setAttribute('id', $id);
        if($heading->tagName == 'h2') {
            $h2++;
            $table_content[$h2] = array(
                'title' => $headingText,
                'href' => '#'.$id,
            );
        }elseif($heading->tagName == 'h3') {
            $table_content[$h2]['child'][] = array(
                'title' => $headingText,
                'href' => '#'.$id,
            );
        }
    }
    $newContent = $dom->saveHTML();
    $table_content_out = '';
    if($table_content){
        ob_start();
        ?>
        <div class="woo_heading_wrap active">
            <div class="woo_heading_title">
                <strong><?php _e('Mục lục', 'woo');?></strong>
            </div>
            <ol>
                <?php foreach ($table_content as $item):?>
                    <?php
                        $title = isset($item['title']) ? sanitize_text_field($item['title']) : '';
                        $href = isset($item['href']) ? esc_attr($item['href']) : '';
                        $child = isset($item['child']) ? (array) $item['child'] : array();
                        if(!$title) continue;
                    ?>
                    <li><a href="<?php echo $href;?>" title="<?php echo $title;?>"><?php echo $title;?></a><?php if($child){?><ul><?php foreach ($child as $child_item):?>
                            <?php
                            $child_title = isset($child_item['title']) ? sanitize_text_field($child_item['title']) : '';
                            $child_href = isset($child_item['href']) ? esc_attr($child_item['href']) : '';
                            if(!$child_title) continue;
                            ?>
                            <li>
                                <a href="<?php echo $child_href;?>" title="<?php echo $child_title;?>"><?php echo $child_title;?></a>
                            </li>
                        <?php endforeach;?></ul><?php }?></li>
                <?php endforeach;?>
            </ol>
        </div>
        <?php
        $table_content_out = ob_get_clean();
    }
    return $table_content_out . $newContent;
}
if(!function_exists('ensure_unique_id')) {
    function ensure_unique_id($id, $xpath, $index)
    {
        $existingIds = [];
        $existingHeadings = $xpath->query('//h2[@id] | //h3[@id]');
        foreach ($existingHeadings as $existingHeading) {
            $existingId = $existingHeading->getAttribute('id');
            $existingIds[] = $existingId;
        }
        if (in_array($id, $existingIds)) {
            $i = 1;
            $newId = $id . '-' . $i;
            while (in_array($newId, $existingIds)) {
                $i++;
                $newId = $id . '-' . $i;
            }
            return $newId;
        }
        return $id;
    }
}

Hiện tại code trên hỗ trợ cho thẻ H2 và H3, mình sẽ update thêm các thể h4 và h5. Các bạn có thể tùy chỉnh lại css cho đẹp theo ý các bạn nhé.

Xem thêm: Hướng dẫn thu gọn nội dung chi tiết sản phẩm và mô tả danh mục

0 0 đánh giá
Đánh giá bài viết
Theo dõi
Thông báo của
guest
0 Góp ý
Cũ nhất
Mới nhất Được bỏ phiếu nhiều nhất
Phản hồi nội tuyến
Xem tất cả bình luận