Visual Sitemap for Readers
An accessible, collapsible HTML sitemap for WordPress with search, filters, and a styled wp-sitemap.xml.
by Imran Ali · github.com/grim-reapper/visual-sitemap-for-readers · website
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/grim-reapper/visual-sitemap-for-readers/archive/refs/heads/main.zipReadme
Visual Sitemap for Readers
An accessible, collapsible visual sitemap of your pages, categories, posts and tags. Add it to any post or page with a single shortcode.
- Version: 1.0.0
- Requires: WordPress 5.8+, PHP 7.2+
- License: GPL-2.0-or-later
- wordpress.org slug:
visual-sitemap-for-readers
What it does
Renders the structure of your site as a clean, collapsible tree — pages nested by
parent, categories nested with their posts inside, and a group of tags. Every entry
is a real <a> link, so the sitemap is crawlable, printable and screen-reader
friendly.
- Live search with match highlighting
- Filter by content type (pages / categories / posts / tags)
- Expand all / collapse all
- Per-type colours, width and default open state via the Customizer
- Light / dark aware, follows the visitor's
prefers-color-scheme - Keyboard accessible, respects
prefers-reduced-motion - No jQuery, no external libraries; assets load only where the shortcode is used
- Tree cached with the Transients API, rebuilt automatically on content changes
Usage
[visual_sitemap]
[visual_sitemap show="pages,categories" expanded="all" depth="3" search="false"]
| Attribute | Values | Default |
|---|---|---|
show |
pages, categories, tags |
all |
expanded |
all, groups, none |
Customizer value |
depth |
integer, 0 = unlimited |
0 |
search |
true / false |
Customizer value |
filters |
true / false |
Customizer value |
title |
any text | "Site map" |
Appearance is configured under Appearance → Customize → Visual Sitemap. Settings → Visual Sitemap documents the shortcode, selects the sitemap page, and offers a cache-clear button.
Sitemap page & wp-sitemap.xml
- Settings → Visual Sitemap lets you pick the sitemap page, or press Create a sitemap page.
With nothing selected, a published page whose slug is
sitemap/site-mapis used. - On that page the tree renders automatically (priority-25
the_contentfilter) unless the page already contains[visual_sitemap]. - The page is registered with WordPress core's Sitemaps API as a
visualsitemapprovider, so it appears inwp-sitemap.xml(aswp-sitemap-visualsitemap-1.xml) and is removed from the default pages sitemap to avoid a duplicate entry. - A
<link rel="sitemap" type="application/xml" href=".../wp-sitemap.xml">tag is added towp_head. - The browser view of
wp-sitemap.xmland every sub-sitemap is restyled to match the plugin, by replacing core's XSLT viawp_sitemaps_stylesheet_content/wp_sitemaps_stylesheet_index_content. Templates: public/xsl/sitemap.xsl, public/xsl/sitemap-index.xsl; translatable strings are filled in by class-visual-sitemap-stylesheet.php. - All of this is skipped when core sitemaps are disabled (
blog_public = 0, or an SEO plugin filteringwp_sitemaps_enabled). Filters:visual_sitemap_page_id,visual_sitemap_auto_render,visual_sitemap_xml_provider,visual_sitemap_xml_url_list,visual_sitemap_head_link,visual_sitemap_style_xsl.
Extending
// Add or reshape nodes before the tree is cached.
add_filter( 'visual_sitemap_tree', function ( $tree ) {
return $tree;
} );
// Include categories / tags with no content.
add_filter( 'visual_sitemap_hide_empty_terms', '__return_false' );
// Change how long the tree is cached (default: one day).
add_filter( 'visual_sitemap_cache_lifetime', fn() => HOUR_IN_SECONDS );
// Cap how many posts are grouped under categories (default: 1000).
add_filter( 'visual_sitemap_max_posts', fn() => 500 );
Node shape:
array(
'id' => 'page-12',
'type' => 'page' | 'category' | 'post' | 'tag' | 'group',
'title' => 'About',
'url' => 'https://example.com/about/',
'count' => 3, // optional, shown as a badge
'children' => array( /* nodes */ ),
);
Structure
visual-sitemap-for-readers.php Bootstrap, constants, activation hooks
includes/
class-visual-sitemap.php Wires everything together
class-visual-sitemap-loader.php Hook registrar
class-visual-sitemap-i18n.php Text domain
class-visual-sitemap-generator.php Builds + caches the tree
class-visual-sitemap-settings.php Defaults, Customizer values, attribute merge
class-visual-sitemap-renderer.php Tree -> accessible HTML
class-visual-sitemap-shortcode.php [visual_sitemap]
class-visual-sitemap-customizer.php Customizer section
class-visual-sitemap-integration.php Sitemap page + wp-sitemap.xml wiring
class-visual-sitemap-xml-provider.php Core Sitemaps API provider
class-visual-sitemap-stylesheet.php Styled XSLT for the XML sitemap views
admin/
class-visual-sitemap-admin.php Settings help page + cache tool
public/
class-visual-sitemap-public.php Registers / enqueues assets
css/visual-sitemap.css
js/visual-sitemap.js
xsl/sitemap.xsl, xsl/sitemap-index.xsl XML-sitemap stylesheet templates
uninstall.php Cleanup on delete
Development
Tests use the WordPress PHPUnit test suite:
composer install
./vendor/bin/phpunit