If you need to create a custom URL Path (rewrite) it’s easy enough to  just create the page in the admin and create a custom shortcode that will output the HTML that you want.  However, you would not be able to properly re-theme this output so a preferred method is to create a URL rewrite that will automatically pull a custom template file that can be customized in a theme as needed.

Create URL Path Rewrites

After you add or update a rewrite you need to flush the rewrites. This can be done programmatically using flush_rewrite_rules() or manually by going to the Settings > Permalinks page and saving the page there (no changes needed). The save function will issue a flush of the rewrite rules.

/**
 * URL Rewrites
 */
function my_rewrite()
{
    global $wp_rewrite;
    add_rewrite_rule('pets/?$', 'index.php?my_page=pet', 'top');
    add_rewrite_rule('pets/(\d+)/?$', 
        sprintf(
            'index.php?my_page=pet&pet_id=%s',
            $wp_rewrite->preg_index(1)
        ), 'top');
}
 
add_action('init', 'my_rewrite');

Template File Redirect

This handles getting the overridden file in a theme or falls back to your copy in your plugin.

/**
 * Set templates for custom pages
 *
 * @see http://stackoverflow.com/questions/4647604/wp-use-file-in-plugin-directory-as-custom-page-template
 */
function my_theme_redirect()
{
    $plugindir = dirname(__FILE__);
    $prefix = 'myprefix'; // Set custom prefix for each plugin to prevent conflicts
    $theme_files_dir = 'theme-files'; // Sub directory in your plugin to put all your template files
 
    $page = get_query_var('my_page');
    $pet_id = (int)get_query_var('pet_id', 0);
 
    if ($page == 'pet' && empty($pet_id)) {
 
        // Pet Archive
        $data = array( // Data you can pass to the template
            'pets' => array(
                array('name' => 'Fluffy', 'species' => 'dog'),
                array('name' => 'Spot', 'species' => 'cat'),
            ),
            'action' => 'my_action'
        );
        $filename = 'archive-pet.php'; // filename of template
        $full_template_path = TEMPLATEPATH . DIRECTORY_SEPARATOR . $prefix . DIRECTORY_SEPARATOR . $filename;
        $return_template = (file_exists($full_template_path)) ? $full_template_path 
            : $plugindir . DIRECTORY_SEPARATOR . $theme_files_dir . DIRECTORY_SEPARATOR . $filename;
        do_my_theme_redirect($return_template, true, $data);
 
    } elseif ($page == 'pet' && !empty($pet_id)) {
 
        // Single Pet
        $data = array( // Data you can pass to the template
            'pet' => array('name' => 'Fluffy', 'species' => 'dog'),
        );
        $filename = 'single-pet.php'; // filename of template
        $full_template_path = TEMPLATEPATH . DIRECTORY_SEPARATOR . $prefix . DIRECTORY_SEPARATOR . $filename;
        $return_template = (file_exists($full_template_path)) ? $full_template_path 
            : $plugindir . DIRECTORY_SEPARATOR . $theme_files_dir . DIRECTORY_SEPARATOR . $filename;
        do_my_theme_redirect($return_template, true, $data);
 
    }
}
 
/**
 * Process theme redirect
 *
 * @param mixed $path
 * @param bool  $force force redirect regardless of have_posts()
 * @param array $data vars to set for theme
 */
function do_my_theme_redirect($path, $force = false, $data = array())
{
    global $wp_query;
 
    if (have_posts() || $force) {
        if (!empty($data)) extract($data);
        include($path);
        die();
    } else {
        $wp_query->set_404();
        status_header(404);
    }
}
 
add_action('template_redirect', 'my_theme_redirect');

Register Custom Query Variables

If you need to use any custom query variables such as “my_page” and “pet_id” in the example above, you need to register them.

/**
 * Register custom query vars
 *
 * @param array $vars The array of available query variables
 *
 * @return array
 *
 * @link https://codex.wordpress.org/Plugin_API/Filter_Reference/query_vars
 */
function my_register_query_vars($vars)
{
    $vars[] = 'my_page';
    $vars[] = 'pet_id';
    return $vars;
}
 
add_filter('query_vars', 'my_register_query_vars');
4.3 3 votes
Article Rating
in WordPress
Subscribe
Notify of
guest
1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Mohammad
Mohammad
3 years ago

very very goooooood ๐Ÿ˜˜๐Ÿ˜˜๐Ÿ˜˜