{"id":339334,"date":"2026-07-18T17:07:47","date_gmt":"2026-07-18T17:07:47","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/axismundi-table-of-contents\/"},"modified":"2026-07-18T17:07:15","modified_gmt":"2026-07-18T17:07:15","slug":"axismundi-table-of-contents","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/axismundi-table-of-contents\/","author":21128503,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.1.2","stable_tag":"0.1.2","tested":"7.0.2","requires":"6.7","requires_php":"8.1","requires_plugins":null,"header_name":"Axismundi Table of Contents","header_author":"KIM JIWOON","header_description":"On-page table of contents block that builds from a post's headings and keeps the heading ids in sync.","assets_banners_color":"","last_updated":"2026-07-18 17:07:15","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/github.com\/Jiwoon-Kim\/axismundi\/tree\/main\/products\/distributables\/plugins\/axismundi-table-of-contents","header_author_uri":"https:\/\/designbusan.ai.kr","rating":0,"author_block_rating":0,"active_installs":0,"downloads":49,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.1.2":{"tag":"0.1.2","author":"kimjiwoon","date":"2026-07-18 17:07:15"}},"upgrade_notice":[],"ratings":[],"assets_icons":[],"assets_banners":[],"assets_blueprints":{},"all_blocks":{"axismundi\/toc":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"axismundi\/toc","version":"0.1.2","title":"Table of Contents","category":"theme","icon":"list-view","description":"Builds an on-page table of contents from the post's headings, with a scroll-spy active state.","keywords":["toc","table of contents","headings","outline","on this page"],"textdomain":"axismundi-table-of-contents","attributes":{"title":{"type":"string","default":"On this page"},"showTitle":{"type":"boolean","default":true},"ordered":{"type":"boolean","default":false},"minLevel":{"type":"number","default":2},"maxLevel":{"type":"number","default":4},"variant":{"type":"string","default":"rail"},"openByDefault":{"type":"boolean","default":false},"summaryMode":{"type":"string","default":"current"}},"supports":{"html":false,"align":false,"color":{"text":true,"background":true},"spacing":{"padding":true,"margin":true}},"example":{"attributes":{}},"editorScript":"file:.\/edit.js","editorStyle":"file:.\/editor.css","style":"file:.\/style.css","render":"file:.\/render.php","viewScriptModule":"file:.\/view.js"}},"tagged_versions":["0.1.2"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[1220,19897,1753,10851,10852],"plugin_category":[43],"plugin_contributors":[270183],"plugin_business_model":[],"class_list":["post-339334","plugin","type-plugin","status-publish","hentry","plugin_tags-block","plugin_tags-headings","plugin_tags-navigation","plugin_tags-table-of-contents","plugin_tags-toc","plugin_category-customization","plugin_contributors-kimjiwoon","plugin_committers-kimjiwoon"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/s.w.org\/plugins\/geopattern-icon\/axismundi-table-of-contents.svg","icon_2x":false,"generated":true},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Axismundi Table of Contents provides the <code>axismundi\/toc<\/code> block: a dynamic,\nserver-rendered list built from the current post's headings, with a scroll-spy\nthat marks the section you are reading.<\/p>\n\n<p>The block render and a <code>render_block_core\/post-content<\/code> filter share one\ndeterministic slug function, so the table-of-contents anchors always match the\nheading ids \u2014 regardless of render order or where you place the block (a template\naside or inside the content). Author-provided HTML anchors are respected, and\nduplicate headings are de-duplicated (<code>-2<\/code>, <code>-3<\/code>).<\/p>\n\n<ul>\n<li>Two placements: a sidebar <strong>rail<\/strong>, or a collapsible <strong>disclosure<\/strong> above the\ncontent (a native <code>&lt;details&gt;<\/code> whose summary can echo the current\nsection). A \"Table of contents (above content)\" pattern ships the disclosure\nready to drop before the post content.<\/li>\n<li>Builds from <code>h2<\/code>\u2013<code>h4<\/code> by default (configurable per block).<\/li>\n<li>Unordered list by default; switch to a numbered (ordered) list per block.<\/li>\n<li>Emits the shared <code>toc-list<\/code> \/ <code>toc-h2\u2026h4<\/code> \/ <code>is-current<\/code> class vocabulary so a\ntheme's table-of-contents skin couples for free; ships a Material Design 3\ntoken skin (with fallbacks) in the meantime.<\/li>\n<li>Scroll-spy marks the current heading and clears when you leave the content\n(above the first heading or past the post content).<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Install and activate the Axismundi theme (for the Material Design 3 skin; the\nblock also works under any theme that styles <code>.toc-list<\/code> \/ <code>.is-current<\/code>).<\/li>\n<li>Upload and activate this plugin.<\/li>\n<li>Add the Table of Contents block where you want it \u2014 typically a sidebar aside\nin the single-post template, or inside a Details block above the content.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20this%20plugin%20require%20an%20external%20service%3F\"><h3>Does this plugin require an external service?<\/h3><\/dt>\n<dd><p>No. The table of contents is built on the server from the post's own headings.<\/p><\/dd>\n<dt id=\"how%20are%20the%20heading%20ids%20created%3F\"><h3>How are the heading ids created?<\/h3><\/dt>\n<dd><p>From the heading text via <code>sanitize_title()<\/code>, de-duplicated in document order. If\na heading already has an HTML anchor, that id is kept. The same function feeds the\nblock and the heading-id injection, so the anchors always resolve.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20non-latin%20headings%3F\"><h3>Does it work with non-Latin headings?<\/h3><\/dt>\n<dd><p>Yes. Non-ASCII headings (for example Korean) are percent-encoded into the same\nvalue on both the heading id and the table-of-contents link, and the scroll-spy\nmatches them literally.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.1.2<\/h4>\n\n<ul>\n<li>Let the host theme or template control disclosure placement and sticky\nbehavior so the block remains layout-neutral in the editor.<\/li>\n<\/ul>\n\n<h4>0.1.1<\/h4>\n\n<ul>\n<li>Prepare the package for WordPress.org Plugin Check by removing the hidden\ndistribution manifest and relying on WordPress.org translation loading.<\/li>\n<\/ul>\n\n<h4>0.1.0<\/h4>\n\n<ul>\n<li>Initial release: the <code>axismundi\/toc<\/code> block (server-rendered list from post\nheadings) with deterministic, shared heading-id slugs and <code>is-current<\/code>\nscroll-spy.<\/li>\n<li>IntersectionObserver plus an rAF scroll fallback decide the active section from\none rule; the active state clears when the reading position leaves the content.<\/li>\n<li>Material Design 3 token skin (with fallbacks) over the shared <code>toc-list<\/code> \/\n  is-current vocabulary; smooth in-page scrolling is owned by the theme.<\/li>\n<li>Rail and disclosure placements. The disclosure is a native <code>&lt;details&gt;<\/code>;\nplacement and sticky behavior are controlled by the host theme or template.\nOpen-by-default and summary mode are per-block, and its summary can track the\ncurrent section. Ships a \"Table of contents (above content)\" pattern.<\/li>\n<\/ul>","raw_excerpt":"On-page table of contents block that builds from a post&#039;s headings and keeps the heading ids in sync.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/339334","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=339334"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/kimjiwoon"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=339334"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=339334"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=339334"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=339334"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=339334"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=339334"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}