{"id":6440,"date":"2020-10-30T20:09:14","date_gmt":"2020-10-30T20:09:14","guid":{"rendered":"https:\/\/www.terluinwebdesign.nl\/fr\/?p=6440"},"modified":"2025-07-18T14:56:24","modified_gmt":"2025-07-18T14:56:24","slug":"html-table-of-contents-generator-php-powered","status":"publish","type":"post","link":"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/","title":{"rendered":"HTML table of contents generator, PHP-powered"},"content":{"rendered":"<pre><prevent-autop><div class=\"row all d__content-in-narrow-container t__content-in-container m__content-in-container\" data-cache-vw-d=\"1512\" data-cache-h-d=\"3536.4296875\" data-cache-vw-t=\"617\" data-cache-h-t=\"3024.46875\" data-cache-vw-m=\"462\" data-cache-h-m=\"5820.109375\"><div class=\"col all\"><p>An HTML table of contents generator is often based on JavaScript. There are PHP-powered HTML table of contents generators. Those often use regex to seek for headings.<\/p><p>I have a different HTML table of contents generator for you, which does not rely on regex.<\/p><p>Instead, it relies on <a href=\"https:\/\/www.php.net\/manual\/en\/class.domdocument.php\" target=\"_blank\" rel=\"noopener noreferrer\">PHP's built-in HTML parser<\/a>. This generator does not require you to manually add an ID to every single heading, as well. It automatically inserts an ID, if no ID is specified, based on the contents of the heading and the parent-headings (hierarchical).<\/p><p>Sounds great? I'll tell you how to implement this HTML table of contents generator.<\/p><aside class=\"row all bg-yellow__light v-center h-center c half-row-gap d__pad-top-s t__pad-top-m m__pad-top-m d__pad-bottom-s t__pad-bottom-m m__pad-bottom-m d__in-narrow-container wrap t__vertical m__vertical t__in-container m__in-container\" data-cache-vw-d=\"1512\" data-cache-h-d=\"80.203125\" data-cache-vw-t=\"617\" data-cache-h-t=\"116.9375\" data-cache-vw-m=\"462\" data-cache-h-m=\"247.125\"><div class=\"col all d__mar-right-0 d__mar-bottom-0 t__mar-bottom-s m__mar-bottom-s\"><p class=\"wrap-balance anim-fade-in\"><b class=\"h6-size\">Professional AI-built website, no setup costs, for only \u20ac49\/month<\/b><\/p><\/div><div class=\"col all mar-bottom-0 w-auto\"><a class=\"button anim-fade-in bor-pitch-black__light txt-pitch-black-hover__light bg-transparent-hover__light bor-pitch-black-hover__light bg-pitch-black__light txt-yellow__light bg-pitch-black__dark txt-yellow__dark bor-pitch-black__dark bg-transparent-hover__dark txt-pitch-black-hover__dark bor-pitch-black-hover__dark d__h6-size t__h6-size w-auto pad-left-s pad-right-s pad-bottom-xs pad-top-xs\" href=\"https:\/\/www.terluinwebdesign.nl\/en\/ai-website-builder\/\"><span>AI Site Builder<\/span><\/a><\/div><\/aside><h2>Solution for automatic table of contents<\/h2><p>Before you can copy-paste my PHP-code and use it, my solution needs to know what content you want to present to the visitor of your webpage; HTML-content.<\/p><p>In order to start collecting the HTML, you have to add <code>ob_start();<\/code> at the beginning of the PHP-code that is executed when a visitor loads your page. If you've figured that out, you should add <code>$html = ob_get_clean();<\/code> at the end of the PHP-code that is executed when a visitor loads your page. Now, this <code>$html<\/code> variable holds the content that we need to be able to generate a table of contents. The following code will generate a table of contents:<\/p><tw-pre><code class=\"php-code\">$doc = new DOMDocument();\r\n$doc -&gt; loadHTML($html);\r\n$xPath = new DOMXPath($doc);\r\n\r\nfunction getHeadingDepth(DOMElement $heading) {\r\n  return intval(substr($heading -&gt; tagName, 1));\r\n}\r\nfunction idEncode($str) {\r\n  return preg_replace('\/s\/', '-', htmlspecialchars(strtolower($str)));\r\n}\r\n\r\n$tableOfContents = $doc -&gt; createElement('ol');\r\n$tableOfContents -&gt; setAttribute('class', 'table-of-contents auto-toc');\r\n\r\n$currentOL = $tableOfContents;\r\n$previousOLs = [];\r\n\r\n$previousHeading = false;\r\n$allHeadings = $xPath -&gt; query('\/\/main\/\/h2 | \/\/main\/\/h3 | \/\/main\/\/h4 | \/\/main\/\/h5 | \/\/main\/\/h6');\r\n$iHeading = 0;                  <mark>\/\/ ^^ change <i>main<\/i> to whatever you use to indicate the main content of a page (excluding the header and footer, or any repeating blocks). Read about <a href=\"https:\/\/www.w3schools.com\/xml\/xpath_syntax.asp\" target=\"_blank\" rel=\"noopener noreferrer\">xPath<\/a> if you would like to target specific class names or IDs.<\/mark>\r\n\r\n$previousLI = false;\r\n\r\n$generatedIDs = [];\r\n\r\nforeach($allHeadings as $heading) {\r\n  $iHeading++;\r\n  $headingDepth = getHeadingDepth($heading);\r\n  \r\n  if($previousHeading) {\r\n    $previousHeadingDepth = getHeadingDepth($previousHeading);\r\n  } else {\r\n    $previousHeadingDepth = 2;\r\n  }\r\n  \r\n  if($headingDepth &gt; $previousHeadingDepth) {\r\n    \/* If heading is deeper than previous heading, then remember previous OL and\r\n     * create new OL, set it as current OL and append the OL to the previous OL\r\n     *\/\r\n    \r\n    $previousOLs[$previousHeadingDepth] = $currentOL;\r\n    $currentOL = $doc -&gt; createElement('ol');\r\n    if($previousLI) {\r\n        $previousLI -&gt; appendChild($currentOL);\r\n    } else {\r\n        $previousOLs[$previousHeadingDepth] -&gt; appendChild($currentOL);\r\n    }\r\n  } elseif($headingDepth &lt; $previousHeadingDepth) {\r\n    \/* If heading is less deep than previous heading, then set the\r\n     * current OL as the previous OL corresponding to the current depth\r\n     *\/\r\n    \r\n    $currentOL = $previousOLs[$headingDepth];\r\n  }\r\n  \r\n  \/\/ Finally, append a new LI to the current OL.\r\n  $currentLI = $doc -&gt; createElement('li');\r\n  $currentAnchorLink = $doc -&gt; createElement('a');\r\n  $currentAnchorLink -&gt; textContent = $heading -&gt; textContent;\r\n  \r\n  if($heading -&gt; hasAttribute('id')) {\r\n    $currentAnchorLink -&gt; setAttribute('href', '#' . $heading -&gt; getAttribute('id'));\r\n  } else {\r\n    $headingTraceback = [];\r\n    $olInTrace = $currentOL; \r\n    while($olInTrace !== $tableOfContents &amp;&amp; $olInTrace -&gt; tagName == 'ol') {\r\n      array_push (\r\n        $headingTraceback,\r\n        idEncode($olInTrace -&gt; previousSibling -&gt; textContent)\r\n      );\r\n      $olInTrace = $olInTrace -&gt; parentNode;\r\n    }\r\n    $newHeadingID = implode('-', array_reverse($headingTraceback)) . '-' . idEncode($heading -&gt; textContent);\r\n    \r\n    $heading -&gt; setAttribute('id', $newHeadingID);\r\n    $heading -&gt; setAttribute('data-auto-toc-id', $newHeadingID);\r\n    \r\n    $currentAnchorLink -&gt; setAttribute('href', '#' . $newHeadingID);\r\n    \r\n    array_push (\r\n      $generatedIDs,\r\n      $newHeadingID\r\n    );\r\n  }\r\n  \r\n  $currentLI -&gt; appendChild($currentAnchorLink);\r\n  $currentOL -&gt; appendChild($currentLI);\r\n  \r\n  \/\/ Set previous &lt;li&gt;\r\n  $previousLI = $currentLI;\r\n\r\n  \/\/ Set previous heading\r\n  $previousHeading = $heading;\r\n  \r\n  \/\/ Set previous heading depth\r\n  $previousHeadingDepth = $headingDepth;\r\n  \r\n}\r\n\r\n$allAutomaticTablesOfContents = $doc -&gt; getElementsByTagName('auto-toc');\r\nforeach($allAutomaticTablesOfContents as $automaticTableOfContents) {\r\n  $tableOfContentsToUse = $tableOfContents -&gt; cloneNode(true);\r\n  if($automaticTableOfContents -&gt; hasAttribute('class')) {\r\n    $tableOfContentsToUse -&gt; setAttribute (\r\n      'class',\r\n      $tableOfContentsToUse -&gt; getAttribute('class') . ' ' . $automaticTableOfContents -&gt; getAttribute('class')\r\n    );\r\n  }\r\n  \r\n  $automaticTableOfContents -&gt; parentNode -&gt; replaceChild (\r\n    $tableOfContentsToUse,\r\n    $automaticTableOfContents\r\n  );\r\n}\r\n\r\n$html = '&lt;!DOCTYPE html&gt;' . $doc -&gt; saveHTML($doc -&gt; documentElement); \/\/ echo the final HTML\r\n$html = preg_replace('\/&lt;\/wbr&gt;\/is', '', $html);\r\n$html = preg_replace('\/&lt;\/source&gt;\/is', '', $html);\r\necho $html;\r\n<\/code><\/tw-pre><h2>How to place an automatic ToC?<\/h2><p>Simply add <code>&lt;auto-toc&gt;&lt;\/auto-toc&gt;<\/code> and that will get replaced by the table of contents. You can add classes to this element as well, the generator will simply merge the existing classes with the classes that indicate that it is an automatic table of contents.<\/p><tw-pre><code class=\"html-code\">&lt;auto-toc class=\"some-custom-class\"&gt;&lt;\/auto-toc&gt;<\/code><\/tw-pre><hr><p><b>I hope this solution helped you and that you never have to adjust your table of contents everytime you've added or changed headings. This solution has been tested and is actually used in a documentation for the page builder I've made for this website. That table of contents links to 189 anchors which nest all the way down to <code>&lt;h5&gt;<\/code>-headings.<\/b><\/p><p>Are you looking for more flexibility in your web design? Take a look at a few posts I wrote with&nbsp;<a href=\"https:\/\/www.terluinwebdesign.nl\/en\/css\/\" title=\"CSS solutions\">CSS solutions<\/a> I provide you to bring more flexibility into your responsive web design.<\/p><\/div><\/div><aside class=\"row all t__content-in-container m__content-in-container d__in-container v-center bg-yellow__light m__vertical color-scheme-light__dark bg-yellow__dark t__vertical t__h-center t__c m__c\" data-cache-vw-d=\"1512\" data-cache-h-d=\"318.53125\" data-cache-vw-t=\"617\" data-cache-h-t=\"836.5546875\" data-cache-vw-m=\"462\" data-cache-h-m=\"870.9609375\"><div class=\"col all w-1\/d\/3 w-10\/t\/13\"><h2 class=\"t__h1 wrap-balance anim-fade-in\">Professional AI-built website, no setup costs, for only \u20ac49\/month<\/h2><a class=\"button bor-pitch-black__light txt-pitch-black-hover__light bg-transparent-hover__light bor-pitch-black-hover__light bg-pitch-black__light txt-yellow__light bg-pitch-black__dark txt-yellow__dark bor-pitch-black__dark bg-transparent-hover__dark txt-pitch-black-hover__dark bor-pitch-black-hover__dark d__h6-size t__h6-size\" href=\"https:\/\/www.terluinwebdesign.nl\/en\/ai-website-builder\/\"><span>AI Site Builder<\/span><\/a><\/div><div class=\"col all\"><div class=\"row all m__vertical t__vertical\"><div class=\"col all\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.terluinwebdesign.nl\/wp-content\/uploads\/2025\/07\/website-builder-ai-bizbuilder-homepage.png\" class=\"anim-fade-in\" data-src-light=\"\" data-src-dark=\"\" title=\"\" alt=\"\" width=\"3020\" height=\"1645\" srcset=\"https:\/\/www.terluinwebdesign.nl\/wp-content\/plugins\/tw-builder\/access\/img\/tmp\/2025\/07\/website-builder-ai-bizbuilder-homepage-w512.png.webp\" data-img-vw-d=\"1512\" data-img-w-d=\"356.2890625\" data-img-h-d=\"193.453125\" data-img-of-d=\"fill\" data-img-vw-t=\"617\" data-img-w-t=\"502.421875\" data-img-h-t=\"272.796875\" data-img-of-t=\"fill\" data-img-vw-m=\"462\" data-img-w-m=\"404.25\" data-img-h-m=\"219.4921875\" data-img-of-m=\"fill\"><\/div><div class=\"col all\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.terluinwebdesign.nl\/wp-content\/uploads\/2025\/07\/bizbuilder-dienst-pagina-desktop.png\" class=\"anim-fade-in\" data-src-light=\"\" data-src-dark=\"\" title=\"\" alt=\"\" width=\"3840\" height=\"2160\" srcset=\"https:\/\/www.terluinwebdesign.nl\/wp-content\/plugins\/tw-builder\/access\/img\/tmp\/2025\/07\/bizbuilder-dienst-pagina-desktop-w512.png.webp\" data-img-vw-d=\"1512\" data-img-w-d=\"356.2890625\" data-img-h-d=\"200.40625\" data-img-of-d=\"fill\" data-img-vw-t=\"617\" data-img-w-t=\"502.421875\" data-img-h-t=\"282.609375\" data-img-of-t=\"fill\" data-img-vw-m=\"462\" data-img-w-m=\"404.25\" data-img-h-m=\"227.390625\" data-img-of-m=\"fill\"><\/div><\/div><\/div><\/aside><\/prevent-autop><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>An HTML table of contents generator is often based on JavaScript. There are PHP-powered HTML table of contents generators. Those often use regex to seek for headings.I have a different HTML table of contents generator for you, which does not rely on regex.Instead, it relies on PHP&#8217;s built-in HTML parser. This generator does not require <a href=\"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/\" class=\"read-more-link block\">Read more<\/a><\/p>\n","protected":false},"author":2,"featured_media":6441,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,57],"tags":[],"class_list":["post-6440","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","category-html"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>HTML table of contents generator, PHP-powered \u2013 Terluin Webdesign<\/title>\n<meta name=\"description\" content=\"HTML table of contents generator, PHP-powered. No JavaScript, no regex, but using PHP&#039;s DOM API. Automatic ID&#039;s for headings, if not present.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"HTML table of contents generator, PHP-powered \u2013 Terluin Webdesign\" \/>\n<meta property=\"og:description\" content=\"HTML table of contents generator, PHP-powered. No JavaScript, no regex, but using PHP&#039;s DOM API. Automatic ID&#039;s for headings, if not present.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/\" \/>\n<meta property=\"og:site_name\" content=\"Terluin Webdesign\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/TerluinWebdesign\/\" \/>\n<meta property=\"article:published_time\" content=\"2020-10-30T20:09:14+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-07-18T14:56:24+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.terluinwebdesign.nl\/en\/wp-content\/uploads\/2021\/05\/html-table-of-contents-generator-php-powered.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"676\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Thijs Terluin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@terluinwdesign\" \/>\n<meta name=\"twitter:site\" content=\"@terluinwdesign\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Thijs Terluin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/\"},\"author\":{\"name\":\"Thijs Terluin\",\"@id\":\"https:\/\/www.terluinwebdesign.nl\/en\/#\/schema\/person\/a6f6b03a4d7acb99553ec297f1d6d1dd\"},\"headline\":\"HTML table of contents generator, PHP-powered\",\"datePublished\":\"2020-10-30T20:09:14+00:00\",\"dateModified\":\"2025-07-18T14:56:24+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/\"},\"wordCount\":6,\"publisher\":{\"@id\":\"https:\/\/www.terluinwebdesign.nl\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.terluinwebdesign.nl\/en\/wp-content\/uploads\/2021\/05\/html-table-of-contents-generator-php-powered.jpg\",\"articleSection\":[\"Blog\",\"HTML\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/\",\"url\":\"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/\",\"name\":\"HTML table of contents generator, PHP-powered \u2013 Terluin Webdesign\",\"isPartOf\":{\"@id\":\"https:\/\/www.terluinwebdesign.nl\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.terluinwebdesign.nl\/en\/wp-content\/uploads\/2021\/05\/html-table-of-contents-generator-php-powered.jpg\",\"datePublished\":\"2020-10-30T20:09:14+00:00\",\"dateModified\":\"2025-07-18T14:56:24+00:00\",\"description\":\"HTML table of contents generator, PHP-powered. No JavaScript, no regex, but using PHP's DOM API. Automatic ID's for headings, if not present.\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/#primaryimage\",\"url\":\"https:\/\/www.terluinwebdesign.nl\/en\/wp-content\/uploads\/2021\/05\/html-table-of-contents-generator-php-powered.jpg\",\"contentUrl\":\"https:\/\/www.terluinwebdesign.nl\/en\/wp-content\/uploads\/2021\/05\/html-table-of-contents-generator-php-powered.jpg\",\"width\":1200,\"height\":676,\"caption\":\"HTML table of contents generator\"},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.terluinwebdesign.nl\/en\/#website\",\"url\":\"https:\/\/www.terluinwebdesign.nl\/en\/\",\"name\":\"Terluin Webdesign\",\"description\":\"Let your website work for you\",\"publisher\":{\"@id\":\"https:\/\/www.terluinwebdesign.nl\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.terluinwebdesign.nl\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.terluinwebdesign.nl\/en\/#organization\",\"name\":\"Terluin Webdesign\",\"url\":\"https:\/\/www.terluinwebdesign.nl\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.terluinwebdesign.nl\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.terluinwebdesign.nl\/en\/wp-content\/uploads\/2019\/05\/terluin.png\",\"contentUrl\":\"https:\/\/www.terluinwebdesign.nl\/en\/wp-content\/uploads\/2019\/05\/terluin.png\",\"width\":294,\"height\":674,\"caption\":\"Terluin Webdesign\"},\"image\":{\"@id\":\"https:\/\/www.terluinwebdesign.nl\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/TerluinWebdesign\/\",\"https:\/\/x.com\/terluinwdesign\",\"https:\/\/www.instagram.com\/terluinwebdesign\/\",\"https:\/\/www.linkedin.com\/company\/terluin-webdesig\/\",\"https:\/\/www.youtube.com\/channel\/UCqaaHJh0caCmucUaWsewhKQ\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.terluinwebdesign.nl\/en\/#\/schema\/person\/a6f6b03a4d7acb99553ec297f1d6d1dd\",\"name\":\"Thijs Terluin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.terluinwebdesign.nl\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/adff8d4881876bce4a26779bbab04daa390a45232b37b4f00a6ad954e4bc705f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/adff8d4881876bce4a26779bbab04daa390a45232b37b4f00a6ad954e4bc705f?s=96&d=mm&r=g\",\"caption\":\"Thijs Terluin\"},\"description\":\"Thijs Terluin is a web designer at Terluin Webdesign. He specializes in providing the structure, functionalities and speed of websites and web shops on devices and web browsers.\",\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/thijs-terluin\/\"],\"url\":\"https:\/\/www.terluinwebdesign.nl\/en\/about-us\/thijs-terluin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"HTML table of contents generator, PHP-powered \u2013 Terluin Webdesign","description":"HTML table of contents generator, PHP-powered. No JavaScript, no regex, but using PHP's DOM API. Automatic ID's for headings, if not present.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/","og_locale":"en_US","og_type":"article","og_title":"HTML table of contents generator, PHP-powered \u2013 Terluin Webdesign","og_description":"HTML table of contents generator, PHP-powered. No JavaScript, no regex, but using PHP's DOM API. Automatic ID's for headings, if not present.","og_url":"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/","og_site_name":"Terluin Webdesign","article_publisher":"https:\/\/www.facebook.com\/TerluinWebdesign\/","article_published_time":"2020-10-30T20:09:14+00:00","article_modified_time":"2025-07-18T14:56:24+00:00","og_image":[{"width":1200,"height":676,"url":"https:\/\/www.terluinwebdesign.nl\/en\/wp-content\/uploads\/2021\/05\/html-table-of-contents-generator-php-powered.jpg","type":"image\/jpeg"}],"author":"Thijs Terluin","twitter_card":"summary_large_image","twitter_creator":"@terluinwdesign","twitter_site":"@terluinwdesign","twitter_misc":{"Written by":"Thijs Terluin","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/#article","isPartOf":{"@id":"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/"},"author":{"name":"Thijs Terluin","@id":"https:\/\/www.terluinwebdesign.nl\/en\/#\/schema\/person\/a6f6b03a4d7acb99553ec297f1d6d1dd"},"headline":"HTML table of contents generator, PHP-powered","datePublished":"2020-10-30T20:09:14+00:00","dateModified":"2025-07-18T14:56:24+00:00","mainEntityOfPage":{"@id":"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/"},"wordCount":6,"publisher":{"@id":"https:\/\/www.terluinwebdesign.nl\/en\/#organization"},"image":{"@id":"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/#primaryimage"},"thumbnailUrl":"https:\/\/www.terluinwebdesign.nl\/en\/wp-content\/uploads\/2021\/05\/html-table-of-contents-generator-php-powered.jpg","articleSection":["Blog","HTML"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/","url":"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/","name":"HTML table of contents generator, PHP-powered \u2013 Terluin Webdesign","isPartOf":{"@id":"https:\/\/www.terluinwebdesign.nl\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/#primaryimage"},"image":{"@id":"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/#primaryimage"},"thumbnailUrl":"https:\/\/www.terluinwebdesign.nl\/en\/wp-content\/uploads\/2021\/05\/html-table-of-contents-generator-php-powered.jpg","datePublished":"2020-10-30T20:09:14+00:00","dateModified":"2025-07-18T14:56:24+00:00","description":"HTML table of contents generator, PHP-powered. No JavaScript, no regex, but using PHP's DOM API. Automatic ID's for headings, if not present.","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.terluinwebdesign.nl\/en\/blog\/html-table-of-contents-generator-php-powered\/#primaryimage","url":"https:\/\/www.terluinwebdesign.nl\/en\/wp-content\/uploads\/2021\/05\/html-table-of-contents-generator-php-powered.jpg","contentUrl":"https:\/\/www.terluinwebdesign.nl\/en\/wp-content\/uploads\/2021\/05\/html-table-of-contents-generator-php-powered.jpg","width":1200,"height":676,"caption":"HTML table of contents generator"},{"@type":"WebSite","@id":"https:\/\/www.terluinwebdesign.nl\/en\/#website","url":"https:\/\/www.terluinwebdesign.nl\/en\/","name":"Terluin Webdesign","description":"Let your website work for you","publisher":{"@id":"https:\/\/www.terluinwebdesign.nl\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.terluinwebdesign.nl\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.terluinwebdesign.nl\/en\/#organization","name":"Terluin Webdesign","url":"https:\/\/www.terluinwebdesign.nl\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.terluinwebdesign.nl\/en\/#\/schema\/logo\/image\/","url":"https:\/\/www.terluinwebdesign.nl\/en\/wp-content\/uploads\/2019\/05\/terluin.png","contentUrl":"https:\/\/www.terluinwebdesign.nl\/en\/wp-content\/uploads\/2019\/05\/terluin.png","width":294,"height":674,"caption":"Terluin Webdesign"},"image":{"@id":"https:\/\/www.terluinwebdesign.nl\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/TerluinWebdesign\/","https:\/\/x.com\/terluinwdesign","https:\/\/www.instagram.com\/terluinwebdesign\/","https:\/\/www.linkedin.com\/company\/terluin-webdesig\/","https:\/\/www.youtube.com\/channel\/UCqaaHJh0caCmucUaWsewhKQ"]},{"@type":"Person","@id":"https:\/\/www.terluinwebdesign.nl\/en\/#\/schema\/person\/a6f6b03a4d7acb99553ec297f1d6d1dd","name":"Thijs Terluin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.terluinwebdesign.nl\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/adff8d4881876bce4a26779bbab04daa390a45232b37b4f00a6ad954e4bc705f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/adff8d4881876bce4a26779bbab04daa390a45232b37b4f00a6ad954e4bc705f?s=96&d=mm&r=g","caption":"Thijs Terluin"},"description":"Thijs Terluin is a web designer at Terluin Webdesign. He specializes in providing the structure, functionalities and speed of websites and web shops on devices and web browsers.","sameAs":["https:\/\/www.linkedin.com\/in\/thijs-terluin\/"],"url":"https:\/\/www.terluinwebdesign.nl\/en\/about-us\/thijs-terluin\/"}]}},"_links":{"self":[{"href":"https:\/\/www.terluinwebdesign.nl\/en\/wp-json\/wp\/v2\/posts\/6440","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.terluinwebdesign.nl\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.terluinwebdesign.nl\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.terluinwebdesign.nl\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.terluinwebdesign.nl\/en\/wp-json\/wp\/v2\/comments?post=6440"}],"version-history":[{"count":2,"href":"https:\/\/www.terluinwebdesign.nl\/en\/wp-json\/wp\/v2\/posts\/6440\/revisions"}],"predecessor-version":[{"id":9086,"href":"https:\/\/www.terluinwebdesign.nl\/en\/wp-json\/wp\/v2\/posts\/6440\/revisions\/9086"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.terluinwebdesign.nl\/en\/wp-json\/wp\/v2\/media\/6441"}],"wp:attachment":[{"href":"https:\/\/www.terluinwebdesign.nl\/en\/wp-json\/wp\/v2\/media?parent=6440"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.terluinwebdesign.nl\/en\/wp-json\/wp\/v2\/categories?post=6440"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.terluinwebdesign.nl\/en\/wp-json\/wp\/v2\/tags?post=6440"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}