WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I need to develop a plugin in which a special page needs to be created. This page will have a completely separate design from the rest of the website, and will be located at a specific URL.

I realize short codes are the "proper" way for a plugin to run itself on a page, but how would I go about actually over-riding the entire theme of the page and replace it with my own content? In this case, since it's a single page, I don't want to actually create an entire Wordpress theme-- I just need to be able to essentially start from a blank slate and I can just use my own HTML from there.

share|improve this question
Have you seen How to Rewrite Wordpress URL for a Plugin? – toscho May 24 '13 at 18:29
That looks perfect, but is there a way to only handle a single URL (e.g. /register versus /any-page/register) without manually checking the URL and returning if it doesn't match exactly? – Andrew M May 24 '13 at 18:58
Yes, use EP_ROOT instead of EP_PERMALINK. – toscho May 24 '13 at 19:00

Here's a slimmed-down version of what I usually do. Replace wpse100645 with whatever you want, but be respectful of the fact that you don't want to interfere with a site's content.

 * Create a custom path and process code when it gets triggered
 * @author Matthew Boynes

if ( !class_exists( 'WPSE_100645_Custom_Page' ) ) :

class WPSE_100645_Custom_Page {

    public function __construct() {
        # Add our query_var, 'wpse100645'
        add_filter( 'query_vars',    array( &$this, 'add_query_var' ) );

        # setup rewrite rules for our path
        add_action( 'init',          array( &$this, 'add_rewrite_rules' ), 5 );

        # We're doing this on parse_query to ensure that query vars are set
        add_action( 'parse_query',   array( &$this, 'dispatch_path' ) );

     * Add rewrite rules for our path
     * @return void
    public function add_rewrite_rules() {
        add_rewrite_rule( "wpse100645/?$", 'index.php?wpse100645=1', 'top' );

     * Add the class query var, wpse100645
     * @param array $qv The current query vars
     * @return array The modified query vars
    public function add_query_var( $qv ) {
        $qv[] = 'wpse100645';
        return $qv;

     * This is where the magic happens.
     * @uses WPSE_100645_Custom_Page::$paths
     * @return void
    public function dispatch_path() {
        if ( get_query_var( 'wpse100645' ) ) {

            # Do your magic here. You probably want to call another function to keep the code orthoginal.

            # Then, you'll want to...
            exit; # So that WordPress doesn't continue the rest of the chain

new WPSE_100645_Custom_Page();


What's happening here?

First, we're adding a query var, wpse100645 and we're adding a rewrite rule for that query var. This way, it will work whether the user has permalinks enabled or not, either at domain.com/?wpse100645=1 or at domain.com/wpse100645/.

Next, when parse_query fires, we check to see if our query var is present. If it is, we run whatever code we want and exit (see dispatch_path). Therefore, your plugin can render whatever HTML it wants, because no template files have loaded yet. It will be quite fast too, because the main query hasn't even run yet. This all fires pretty high up in the request chain. Note that if you don't exit, the homepage will render after your code does.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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