0

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 '15 at 19:00
  • Sounds like a custom menu or even a custom walker (but I think a custom walker might be a bit overboard) – Pieter Goosen Jan 2 '15 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 '15 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 '15 at 10:19
0

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

update

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

<?php
//path/to/your/wordpress/installation/my-page.php

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 '15 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 – Hasin Hayder Jan 2 '15 at 18:51
0

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 ) ){
          myplugin_dosomething();
          die();
        }
     }
    
  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.

-1

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, privacy policy and cookie policy

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