Building 24 Pages That Don’t Exist in the Database
November 19, 2025 • Bojan
November 19, 2025 • Bojan

Yes, you read that correctly.
Everyone “knows” WordPress stores pages in wp_posts.
Everyone also accepts the slow queries, the meta bloat, the accidental deletions, the import/export nightmares.
I don’t.
For a SaaS dashboard with 24 different admin screens, relying on database pages is basically architectural self-harm.
So I stopped doing it.
Instead of creating pages in the database…
I just don’t.
I intercept routing before WordPress does anything:
add_action('template_redirect', function() {
$path = trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/');
$virtual_pages = [
'app/orders' => 'virtual-pages/all-orders.php',
'app/samples' => 'virtual-pages/all-samples.php',
// ... 20 more
];
if (isset($virtual_pages[$path])) {
global $wp_query;
$wp_query->is_404 = false;
$wp_query->is_page = true;
include get_template_directory() . '/' . $virtual_pages[$path];
exit;
}
});
No posts table.
No queries.
No revisions.
No “who deleted the page?” mysteries.
Just pure, clean routing.
Database pages:
SELECT * FROM wp_posts...
SELECT * FROM wp_postmeta...
Virtual pages:
0 queries.
Just vibes.
virtual-pages/
├── all-orders.php
├── order-details.php
└── edit-sample.php
You edit, commit, deploy.
Your UI is in Git, where it belongs.
Users can’t delete a page that doesn’t exist.
End of problem.
You’re no longer “using WordPress.”
You’re building an app that happens to run on WordPress.
<?php
/**
* Virtual pages loader for WordPress
*
* - Treats PHP files in a folder (e.g. /virtual-pages) as "pages"
* - No entries in wp_posts
* - Works on subdirectory installs (https://example.com/subsite/app/orders)
*
* Usage:
* 1. Put your virtual page templates in: wp-content/themes/your-theme/virtual-pages/
* 2. Create a wrapper template: wp-content/themes/your-theme/virtual-page-wrapper.php
* 3. This class will route /slug to virtual-pages/slug.php
*/
if ( ! class_exists( 'BV_Virtual_Pages_Loader' ) ) {
class BV_Virtual_Pages_Loader {
/**
* Folder (inside the theme) that contains virtual page templates.
*
* @var string
*/
protected $folder;
/**
* Map of slug => file path.
*
* @var array
*/
protected $slugs = [];
/**
* Currently requested virtual page slug (if any).
*
* @var string|null
*/
protected $current_slug = null;
/**
* @param string $folder Relative folder inside the theme (no leading slash).
*/
public function __construct( $folder = 'virtual-pages' ) {
$this->folder = trim( $folder, '/' );
add_action( 'init', [ $this, 'scan_files' ] );
add_filter( 'template_include', [ $this, 'intercept_request' ], 99 );
// Keep titles consistent for virtual pages.
add_filter( 'the_title', [ $this, 'maybe_override_title' ], 10, 2 );
add_filter( 'get_the_title', [ $this, 'maybe_override_title' ], 10, 2 );
}
/**
* Scan the virtual pages folder and register all *.php files as slugs.
*/
public function scan_files() {
$directory = trailingslashit( get_stylesheet_directory() ) . $this->folder;
if ( ! is_dir( $directory ) ) {
return;
}
foreach ( glob( $directory . '/*.php' ) as $file ) {
$slug = basename( $file, '.php' );
$this->slugs[ $slug ] = $file;
}
}
/**
* Get the current request path converted to a slug.
*
* Handles subdirectory installs like /my-site/app/dashboard.
*
* @return string
*/
protected function get_requested_slug() {
$request_uri = parse_url( $_SERVER['REQUEST_URI'] ?? '', PHP_URL_PATH );
$site_path = parse_url( home_url(), PHP_URL_PATH );
if ( $request_uri === null ) {
$request_uri = '';
}
if ( $site_path === null ) {
$site_path = '';
}
// Strip the site base path (for subdirectory installs).
if ( $site_path !== '/' && $site_path !== '' && $request_uri !== '' && strpos( $request_uri, $site_path ) === 0 ) {
$request_uri = substr( $request_uri, strlen( $site_path ) );
}
return trim( $request_uri, '/' );
}
/**
* Intercept the template resolution and route to a virtual page if it matches.
*
* @param string $template Default template path.
* @return string
*/
public function intercept_request( $template ) {
$requested_slug = $this->get_requested_slug();
$this->current_slug = $requested_slug;
if ( isset( $this->slugs[ $requested_slug ] ) ) {
// Mark as a valid page, not a 404.
status_header( 200 );
global $wp_query;
$wp_query->is_404 = false;
$wp_query->is_page = true;
// Browser <title>.
add_filter(
'document_title_parts',
function ( $parts ) use ( $requested_slug ) {
$parts['title'] = $this->humanize_slug( $requested_slug );
return $parts;
}
);
// Let title functions know we're on a virtual page.
$GLOBALS['virtual_page_slug'] = $requested_slug;
// Wrapper template: can include header/footer and then load the actual page.
$wrapper = trailingslashit( get_stylesheet_directory() ) . 'virtual-page-wrapper.php';
if ( file_exists( $wrapper ) ) {
return $wrapper;
}
// Fallback: load the virtual page template directly.
return $this->slugs[ $requested_slug ];
}
return $template;
}
/**
* Override the_title() / get_the_title() for virtual pages.
*
* @param string $title
* @param int|string $post_id
* @return string
*/
public function maybe_override_title( $title, $post_id = null ) {
if ( isset( $GLOBALS['virtual_page_slug'] ) && ! is_admin() ) {
return $this->humanize_slug( $GLOBALS['virtual_page_slug'] );
}
return $title;
}
/**
* Get the current virtual slug (optional helper for wrappers).
*
* @return string|null
*/
public function get_current_slug() {
return $this->current_slug;
}
/**
* Convert a slug like "app-orders" to "App Orders".
*
* @param string $slug
* @return string
*/
protected function humanize_slug( $slug ) {
return ucwords( str_replace( '-', ' ', $slug ) );
}
}
// Bootstrap: create loader instance once the theme is ready.
add_action(
'after_setup_theme',
function () {
new BV_Virtual_Pages_Loader( 'virtual-pages' );
}
);
}
You can pair this with a simple virtual-page-wrapper.php like:
<?php
// virtual-page-wrapper.php
get_header();
$slug = isset( $GLOBALS['virtual_page_slug'] ) ? $GLOBALS['virtual_page_slug'] : '';
if ( $slug ) {
$file = trailingslashit( get_stylesheet_directory() ) . 'virtual-pages/' . $slug . '.php';
if ( file_exists( $file ) ) {
include $file;
} else {
echo '<p>Virtual page not found.</p>';
}
}
get_footer();My system has:
All inside one folder:
virtual-pages/
├── scan.php
├── manager-dashboard.php
├── create-order.php
└── system-settings.php
Not a single database page.
Deployment is just Git push.
Use it when:
You’re building a SaaS or dashboard
Pages are interface, not “content”
You want Git over database
You want speed
You hate WordPress menus
Avoid it when:
You need the WP editor
Clients manage content
SEO matters
Comments/revisions matter
WordPress is not an app framework.
But you can bend it.
Hard.
Application pages don’t belong in wp_posts.
They belong in code.
24 pages.
0 posts.
0 database problems.
Maximum control.
Use this pattern and you stop fighting WordPress – you make it work for you.

I’m Bojan Josifoski - I’m a WordPress systems engineer who developed and maintained a proprietary WordPress-based framework used by U.S. financial institutions between 2016 and 2025.