5

Basically I want to be able to see the names of files on the front-end - not just templates e.g. category/page templates, but the actual theme files like header.php/sidebar.php/footer.php and so on.

So I think the problem is what I've found so far doesn't have the depth I need and only goes as far as telling me what "template" is being used versus all the pieces that make up the "template".

I can't seem to find something that'll give me a PHP object for me var_dump and see what's available or a hook that I can manipulate. Does this actually exist or am I grasping for straws?

What I looked into so far:

  • How do you find out which template is serving the current page?

    t31os' answer is helpful, but it only goes as deep as the container template, so if I call his function in header.php, it will tell me page.php instead of header.php. In other words, I want to know the exact file my function is calling out from.

  • Get Name of Current Template File

    This is a similar issue as the first question, and still using t310s' answer as reference.

  • Also looked into the wp_get_theme function, but that object only gives me info about the theme itself, rather than an array or list of files.

My goal is to write a function that would dynamically echo out all the file names or pieces on what's being viewed on the front-end . So a "Page" would echo page.php, sidebar.php, footer.php and header.php for example.

Please no plugins, I'd like to resolve this with PHP. I get that this might not be a simple answer, but I'd like a starting point at the very least - or at least know if it's possible.

3 Answers 3

7

PHP has a function, get_included_files(), that returns all the files that have been included during a request.

However, if you use that function you obtain all the files required: WordPress core files, plugin files...

You need a way to:

  • Filter out files that do not belong to the theme and child theme (if any)
  • Include only files loaded after the main template has been included

Also you need to call this function as late as possible; shutdown would be the better hook, however, wp_footer should be fine, because it's rare that you include a file after that hook has been fired.

Regarding the 2 problems mentioned above, the first can be solved by filtering the array for files that only belong to the theme folder.

The second can be solved by using template_include, with a very low priority, to save the path of the main template, and then including in the output only files included after it.

Here's a class that implements what's said above. Put in a file and require from functions.php:

class IncludedPartGrabber
{    
    private $main;
    private $root;
    private $switch = false;

    public function setup( $template )
    {
        $this->root = wp_normalize_path( get_theme_root() ); // theme folder
        $this->main = wp_normalize_path( $template ); // main template

        return $template;
    }

    public function grab()
    {
        return array_filter( get_included_files(), array( $this, 'filter' ) );
    }

    private function filter( $file )
    {
        $norm =  wp_normalize_path( $file );
        if ( $norm === $this->main )
            $this->switch = TRUE; // after main template all files are good to be included

        return $this->switch && strpos( $norm, $this->root ) === 0; // true if file is in theme dir
    }
}

Use it like so, in your functions.php:

$grabber = new IncludedPartGrabber;

add_action( 'template_include', array( $grabber, 'setup' ) );

add_action( 'wp_footer', function() use($grabber) {
    echo '<pre>';
    print_r( $grabber->grab() ); // see your footer :)
    echo '</pre>';
} );

If you want to use inside a template file, in functions.php put:

global $grabber;
$grabber = new IncludedPartGrabber;

add_action( 'template_include', array( $grabber, 'setup' ) );

and then in the template file, e.g. footer.php:

<pre><?php print_r( $GLOBALS['grabber']->grab() ); ?></pre>

Of course you can use in header.php too, but from that file you'll get only the files loaded at the moment header.php has been included, e.g. page.php and header.php. PHP is a programming language, not a magic machine, and can't know which files are going to be included before they are actually included.

1
  • I like this solution because I don't have to use multiple functions to grab the header/footer/sidebar and then the general templates. It's all consolidated into one class and feels much cleaner. I've tried it out and I am getting all the templates printed in the footer. Of course I can re-work it so it's not printing out the array of paths - but this is a great start! Thanks so much!
    – RachieVee
    Nov 12, 2014 at 14:41
3

get_header, get_footer, and get_sidebar all have corresponding actions that pass the name as an argument, so you can hook those actions, test for their existence via locate_template and log the names.

get_template_part has an action, but it's dynamic and includes the slug, so unless you know the slugs, those will be difficult to hook. what you can do is hook all, and string match the first part of the action, get_template_part_, which is exactly what this What the File plugin does:

add_action( 'all', 'save_template_parts', 1, 3 );

function save_template_parts( $tag, $slug = null, $name = null ) {
    if ( 0 !== strpos( $tag, 'get_template_part_' ) ) {
        return;
    }

    // Check if slug is set
    if ( $slug != null ) {

        // Templates array
        $templates = array();

        // Add possible template part to array
        if ( $name != null ) {
            $templates[] = "{$slug}-{$name}.php";
        }

        // Add possible template part to array
        $templates[] = "{$slug}.php";

        // Get the correct template part
        $template_part = str_replace( get_template_directory() . '/', '', locate_template( $templates ) );
        $template_part = str_replace( get_stylesheet_directory() . '/', '', $template_part );

        // Add template part if found
        if ( $template_part != '' ) {
            // log $template_part
        }
    }

}
2
  • The locate_template function is only used in a conditional to find a file I specify, correct? And then if I have it hook into get_header, I have to write a function to display "header.php" on the front-end if locate_template for header.php returns true? Just trying to confirm I'm thinking about this right. Thanks. :-)
    – RachieVee
    Nov 11, 2014 at 21:55
  • yes, you're using locate_template strictly to see if templates exist. you don't have to do anything on the get_ hooks except test and log, those functions just trigger the actions and continue doing their thing on their own.
    – Milo
    Nov 11, 2014 at 22:02
0

Play along with:

echo '<ul><li>'.implode('</li><li>', str_replace(str_replace('\\', '/', ABSPATH).'wp-content/', '', array_slice(str_replace('\\', '/', get_included_files()), (array_search(str_replace('\\', '/', ABSPATH).'wp-includes/template-loader.php', str_replace('\\', '/', get_included_files())) + 1)))).'</li></ul>';

HTML-list with all template files in use for the current landing page, including all template-parts from plugins, child theme and/ or parent theme combinations, all in one line of code.

Written at:

How do you find out which template page is serving the current page?

if admin-bar stuff path is showing at the top, or any other file, change the filename template-loader.php in this line of code to: whatever filname you need to break from.

if you need this in the admin bar, use the right priotity (earliest) to make shure no files are entered at the end of this list. For example:

add_action('admin_bar_menu', 'my_adminbar_template_monitor', -5);

priority -5 make shure it loads first. The key is to render this line at the right moment.

Do some changes if your server using dubble-slashes.

Your Answer

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

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