I'm working on a plugin that adds custom templates to WordPress for use with the active theme. The template files are located in a plugin directory and are being passed into WordPress with the theme_templates
hook.
What's stumping me is one small variation in an if statement results in the REST API returning an error when firing WP_REST_Posts_Controller::check_template(). The error is only present in the block editor as the classic editor bypasses the REST API check.
This is my function.
public function add_custom_templates($templates)
{
global $post_type;
/**
* Collect an array of templates files
*/
$templates = $this->template_files();
foreach ($templates as $template) {
/**
* Get header info from template file to parse template name and post type(s)
*/
$data = get_file_data( MY_TEMPLATES_PATH . $template, array(
'name' => 'Template Name',
'post_type' => 'Template Post Type'
));
// remove spaces if present
$trimmed = str_replace(' ', '', $data['post_type']);
//convert template data post type string to array
$post_types = explode(',', $trimmed);
// THIS WORKS <---
if (!empty($data['name']) && !empty($data['post_type'])) {
$custom_templates[$template] = $data['name'];
}
// THIS DOES NOT WORK <---
// if (!empty($data['name']) && !empty($data['post_type']) && in_array($post_type, $post_types)){
// $custom_templates[$template] = $data['name'];
// }
}
// manual override
$custom_templates['example.php'] = 'fake template';
return $custom_templates;
}
}
Let's assume $templates = array('one.php', two.php, three.php')
one.php
has the following comment block below the opening tag
/*
* Template Name: Template One
* Template Post Type: post, page
*/
two.php
has the following comment block below the opening tag
/*
* Template Name: Template Two
* Template Post Type: post, product
*/
three.php
has the following comment block below the opening tag
/*
* Template Name: Template Three
* Template Post Type: page, product
*/
This working if statement returns all templates and allows for saving/updating inside the block editor without errors from the REST API
if (!empty($data['name']) && !empty($data['post_type'])) {
$custom_templates[$template] = $data['name'];
}
$custom_templates returns the following array: array(4) { ["one.php"]=> string(12) "Template One" ["two.php"]=> string(12) "Template Two" ["three.php"]=> string(14) "Template Three" ["example.php"]=> string(13) "fake template" }
However, that statement results in all 3 templates being accessible no matter the post type. I'm wanting to only include a template if the $data['post_type'] matches the global $post_type for the given post.
This if statement is supposed to limit it as per my intent.
if (!empty($data['name']) && !empty($data['post_type']) && in_array($post_type, $post_types)){
$custom_templates[$template] = $data['name'];
}
When running just the second if statement on a "page", $custom_templates returns the following array:array(3) { ["one.php"]=> string(12) "Template One" ["three.php"]=> string(14) "Template Three" ["example.php"]=> string(13) "fake template" }
*No matter which if statement is used, the manual override I added as a temporary sanity check is able to be selected and saved despite the lack of an actual file existing.
When running the if statement with in_array($post_type, $post_types)
it correctly returns the templates I'm wanting to return, but any attempt to select and save that template inside the block editor results in the REST API kicking back the error "Updating failed. Invalid parameter(s): template".
Any help would be greatly appreciated as I'm stumped why the REST API is blocking the request *only when adding the extra check to my if statement.