I need to create a frontend page (and sub-pages) which will display custom data that is saved in the database but is not part of wordpress, it is not a post or page as such but API called data. I do not want to use a short code because of the need of sub-pages.

I have looked at the following but don't seem to be able to make it work as required: Dynamic URL, not a physical page within the database

What I need is to have for example site.com/mypage/ but I do not want 'mypage' to exist in the backend.

I have achieved this with:

public function mypage_rewrite_ext() {
    global $wp_rewrite;
    $plugin_url = plugins_url( 'mypage.php', __FILE__ );
    $plugin_url = substr( $plugin_url, strlen( home_url() ) + 1 );
    // The pattern is prefixed with '^'
    // The substitution is prefixed with the "home root", at least a '/'
    // This is equivalent to appending it to `non_wp_rules`
    $wp_rewrite->add_external_rule( 'mypage$', $plugin_url );

But I need my page to still be within WordPress as I need to use the header and footer.

I have tried the following from the above linked question, but this just redirects to the home page (even after re-saving permalinks):

public function add_query_vars( $query_vars )
    $query_vars[] = 'test';
    return $query_vars;

public function add_endpoint()
    add_rewrite_rule('^mypage/?', 'index.php?__test=1', 'top');
    flush_rewrite_rules(false); //// <---------- REMOVE THIS WHEN DONE

public function sniff_requests($wp_query)
    global $wp;

    if(isset($wp->query_vars[ '__test' ])) {
        add_filter('template_include', function ($original_template) {

            // change the default template to a google map template
            return plugin_dir_path( __FILE__ ) . 'mypage.php';

Any ideas on 1) what I am doing wrong and/or 2) how I can achieve this?

This is the result from the analyser: enter image description here

  • Just curious, why are you averse to having actual WP 'pages' for these? You could assign them each a custom Page template that pulls in your non-WP data (as well as WP header/footer) and note in the content editor that the page content is controlled in the theme, not in content editor.
    – WebElaine
    Apr 13, 2017 at 15:39
  • Because it's going to be a custom hierarchy for 1000's of items, so I don't want to have to make a page per one, or use a shortcode as I will need to eventually have /mypage/myotherpage/mylastpage/
    – Aravona
    Apr 13, 2017 at 15:41
  • Have you tested with monkeyman rewrite rules analyser plugin to verify that the URL you expected actually matches the rewrite rule? Note that you added test as a query variable, but you used instead __test which isn't the same
    – Tom J Nowell
    Apr 13, 2017 at 16:16
  • @TomJNowell I have it there but to be honest I'm not sure what to expect from it. See attached image (Just updating with the correct var as well, didn't notice that - which now make 'mypage' go to the archive page)
    – Aravona
    Apr 13, 2017 at 16:21
  • 1
    @Aravona Don't delete the question, answer it! Who knows who else might have the same issue but not spot the problem as you did
    – Tom J Nowell
    Apr 13, 2017 at 16:29

1 Answer 1


"What I need is to have for example site.com/mypage/ but I do not want 'mypage' to exist in the backend."

It's a bit late, but maybe someone else is in a need for this as well:

Step 1
Create /templates/ folder inside your plugin, and create custom.php file inside of it, with temporary content for testing purposes such as

echo "Hi";

Step 2
Add this code to your plugin:

add_filter( 'generate_rewrite_rules', function ( $wp_rewrite ){
    $wp_rewrite->rules = array_merge(
        ['mypage/?$' => 'index.php?custom=1'],
} );
add_filter( 'query_vars', function( $query_vars ){
    $query_vars[] = 'custom';
    return $query_vars;
} );
add_action( 'template_redirect', function(){
    $custom = intval( get_query_var( 'custom' ) );
    if ( $custom ) {
        include plugin_dir_path( __FILE__ ) . 'templates/custom.php';
} );

Please note that plugin_dir_path( __FILE__ ) may not be appropriate function for your case, depending on where you will add this code.

Step 3
Go to WP admin -> Settings -> Permalinks and re-save them, to flush/recreate permalinks.

Step 4
Try to visit yoursite.com/mypage.
Clear your browser cache / history, or maybe even try incognito/different browser.

Step 5
Remove the testing code from custom.php file and add your own backend code.

  • 1
    This works 100%. Thanks for posting.
    – E Benzle
    Jan 18, 2022 at 20:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.