{"id":355602,"date":"2026-08-17T05:16:17","date_gmt":"2026-08-17T05:16:17","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/aiforya-table-of-contents\/"},"modified":"2026-08-17T05:15:50","modified_gmt":"2026-08-17T05:15:50","slug":"aiforya-table-of-contents","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/aiforya-table-of-contents\/","author":23534313,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.0","stable_tag":"1.0.0","tested":"7.1","requires":"6.0","requires_php":"8.0","requires_plugins":null,"header_name":"AIFORYA Table of Contents","header_author":"AIFORYA","header_description":"Automatically add a clickable table of contents to your posts and pages, built from the headings in the content, with anchors and a shortcode \u2014 100% local, no API key.","assets_banners_color":"0e0e2a","last_updated":"2026-08-17 05:15:50","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/www.aiforya.fr\/fr\/wordpress\/extensions-gratuites\/toc","header_author_uri":"https:\/\/aiforya.fr","rating":0,"author_block_rating":0,"active_installs":0,"downloads":31,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"aiforya","date":"2026-08-17 05:15:50"}},"upgrade_notice":{"1.0.0":"<p>Initial release.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3650459,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3650459,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3650483,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3650483,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3650480,"resolution":"1","location":"assets","locale":"","width":1704,"height":940},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3650480,"resolution":"2","location":"assets","locale":"","width":1707,"height":938},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3650480,"resolution":"3","location":"assets","locale":"","width":831,"height":914}},"screenshots":{"1":"Table of contents status and configuration overview.","2":"Settings: display, covered content and table contents.","3":"The clickable table of contents as readers see it on the front end."}},"plugin_section":[],"plugin_tags":[7205,19897,939,10851,10852],"plugin_category":[59],"plugin_contributors":[275016],"plugin_business_model":[],"class_list":["post-355602","plugin","type-plugin","status-publish","hentry","plugin_tags-anchors","plugin_tags-headings","plugin_tags-permalinks","plugin_tags-table-of-contents","plugin_tags-toc","plugin_category-utilities-and-tools","plugin_contributors-aiforya","plugin_committers-aiforya"],"banners":{"banner":"https:\/\/ps.w.org\/aiforya-table-of-contents\/assets\/banner-772x250.png?rev=3650483","banner_2x":"https:\/\/ps.w.org\/aiforya-table-of-contents\/assets\/banner-1544x500.png?rev=3650483","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/aiforya-table-of-contents\/assets\/icon-128x128.png?rev=3650459","icon_2x":"https:\/\/ps.w.org\/aiforya-table-of-contents\/assets\/icon-256x256.png?rev=3650459","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/aiforya-table-of-contents\/assets\/screenshot-1.png?rev=3650480","caption":"Table of contents status and configuration overview."},{"src":"https:\/\/ps.w.org\/aiforya-table-of-contents\/assets\/screenshot-2.png?rev=3650480","caption":"Settings: display, covered content and table contents."},{"src":"https:\/\/ps.w.org\/aiforya-table-of-contents\/assets\/screenshot-3.png?rev=3650480","caption":"The clickable table of contents as readers see it on the front end."}],"raw_content":"<!--section=description-->\n<p><strong>AIFORYA Table of Contents<\/strong> builds a clickable table of contents from the headings in your content \u2014 and then keeps the resulting anchor links working.<\/p>\n\n<h4>The problem this plugin exists for<\/h4>\n\n<p>In most tables of contents an anchor is derived from the heading text. Rename \"Introduction\" to \"Foreword\" and <code>#introduction<\/code> stops existing. Every link that pointed at it is now broken: your own internal links, links from other sites, links in newsletters you sent two years ago.<\/p>\n\n<p>Nothing warns you. The page still returns 200, and the browser simply does not scroll.<\/p>\n\n<h4>What this plugin does instead<\/h4>\n\n<p>A section is given its address <strong>when it is first published<\/strong>, and keeps it. The heading text can change, the section can be moved, the post can be split into pages \u2014 the address follows the <em>content<\/em>, never the wording or the position. Every heading text a section has ever had is kept as an alias, so older links keep resolving too.<\/p>\n\n<p><strong>Try it in thirty seconds:<\/strong> publish a post with two sections, copy a link to the second one, then swap the two sections around and rename one of them. Your link still lands on the right section.<\/p>\n\n<h4>Features<\/h4>\n\n<ul>\n<li><strong>Permanent section addresses<\/strong> \u2014 an anchor assigned once is kept, through renames, reordering and repagination.<\/li>\n<li><strong>Alias registry<\/strong> \u2014 previous addresses of a section stay reachable, so old links keep working. Addresses are kept by default: an address you stop honouring is a promise you break without knowing it.<\/li>\n<li><strong>Multipage posts covered end to end<\/strong> \u2014 when a post is split with the <code>&lt;!--nextpage--&gt;<\/code> tag, the table lists the headings of <em>every<\/em> page and links to the right page and heading. This is the same promise applied across pages.<\/li>\n<li><strong>Automatic table of contents<\/strong> \u2014 reads the headings (h2, h3, and so on) in your content and builds a hierarchical list of links.<\/li>\n<li><strong>Clickable anchors<\/strong> \u2014 a unique anchor link is added to each heading so readers can jump directly.<\/li>\n<li><strong>Automatic or manual placement<\/strong> \u2014 insert the table automatically before the first heading, or choose where it goes with the <code>[aiforya_toc]<\/code> shortcode.<\/li>\n<li><strong>Post types of your choice<\/strong> \u2014 enable the table on the post types you want (posts, pages, and more).<\/li>\n<li><strong>Adjustable threshold and levels<\/strong> \u2014 set the minimum number of headings required, and the deepest heading level to include.<\/li>\n<li><strong>Neutral, unobtrusive styling<\/strong> \u2014 the table fits into any public theme without imposing its own colours.<\/li>\n<\/ul>\n\n<h4>Privacy<\/h4>\n\n<p>The plugin runs entirely on your own server. Nothing is sent to any third party.<\/p>\n\n<h4>Advanced version<\/h4>\n\n<p>An advanced version (see aiforya.fr) adds a floating table of contents, numbering, word counts and smooth scrolling. This free version is fully functional on its own, with no time limit.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Install and activate the plugin.<\/li>\n<li>Open the <strong>AIFORYA Table of Contents<\/strong> menu.<\/li>\n<li>In the <strong>Settings<\/strong> tab, choose the post types, the minimum number of headings and the levels to include.<\/li>\n<li>Publish or edit a long piece of content: the table appears automatically. To place it yourself, insert <code>[aiforya_toc]<\/code>.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"how%20is%20the%20table%20built%3F\"><h3>How is the table built?<\/h3><\/dt>\n<dd><p>The plugin reads the headings in your content (h2, h3, and so on, down to the level you choose) and turns them into a hierarchical list. An anchor link is added to each heading so readers can jump directly.<\/p><\/dd>\n<dt id=\"what%20happens%20to%20my%20links%20when%20i%20rename%20a%20heading%3F\"><h3>What happens to my links when I rename a heading?<\/h3><\/dt>\n<dd><p>They keep working. The section keeps the address it was given when it was first published, and the heading text you just replaced is kept as an alias, so links built on it still resolve. Both the old and the new wording lead to the same section.<\/p><\/dd>\n<dt id=\"and%20if%20i%20move%20a%20section%20somewhere%20else%20in%20the%20post%3F\"><h3>And if I move a section somewhere else in the post?<\/h3><\/dt>\n<dd><p>Its address moves with it. Sections are matched by their content, not by their position, so swapping two sections does not swap their addresses \u2014 which is exactly what would happen if positions were used.<\/p><\/dd>\n<dt id=\"where%20is%20this%20registry%20stored%2C%20and%20what%20happens%20if%20i%20remove%20the%20plugin%3F\"><h3>Where is this registry stored, and what happens if I remove the plugin?<\/h3><\/dt>\n<dd><p>In your own database, as post metadata, on your own server. Nothing leaves your site. If you deactivate the plugin the registry is left untouched, so reactivating it restores every address; uninstalling removes the plugin's settings.<\/p><\/dd>\n<dt id=\"are%20there%20sections%20the%20plugin%20will%20not%20track%3F\"><h3>Are there sections the plugin will not track?<\/h3><\/dt>\n<dd><p>Yes, and deliberately: two headings with the exact same wording in the same post. They cannot be told apart without guessing, and a \"permanent\" address that guesses wrong is worse than none. Those headings keep the ordinary behaviour, with an anchor derived from their text.<\/p><\/dd>\n<dt id=\"what%20happens%20on%20a%20post%20split%20into%20several%20pages%3F\"><h3>What happens on a post split into several pages?<\/h3><\/dt>\n<dd><p>The table covers the whole post. On any page, it lists the headings of every page, and each link takes the reader to the correct page and scrolls to the correct heading. A page that contains no heading of its own still shows the table, so the reader is never left without the outline.<\/p><\/dd>\n<dt id=\"which%20content%20shows%20a%20table%20of%20contents%3F\"><h3>Which content shows a table of contents?<\/h3><\/dt>\n<dd><p>The post types you select in the Settings tab, and only when they reach the minimum number of headings you defined.<\/p><\/dd>\n<dt id=\"can%20i%20place%20the%20table%20at%20a%20specific%20spot%3F\"><h3>Can I place the table at a specific spot?<\/h3><\/dt>\n<dd><p>Yes. Insert the <code>[aiforya_toc]<\/code> shortcode where you want it. When that shortcode is present, automatic insertion is disabled for that content to avoid duplicates.<\/p><\/dd>\n<dt id=\"is%20it%20compatible%20with%20my%20theme%3F\"><h3>Is it compatible with my theme?<\/h3><\/dt>\n<dd><p>Yes. It uses neutral, unobtrusive styling designed to fit into any public theme.<\/p><\/dd>\n<dt id=\"do%20i%20need%20an%20api%20key%3F\"><h3>Do I need an API key?<\/h3><\/dt>\n<dd><p>No. The plugin is entirely self-contained and runs locally, with no external service.<\/p><\/dd>\n<dt id=\"where%20do%20i%20get%20support%3F\"><h3>Where do I get support?<\/h3><\/dt>\n<dd><p>Through the support forum of this plugin on WordPress.org.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release: permanent section addresses kept through renames and reordering, alias registry so older anchor links keep resolving, full coverage of multipage posts split with <code>&lt;!--nextpage--&gt;<\/code>, automatic table of contents from headings, automatic insertion or <code>[aiforya_toc]<\/code> shortcode, post types, adjustable threshold and levels.<\/li>\n<\/ul>","raw_excerpt":"A table of contents whose anchor links keep working after you rename, move or repaginate a section. Fully local, no API key.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/355602","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=355602"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/aiforya"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=355602"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=355602"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=355602"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=355602"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=355602"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=355602"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}