I have added page templates via plugin. It works absolutely fine with classic editor but while using Gutenberg, the page can not be published when page template is assigned. However, page templates added via theme works fine and page is saved as well. But page templates added via plugins creates issues as page cannot be published with those page templates (added via plugin) assigned.
This is how I have added page templates via plugin:
/**
* Destination template.
*/
function wpte_get_destination_template( $template ) {
$post = get_post();
$page_template = get_post_meta( $post->ID, '_wp_page_template', true );
if( $page_template == 'templates/template-destination.php' ){
$template_path = locate_template( array( 'template-destination.php' ) );
if(!$template_path)
{
$template_path = BASE_PATH . '/includes/templates/template-destination.php';
}
return $template_path;
}
return $template;
}
/**
* Destination template returned.
*/
function wpte_filter_admin_page_templates( $templates ) {
$templates['templates/template-destination.php'] = __( 'Destination Template','' );
return $templates;
}
/**
* Destination template added.
*/
add_action( 'wp_loaded', array( $this, 'wpte_add_destination_templates' ) );
function wpte_add_destination_templates() {
if( is_admin() ) {
add_filter( 'theme_page_templates', array( $this, 'wpte_filter_admin_page_templates' ) );
}
else {
add_filter( 'page_template', array( $this, 'wpte_get_destination_template' ) );
}
}
This is the error seen on console when 'Publish' button is pressed after selecting plugin's page templates:
{"code":"rest_invalid_param","message":"Invalid parameter(s): template","data":{"status":400,"params":{"template":"template is not one of templates\/about.php, templates\/contact.php, templates\/team.php, templates\/testimonial.php."}}}
All of these templates are of theme. Page templates added via plugin is not listed there. Though, they are available in the templates drop-down.
Any help would be more than appreciable.
I have added page templates via plugin. It works absolutely fine with classic editor but while using Gutenberg, the page can not be published when page template is assigned. However, page templates added via theme works fine and page is saved as well. But page templates added via plugins creates issues as page cannot be published with those page templates (added via plugin) assigned.
This is how I have added page templates via plugin:
/**
* Destination template.
*/
function wpte_get_destination_template( $template ) {
$post = get_post();
$page_template = get_post_meta( $post->ID, '_wp_page_template', true );
if( $page_template == 'templates/template-destination.php' ){
$template_path = locate_template( array( 'template-destination.php' ) );
if(!$template_path)
{
$template_path = BASE_PATH . '/includes/templates/template-destination.php';
}
return $template_path;
}
return $template;
}
/**
* Destination template returned.
*/
function wpte_filter_admin_page_templates( $templates ) {
$templates['templates/template-destination.php'] = __( 'Destination Template','' );
return $templates;
}
/**
* Destination template added.
*/
add_action( 'wp_loaded', array( $this, 'wpte_add_destination_templates' ) );
function wpte_add_destination_templates() {
if( is_admin() ) {
add_filter( 'theme_page_templates', array( $this, 'wpte_filter_admin_page_templates' ) );
}
else {
add_filter( 'page_template', array( $this, 'wpte_get_destination_template' ) );
}
}
This is the error seen on console when 'Publish' button is pressed after selecting plugin's page templates:
{"code":"rest_invalid_param","message":"Invalid parameter(s): template","data":{"status":400,"params":{"template":"template is not one of templates\/about.php, templates\/contact.php, templates\/team.php, templates\/testimonial.php."}}}
All of these templates are of theme. Page templates added via plugin is not listed there. Though, they are available in the templates drop-down.
Any help would be more than appreciable.
Share Improve this question edited Apr 12, 2019 at 9:55 saurav.rox asked Apr 11, 2019 at 5:08 saurav.roxsaurav.rox 2051 silver badge13 bronze badges 6 | Show 1 more comment1 Answer
Reset to default 1(Revised answer)
Gutenberg (or the Block Editor) uses the WordPress REST API when working with a Page/post (creating, updating, etc.) and the REST API will check whether the template is valid for the given post through WP_REST_Posts_Controller::check_template()
and when the template is not valid, the error template is not one of
will be thrown.
And as I (recently) stated in this answer:
By default, is_admin()
returns false
on a REST API endpoint/URL. So if for example you're on http://example/wp-json/wp/v2/posts
(or that you make API request to that endpoint), then:
if ( is_admin() ) {
// code here does **not** run
}
So that should answer the question, where in your wpte_add_destination_templates
function, the is_admin()
check fails and the custom template is not added to the list of valid/registered templates; and eventually results in the error template is not one of
.
Possible Solutions
Hook to both wp_loaded
and rest_api_init
add_action( 'wp_loaded', array( $this, 'wpte_add_destination_templates' ) ); // for admin requests
add_action( 'rest_api_init', array( $this, 'wpte_add_destination_templates' ) ); // for REST requests
And in the wpte_add_destination_templates
function:
// If REST_REQUEST is defined (by WordPress) and is a TRUE, then it's a REST API request.
$is_rest_route = ( defined( 'REST_REQUEST' ) && REST_REQUEST );
if (
( is_admin() && ! $is_rest_route ) || // admin and AJAX (via admin-ajax.php) requests
( ! is_admin() && $is_rest_route ) // REST requests only
) {
add_filter( 'theme_page_templates', array( $this, 'wpte_filter_admin_page_templates' ) );
}
Or hook directly to theme_page_templates
//add_action( 'wp_loaded', array( $this, 'wpte_add_destination_templates' ) ); // remove
add_filter( 'theme_page_templates', array( $this, 'wpte_filter_admin_page_templates' ) );
And then your wpte_filter_admin_page_templates
would be:
function wpte_filter_admin_page_templates( $templates ) {
// If it's an admin or a REST API request, then filter the templates.
if ( is_admin() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) {
$templates['templates/template-destination.php'] = __( 'Destination Template','' );
} // else, do nothing (i.e. don't modify $templates)
return $templates;
}
add_action( 'wp_loaded', $plugin_admin, 'wpte_add_destination_templates' );
is not valid. What is$plugin_admin
supposed to be? – Jacob Peattie Commented Apr 11, 2019 at 8:43