How to Add Page Template from Plugin without Losing $this

Background

I am trying to add page templates from inside of a plugin. For this question, I have trimmed my code down into a test plugin which has two files, the PHP main plugin file, and a PHP template file.

wp-plugins/test-plugin/test-plugin.php

wp-plugins/test-plugin/templates/test-template.php

The plugin has two pieces. First off, I tap into the template_include filter, and I return the path to the template file (test-template.php).

Next, I have a new extension of Walker_Page, called Walker_Page_New in this example. In the file, it is a word for word copy of Walker_Page.

Current Code

test-plugin.php

<?php

/**
 * Plugin Name: Test Plugin
 * Version: 1.0
 * Author: Andy Mercer
 * Author URI: http://www.andymercer.net
 * License: GPL2
 */ 

add_filter( 'template_include', 'test_get_template' );

function test_get_template( $template ) {

    $template_path = plugin_dir_path( __FILE__ ) . 'templates/test-template.php';

    if ( file_exists( $template_path ) ) {

        $template = $template_path;

    }

    return $template;

}


class Walker_Page_New extends Walker_Page {

    // THE CODE IN HERE IS AN EXACT COPY OF WALKER_PAGE

    // I AM NOT ENTERING IT ALL IN THIS QUESTION BECAUSE IT'S A COUPLE HUNDRED LINES OF CODE

}

test-template.php

<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
    <head>
        ...head stuff...
    </head>
    <body>
        <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
        <div>
            <?php $ancestors = get_ancestors( get_the_ID(), 'page' );
            wp_list_pages([
                'title_li' => '',
                'sort_column' => 'menu_order',
                'child_of' => $ancestors[0],
                'depth' => 2,
                'walker' => 'Walker_Page_New',
            ]); ?>
        </div>
        <div>
            <?php the_title(); ?>
            <?php the_content() ?>
        </div>
        <?php endwhile; endif; ?>
        <?php wp_footer(); ?>
    </body>
</html>

Problem

When I then load the page, I only get this error:

Fatal error: Uncaught Error: Using $this when not in object context in C:…\wp-includes\class-wp-walker.php:199

What is triggering this error is the call to wp_list_pages() with a custom Walker. When I remove the Walker, I am fine and everything works as expected.

Research

From looking around, the only specific mention of this I have found is semi-related here: https://github.com/Automattic/amp-wp/issues/412#issuecomment-240871878, where it’s stated that using template_include will cause this:

e.g. we would no longer have the $this context in the templates

Question

Is it expected that using template_include will break stuff? Should I use template_redirect instead?

2 Answers
2

Your walker argument in wp_list_pages should be an instance, not a string.

'walker' => new Walker_Page_New()

Leave a Comment