Cách thêm mục lục (table of content) cho mô tả danh mục sản phẩm
Đa số các plugin toc+ hay table of content đang có đều không hỗ trợ mục lục cho mô tả danh mục sản phẩm nên mình đã tự viết + tham khảo thêm chat GPT, cuối cùng đã viết được mục lục cho mô tả danh mục sản phẩm rồi. AZ9S Chia sẻ cùng các bạn sử dụng luôn nếu cần nhé
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 nhé
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | /* * Thêm mục lục cho mô tả danh mục sản phẩm * Author: az9s.com */ add_action('wp_footer', 'devvn_add_heading_style'); function devvn_add_heading_style(){ ?> <style> .devvn_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; } .devvn_heading_title { padding: 10px 15px; background: #c5c5c5; position: relative; cursor: pointer; } .devvn_heading_wrap > ol { margin: 10px 0 10px 33px; } .devvn_heading_wrap > ol > li { margin: 0; padding: 0; } .devvn_heading_wrap > ol > li ul { margin: 0; padding: 0; } .devvn_heading_wrap > ol > li ul li { margin: 0; padding: 0; list-style: none; } .devvn_heading_wrap > ol { counter-reset: List; } .devvn_heading_wrap > ol > li { counter-increment: List; } .devvn_heading_wrap > ol > li ul { counter-reset: List; } .devvn_heading_wrap > ol > li ul li { counter-increment: List; } .devvn_heading_wrap > ol > li ul li:before { content: counters(List,"."); } .devvn_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; } .devvn_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; } .devvn_heading_wrap.active .devvn_heading_title::after { transform: rotate(180deg); -moz-transform: rotate(180deg); -webkit-transform: rotate(180deg); } </style> <script> (function ($){ $('body').on('click', '.devvn_heading_title', function (){ let thisBox = $(this).closest('.devvn_heading_wrap'); if(thisBox.hasClass('active')){ $('> ol', thisBox).slideUp(); }else{ $('> ol', thisBox).slideDown(); } thisBox.toggleClass('active'); }); $('.devvn_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', 'devvn_auto_add_heading_ids'); function devvn_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="devvn_heading_wrap active"> <div class="devvn_heading_title"> <strong><?php _e('Mục lục', 'devvn');?></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; } } |