1

I've been Googling for an answer to this and have yet to find much of use. I have seen plugins that will say "pick the page for showing X" and "pick the page for showing y". Then if the page is example.com/mypage1 they can do things like example.com/mypage1/subset/detail/finedetail. What I want to know is how I can do this with one of my plugins?

I am thinking of a specific use case where a plugin might have a lot of data to show via the front end. I know some use a shortcode to output but not all. Some seem to use the page as the building block for their permalink structure. I want to do that too.

1

You are asking a couple of things in one question. Before we sort things out, let's get straight to the point:

You are looking for the template_include hook.

It is the hook, which is lastly called before the final output. In this phase, WordPress decides which template to pick.

To achive your goal, you need to deal with the following hooks:

  1. template_include
  2. add_rewrite_rule
  3. Knowing how to save values in some way or the other..

So, what you can do is, set up an options page in your plugin, add a field/option, and grab the page id, which you have saved before in your option, like this:

<?php

// In your options page, add a value/field
if (!empty( $options['your_data_template'] ) ) {
    $options['your_data_template'] = sanitize_text_field( $options['your_data_template'] );
}
?>

There are many ways to save options one way or the other.

This is the code which lists all pages in the backend:

<?php $value = get_option('your_data_template'); ?>
<select class="custom-select" name="options[your-data-template]">
<?php

    // create a variable that holds all pages (array)
    $pages = get_pages();
    // Then loop over it to list all pages as a select option.
    foreach ($pages as $page) {
    ?>
    <option value="<?php echo $page->ID; ?>" <?php selected( $value, $page->ID, true ); ?>>
       <?php echo $page->post_title; ?></option> 
   <?php } ?>
</select>

Then, add a file, and include it in your plugin's main file, name it as you like, but I'd recommend something like template-include.php or something.

<?php
// In the template include hook, grab the option and do a simple if statement to check
function wpse_check_template(){

    // Grab the value from the database and compare
    $your_data_page = get_option('your_data_template');

    // This is where you intercept the template hierarchy and trigger your own
    if(is_page($your_data_page){

        // if there is a file in the theme directory, use that
        if (file_exists( trailingslashit( get_template_directory() ) . 'your-data-template.php' ) ) {
            return trailingslashit( get_template_directory() ) . 'your-data-template.php';

        // In case, there is no template in the theme folder, look in the plugins folder "templates"..
        } else {
            return plugin_dir_path( __FILE__ ) . 'templates/your-data-template.php';
        }
    }
}
add_action('template_include', 'wpse_check_template');

I've only added a few lines of code for the settings etc. The trick is to find the right hook (template_include) kick in your own template at the right moment. In case you stumble accross the following somewhere else: Please do not use the hook, "template_redirect" - as the name suggests - it is to reeeeedirect, not to include.

I hope this gives you an idea about how it could work. I did not test this code, but it is an approach that should work.

The deeper url structure you asked for requires some advanced knowledge with the "add_rewrite_rule" action. There are also a lot of topics about that. See here one example. Add Rewrite Rule for custom page

In case it helped you solving your issue, feel free accept the answer as correct, thank you.

| improve this answer | |

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.