Somewhere off of the homepage we need to show a container page which does some stuff with custom post types. Actually it doesn't matter what it does, my point is it needs to exist and be reachable from the homepage menu.

We have done this before and created a WordPress "page" to operate as a container page and then in the theme/backend/PHP created a page-xxx.php which is where all the work of being a container happens and that ... sort of ... works.

But it does mean there's this useless "page" in the WordPress admin menu, which we have to instruct the client not to edit as "it's not a real page, just a placeholder" and mostly that's fine. But it's not ideal.

I know we can hide the placeholder page from the client. But is there a less kludgy solution?

Can we have a page in PHP with code to do a specific job and be able reach that code as a slug/address without actually the page existing as a page in admin?

  • Wrong approach from my point of view. In most cases all you need is to use the template files archive-{custom-post-type}.php and manipulate de output using pre_get_posts action hook. Even, depending of the exact need, you may use generic archive.php template and use only pre_get_posts action hook. Maybe with a rewrite endpoint or query var if you need a different URL from the standard archive and the modified one. If you give more information about the some stuff you need to do I can give you some example.
    – cybmeta
    Jan 2, 2015 at 19:00
  • Sounds like a custom menu or even a custom walker (but I think a custom walker might be a bit overboard) Jan 2, 2015 at 20:00
  • @cybmeta "some stuff", well, it has to list them really, in a fancy menu. what would be the url to reach this archive page?
    – hawbsl
    Jan 5, 2015 at 9:47
  • @cybmeta see my later question wordpress.stackexchange.com/q/173962/875. Basically, your comment showed me the way forward.
    – hawbsl
    Jan 5, 2015 at 10:19

5 Answers 5


Well, inside your directory just keep a normal php file like my-page.php, and then create a vanity URL for it using .htaccess. Open your .htaccess file (if present in the nstallation directory) or create one

RewriteEngine On
RewriteRule ^my-page-slug my-page.php

Should be good


if you want to access WP posts and other objects, you must include "wp-load.php" and you can access regular $wpdb or $WP_query object. Here's some sample code


include_once ("wp-load.php");

$posts = get_posts();
foreach($posts as $post){
    echo $post->post_name;
    echo "<hr/>";
  • can i still use the WordPress loop, all the functions etc inside this non-WP php page?
    – hawbsl
    Jan 2, 2015 at 18:43
  • I've updted my answer. So refresh this page and see the update to understand how you can do that in this external php file Jan 2, 2015 at 18:51

When I need a custom php page that works with Wordpress, generally I do this:

  1. I add a query variable to variables permitted by Wordpress:

    add_filter( 'query_vars', 'myplugin_add_query_var' );
    function myplugin_add_query_var( $query_vars ){
       $query_vars[] = 'myplugin_page_name';
  2. I add a function to parse_request action that check if is set the variable previously declared.

     add_action( 'parse_request', 'myplugin_front_controller' );
     function myplugin_front_controller( $query ){
        if( array_key_exists( 'myplugin_page_name', $query->query_vars ) ){
  3. I wrap in a function the code that I would have written in the php page

     function myplugin_dosomething(){
         echo 'Hello World';

Note that I really don't know if this is a good practice.
However before doing all this work I consider if it is not implementable using AJAX.


How about creating a custom page template for the front page and insert your custom queries and stuff there? You could assign those page-templates to all sort of pages. Use something like front-page.php, home.php or custom.php (Link) So you would have your normal homepage in the backend but in the frontend it will shown with your additional modules. With that approach you could add custom fields (eg: with ACF) for that specific page-template too.

Edit: Create a custom page template: custom-template.php

 * Template Name: Custom Homepage


    if ( have_posts() ):

        while ( have_posts() ): the_post();

            get_template_part( 'template-parts/content', get_post_type() );


// Add your custom module
get_template_part( 'template-parts/your-custom-stuff' );


.. and then assign the created template (page-attributes) on the page you want


Keep it very simple. Create a wordpress template and use that to display all your custom post content and other features. That way if the user chooses the template and adds some content blocks they won't break anything it will just look odd when they publish.


You can create a custom post type with register_post_type() function with false as show_ui parameter like this.

//code is taken from codex
//custom post type name is book here. Change the post type name and other options as your need
//Set `show_ui` and `show_in_menu` false
add_action( 'init', 'codex_book_init' );
function codex_book_init() {
$labels = array(
    'name'               => _x( 'Books', 'post type general name', 'your-plugin-textdomain' ),
    'singular_name'      => _x( 'Book', 'post type singular name', 'your-plugin-textdomain' ),
    'menu_name'          => _x( 'Books', 'admin menu', 'your-plugin-textdomain' ),
    'name_admin_bar'     => _x( 'Book', 'add new on admin bar', 'your-plugin-textdomain' ),
    'add_new'            => _x( 'Add New', 'book', 'your-plugin-textdomain' ),
    'add_new_item'       => __( 'Add New Book', 'your-plugin-textdomain' ),
    'new_item'           => __( 'New Book', 'your-plugin-textdomain' ),
    'edit_item'          => __( 'Edit Book', 'your-plugin-textdomain' ),
    'view_item'          => __( 'View Book', 'your-plugin-textdomain' ),
    'all_items'          => __( 'All Books', 'your-plugin-textdomain' ),
    'search_items'       => __( 'Search Books', 'your-plugin-textdomain' ),
    'parent_item_colon'  => __( 'Parent Books:', 'your-plugin-textdomain' ),
    'not_found'          => __( 'No books found.', 'your-plugin-textdomain' ),
    'not_found_in_trash' => __( 'No books found in Trash.', 'your-plugin-textdomain' )

$args = array(
    'labels'             => $labels,
    'public'             => true,
    'publicly_queryable' => true,
    'show_ui'            => false,
    'show_in_menu'       => false,
    'query_var'          => true,
    'rewrite'            => array( 'slug' => 'book' ),
    'capability_type'    => 'post',
    'has_archive'        => true,
    'hierarchical'       => false,
    'menu_position'      => null,
    'supports'           => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' )

register_post_type( 'book', $args );

In this way, it won't be shown in the admin menu. But you can still use it with url like this example.com/wp-admin/edit.php?post_type=book.

You can create separate template single-book.php to display it as you like. You can also create separate file with the id as you did with page.

If you have group of files which fall in the same category, you can use register_taxonomy() to create a taxonomy and use different templates for these groups of pages.

I believe this fulfill all your requirements:

  • It isn't shown in Admin menu.
  • You can use all wordpress functions
  • Create separate php code for each of the page(or group of page if you need, with custom taxonomy)

Your Answer

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

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