Roots Discourse

Advice on Sage Filters and Detecting Post Templates

Hello,

I would like some general advice on a couple things:

  1. How would I best go about converting the below code to work inside Sage? I understand that things must be namespaced, but even when I try to namespace the below it fails.

    Ref: https://www.billerickson.net/disabling-gutenberg-certain-templates/

<?php
/**
 * Disable Editor
 *
 * @package      ClientName
 * @author       Bill Erickson
 * @since        1.0.0
 * @license      GPL-2.0+
**/

/**
 * Templates and Page IDs without editor
 *
 */
function ea_disable_editor( $id = false ) {

	$excluded_templates = array(
		'templates/modules.php', // I also assume "my-template.blade.php" will fail here
		'templates/contact.php'
	);

	$excluded_ids = array(
		// get_option( 'page_on_front' )
	);

	if( empty( $id ) )
		return false;

	$id = intval( $id );
	$template = get_page_template_slug( $id );

	return in_array( $id, $excluded_ids ) || in_array( $template, $excluded_templates );
}

/**
 * Disable Gutenberg by template
 *
 */
function ea_disable_gutenberg( $can_edit, $post_type ) {

	if( ! ( is_admin() && !empty( $_GET['post'] ) ) )
		return $can_edit;

	if( ea_disable_editor( $_GET['post'] ) )
		$can_edit = false;

	return $can_edit;

}
add_filter( 'gutenberg_can_edit_post_type', 'ea_disable_gutenberg', 10, 2 );
add_filter( 'use_block_editor_for_post_type', 'ea_disable_gutenberg', 10, 2 );

/**
 * Disable Classic Editor by template
 *
 */
function ea_disable_classic_editor() {

	$screen = get_current_screen();
	if( 'page' !== $screen->id || ! isset( $_GET['post']) )
		return;

	if( ea_disable_editor( $_GET['post'] ) ) {
		remove_post_type_support( 'page', 'editor' );
	}

}
add_action( 'admin_head', 'ea_disable_classic_editor' );
  1. What is the best recommended approach for detecting a is_page_template() using Sage? for example I have a template “template-three-col.blade.php”, since there is “blade.php” will this fail?

Many thanks.

Please post your actual code, as well as the errors you’re seeing. “it fails” is not a helpful description of a problem.

is_page_template() checks the _wp_page_template field on a page to determine what template it’s using. Whatever is set there is what you should be matching against. You can examine this field directly to get an idea of what’s being saved there.

Apologies for not providing enough detail, my actual code which I’ve added to filters.php

function ea_disable_editor( $id = false ) {

    $excluded_templates = array(
        'template-three-column-layout.blade.php',
        // 'templates/contact.php'
    );

    $excluded_ids = array(
        // get_option( 'page_on_front' )
    );

    if( empty( $id ) ) {
        return false;
    }

    $id = intval( $id );
    $template = get_page_template_slug( $id );

    return in_array( $id, $excluded_ids ) || in_array( $template, $excluded_templates );
}

function ea_disable_gutenberg( $can_edit, $post_type ) {

    if( ! ( is_admin() && !empty( $_GET['post'] ) ) ) {
        return $can_edit;
    }

    if( ea_disable_editor( $_GET['post'] ) ) {
        $can_edit = false;
    }

    return $can_edit;

}

add_filter( 'gutenberg_can_edit_post_type', __NAMESPACE__, 'ea_disable_gutenberg', 10, 2 );
add_filter( 'use_block_editor_for_post_type', __NAMESPACE__, 'ea_disable_gutenberg', 10, 2 );

I receive the below errors which are all titled as below (I receive them in the admin section when going to that post template which is Post Template = template-three-column-layout.blade.php).

Warning: call_user_func_array() expects parameter 1 to be a valid callback, function 'App' not found or invalid function name in /srv/www/foowebsite.test/current/web/wp/wp-includes/class-wp-hook.php on line

You’re not adding the namespace correctly here.

When namespacing a function for a filter, what you’re ultimately doing is passing a string as the second argument that is the fully qualified name of the function—that is, the function with its namespace attached. That string might look like App\function_name to give an example. The nice thing about the __NAMESPACE__ magic constant is that it always yields a string that is the current namespace, which means that it can save you some typing when you’re calling functions in filters. To do that, you have to concatenate it with the name of your function, and you need to include an (escaped) backslash.

In your calls, you’ve made two mistakes:

  1. You aren’t concatenating __NAMESPACE__ with your function: instead you’re passing __NAMESPACE__ as an argument, and then the name of your function as another argument
  2. You aren’t including the necessary preceding backslash (although since you’re not concatenating, this wouldn’t help anyway).

A correct call would look like this:

add_filter( 'gutenberg_can_edit_post_type', __NAMESPACE__ . '\\ea_disable_gutenberg', 10, 2 );

Notice the period after __NAMESPACE__ to concatenate, and the escaped backslash before the name of your function.

The following two calls would be functionally identical:

add_filter( 'gutenberg_can_edit_post_type', __NAMESPACE__ . '\\ea_disable_gutenberg', 10, 2 );
add_filter( 'gutenberg_can_edit_post_type', 'App\\ea_disable_gutenberg', 10, 2 );

The second is a pain in the butt to type and maintain, so we use the __NAMESPACE__ constant.


The reason you’re getting the function 'App' could not be found warning is that you are passing only the namespace as the name of your function. There is no function named App (because that’s your namespace, not your method), so it fails.

1 Like

Thank you very much for the detailed response and for educating me further on the matter it is greatly appreciated.

I have refactored the add_filter statement as per your suggestion and I no longer receive the error in the admin screen.

Furthermore and incase anyone else is following this thread, I had to update the snippet I provided earlier to work with my custom template as follows:

$excluded_templates = array(
    'views/template-three-column-layout.blade.php'
);

Thanks as always @alwaysblank !