{"id":357236,"date":"2026-08-26T16:16:17","date_gmt":"2026-08-26T16:16:17","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/scalable-page-manager\/"},"modified":"2026-09-04T18:28:32","modified_gmt":"2026-09-04T18:28:32","slug":"pagescale","status":"publish","type":"plugin","link":"https:\/\/mr.wordpress.org\/plugins\/pagescale\/","author":23553162,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.6.0","stable_tag":"1.6.0","tested":"7.1","requires":"6.0","requires_php":"7.4","requires_plugins":null,"header_name":"PageScale","header_author":"Shahzaib Rasheed","header_description":"High-performance page management for sites with 10,000+ pages. Lazy tree, virtual-scroll list, keyset pagination, indexed FULLTEXT search across title, slug, content and ACF fields. Elementor-aware quick actions.","assets_banners_color":"416189","last_updated":"2026-09-04 18:28:32","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/github.com\/Shahzeb2u\/scalable-page-manager","header_author_uri":"","rating":0,"author_block_rating":0,"active_installs":0,"downloads":99,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.5.1":{"tag":"1.5.1","author":"shahzeb2u","date":"2026-08-26 18:16:07","revision":3667612},"1.6.0":{"tag":"1.6.0","author":"shahzeb2u","date":"2026-09-04 18:28:32","revision":3681668}},"upgrade_notice":{"1.6.0":"<p>Adds custom post type support. Pages behaviour is unchanged; enable other post types in Settings &gt; PageScale.<\/p>","1.5.0":"<p>Initial public release.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3676698,"resolution":"128x128","location":"assets","locale":"","width":128,"height":129},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3676698,"resolution":"256x256","location":"assets","locale":"","width":256,"height":257}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3676698,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3676698,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.5.1","1.6.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3667612,"resolution":"1","location":"assets","locale":"","width":1748,"height":890},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3667612,"resolution":"2","location":"assets","locale":"","width":1741,"height":814},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3667612,"resolution":"3","location":"assets","locale":"","width":1747,"height":885},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3667612,"resolution":"4","location":"assets","locale":"","width":1750,"height":894}},"screenshots":{"1":"The scalable list with virtual scrolling and quick actions.","2":"Lazy-loading hierarchy tree.","3":"Tiered search across titles, slugs, content and custom fields.","4":"Settings screen for choosing which post types to manage."}},"plugin_section":[],"plugin_tags":[83,4914,243,247,944],"plugin_category":[54],"plugin_contributors":[277681],"plugin_business_model":[],"class_list":["post-357236","plugin","type-plugin","status-publish","hentry","plugin_tags-admin","plugin_tags-page-management","plugin_tags-pages","plugin_tags-performance","plugin_tags-search","plugin_category-security-and-spam-protection","plugin_contributors-shahzeb2u","plugin_committers-shahzeb2u"],"banners":{"banner":"https:\/\/ps.w.org\/pagescale\/assets\/banner-772x250.png?rev=3676698","banner_2x":"https:\/\/ps.w.org\/pagescale\/assets\/banner-1544x500.png?rev=3676698","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/pagescale\/assets\/icon-128x128.png?rev=3676698","icon_2x":"https:\/\/ps.w.org\/pagescale\/assets\/icon-256x256.png?rev=3676698","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/pagescale\/assets\/screenshot-1.png?rev=3667612","caption":"The scalable list with virtual scrolling and quick actions."},{"src":"https:\/\/ps.w.org\/pagescale\/assets\/screenshot-2.png?rev=3667612","caption":"Lazy-loading hierarchy tree."},{"src":"https:\/\/ps.w.org\/pagescale\/assets\/screenshot-3.png?rev=3667612","caption":"Tiered search across titles, slugs, content and custom fields."},{"src":"https:\/\/ps.w.org\/pagescale\/assets\/screenshot-4.png?rev=3667612","caption":"Settings screen for choosing which post types to manage."}],"raw_content":"<!--section=description-->\n<p>PageScale replaces the default WordPress list screen with an admin interface built to stay fast on sites that have tens of thousands (or millions) of entries. The stock list table slows down at that scale because it relies on OFFSET pagination and unindexed queries. PageScale takes a different approach at every layer.<\/p>\n\n<p>As of 1.6.0, PageScale is no longer limited to Pages. You choose which post types it manages from a settings screen. Hierarchical types (like Pages) keep the lazy parent\/child tree; non-hierarchical types (like Posts or a Products CPT) get the fast flat list. Pages behaviour is unchanged by default, so existing sites are unaffected until you opt additional types in.<\/p>\n\n<p><strong>How it stays fast<\/strong><\/p>\n\n<ul>\n<li>Keyset (cursor) pagination instead of OFFSET, so the cost of loading any page of results is constant whether you have 10,000 rows or 1,000,000.<\/li>\n<li>Lazy hierarchy: only the children of a node you actually expand are queried. The tree never loads the whole site at once.<\/li>\n<li>Tiered search: numeric input goes straight to the primary key, slugs use an indexed equality\/prefix lookup, and title\/content\/custom-field search uses InnoDB FULLTEXT (MATCH ... AGAINST) rather than a leading-wildcard LIKE. Content and custom-field search is optional via a UI toggle and runs entirely in MySQL, so post content is never loaded into PHP memory.<\/li>\n<li>Virtual scrolling keeps the DOM bounded (about 50 rows) at any dataset size.<\/li>\n<li>Cached aggregates: totals, the parents list and duplicate reports are cached with the Transients API, keyed per post type.<\/li>\n<\/ul>\n\n<p><strong>Custom post type support<\/strong><\/p>\n\n<ul>\n<li>Choose which post types to manage from Settings &gt; PageScale.<\/li>\n<li>Each managed type gets its own Scalable Manager screen under its menu, with a switcher to move between types.<\/li>\n<li>Hierarchical types show the parent\/child tree and a parents panel; non-hierarchical types show a flat list without a Parent column.<\/li>\n<li>Search, quick edit, bulk actions, duplicate and CSV export all work per type.<\/li>\n<\/ul>\n\n<p><strong>Other features<\/strong><\/p>\n\n<ul>\n<li>Elementor-aware quick actions.<\/li>\n<li>Bulk actions, chunked client-side so large operations don't time out.<\/li>\n<li>Duplicate finder for titles, exact slugs and similar slugs.<\/li>\n<li>CSV export of the current view or a selection.<\/li>\n<li>WP-CLI command to build the search indexes on demand.<\/li>\n<\/ul>\n\n<p><strong>Indexing is safe on large tables<\/strong><\/p>\n\n<p>PageScale never runs a long ALTER TABLE during activation. Instead it records that indexes are pending and builds them lazily, one at a time, on later admin loads (or immediately via WP-CLI). The plugin is fully usable while indexing is in progress, and search simply runs in a basic mode until the FULLTEXT indexes exist.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>pagescale<\/code> folder to <code>\/wp-content\/plugins\/<\/code>, or install the plugin through the Plugins screen in WordPress.<\/li>\n<li>Activate the plugin through the Plugins screen.<\/li>\n<li>Open <strong>Pages &gt; Scalable Manager<\/strong> in the admin menu.<\/li>\n<li>To manage other post types, go to <strong>Settings &gt; PageScale<\/strong> and tick the types you want.<\/li>\n<li>On large sites, optionally run <code>wp pgscl build-indexes<\/code> via WP-CLI to build the search indexes immediately instead of waiting for them to build in the background.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"which%20post%20types%20can%20pagescale%20manage%3F\"><h3>Which post types can PageScale manage?<\/h3><\/dt>\n<dd><p>Any public post type shown in the admin. Pages is enabled by default; add others from Settings &gt; PageScale. Internal or configuration post types are rarely worth managing this way, so the choice is left to you rather than enabling everything automatically.<\/p><\/dd>\n<dt id=\"what%20is%20the%20difference%20between%20hierarchical%20and%20flat%20types%3F\"><h3>What is the difference between hierarchical and flat types?<\/h3><\/dt>\n<dd><p>Hierarchical types (like Pages) have parent\/child relationships and show a tree with a parents panel. Non-hierarchical types (like Posts) show a fast flat list without a Parent column.<\/p><\/dd>\n<dt id=\"will%201.6.0%20change%20my%20existing%20pages%20setup%3F\"><h3>Will 1.6.0 change my existing Pages setup?<\/h3><\/dt>\n<dd><p>No. Only Pages is managed by default, exactly as before. Additional post types appear only after you enable them in settings.<\/p><\/dd>\n<dt id=\"does%20this%20add%20database%20indexes%20to%20my%20site%3F\"><h3>Does this add database indexes to my site?<\/h3><\/dt>\n<dd><p>Yes. It adds a small number of composite and FULLTEXT indexes to wp_posts and wp_postmeta to make search and sorting fast. They are created lazily, one per request, so activation is instant and no request runs long enough to time out.<\/p><\/dd>\n<dt id=\"does%20it%20work%20without%20the%20indexes%3F\"><h3>Does it work without the indexes?<\/h3><\/dt>\n<dd><p>Yes. Until the indexes finish building, search falls back to a bounded, basic mode. Everything else works normally.<\/p><\/dd>\n<dt id=\"which%20capability%20is%20required%3F\"><h3>Which capability is required?<\/h3><\/dt>\n<dd><p>Each managed post type is checked against its own edit capability on every REST route (for pages that is edit_pages). Private entries are only shown to users who can read them, and per-item edit and delete actions are checked individually.<\/p><\/dd>\n<dt id=\"does%20it%20modify%20my%20content%3F\"><h3>Does it modify my content?<\/h3><\/dt>\n<dd><p>No. Read operations never load post content into PHP. Edit and bulk actions use standard WordPress functions and respect per-item capabilities.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.6.0<\/h4>\n\n<ul>\n<li>New: custom post type support. Choose which post types PageScale manages from a new Settings &gt; PageScale screen.<\/li>\n<li>New: each managed post type gets its own Scalable Manager screen, with a post-type switcher when more than one type is managed.<\/li>\n<li>New: automatic tree-vs-flat view. Hierarchical types keep the parent\/child tree; non-hierarchical types get the fast flat list.<\/li>\n<li>Improved: duplicate now inherits the source item's post type and copies that type's taxonomies.<\/li>\n<li>Improved: total and parents caches are keyed per post type to avoid cross-type stale counts.<\/li>\n<li>Improved: permission checks validate against each post type's own capabilities.<\/li>\n<li>Fix: duplicating an Elementor page no longer corrupts its layout (meta is now copied with correct slashing, and per-post builder CSS caches are regenerated for the copy).<\/li>\n<li>Fix: a duplicated page now gets a unique slug (e.g. privacy-policy-2) while the original page keeps its slug unchanged.<\/li>\n<li>Fix: quick edit saves are slashed correctly and report a clear error if a page builder hook fails, instead of silently not saving.<\/li>\n<li>Fix: permanently deleting from trash now verifies the result and recovers when a corrupted builder payload blocks deletion.<\/li>\n<li>Fix: quick edit and drag-and-drop reparenting now save over POST instead of PATCH, which some hosting stacks (LiteSpeed\/ModSecurity) block at the server level, making saves silently fail.<\/li>\n<li>Fix: the virtual-scroll repaint no longer resets an open quick edit form, which silently discarded typed changes (title, status, terms) before saving.<\/li>\n<li>Fix: taxonomy term changes in quick edit now save (the capability check used a non-existent capability name and always failed).<\/li>\n<li>Fix: the Scalable Manager submenu now attaches correctly under the built-in Posts menu.<\/li>\n<li>Pages behaviour is unchanged by default; existing installs see no difference until additional types are enabled.<\/li>\n<\/ul>\n\n<h4>1.5.1<\/h4>\n\n<ul>\n<li>Security: apply private-page readability filtering to the \/parents, \/export and \/default-view REST endpoints so private pages a user cannot read are never exposed, including by direct ID.<\/li>\n<li>Cache the parents list per user to avoid serving one user's readable set to another.<\/li>\n<\/ul>\n\n<h4>1.5.0<\/h4>\n\n<ul>\n<li>Initial public release: keyset pagination, lazy tree, tiered FULLTEXT search, virtual scrolling.<\/li>\n<li>Duplicate finder for titles, exact slugs and similar slugs.<\/li>\n<li>CSV export with formula-injection guarding.<\/li>\n<li>Lazy, timeout-safe index building with a WP-CLI command.<\/li>\n<\/ul>","raw_excerpt":"Fast admin manager for sites with tens of thousands of pages or custom post type entries: lazy tree, virtual scroll, keyset pagination, indexed FULLTE &hellip;","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/mr.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/357236","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mr.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/mr.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/mr.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=357236"}],"author":[{"embeddable":true,"href":"https:\/\/mr.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/shahzeb2u"}],"wp:attachment":[{"href":"https:\/\/mr.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=357236"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/mr.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=357236"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/mr.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=357236"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/mr.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=357236"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/mr.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=357236"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/mr.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=357236"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}