1

I know that you can remove the editor section of the page editor page ( :/) depending on the template chosen using add_action( 'load-page.php', 'hide_editor_function' ); (with proper functionality of course). The problem with this though, as you should be able to tell, is that this will only work on a page load/reload. Not as soon as the template is changed.

As far as I can find, there is no specific hook for this. So my question really is, is there a hook for when the user changes the page template for a page in the admin panel? And if not, what would be the best way to have 'instantaneous' hiding/revealing of the editor (and add custom meta boxes)?

Thank you for your time, Lyphiix

1

If you want to toggle the editor "on the fly", you'll need to revert to a pure JavaScript solution, and only ever "visually" hide it (as opposed to removing it server-side):

function wpse_189693_hide_on_template_toggle() {
    $screen = get_current_screen();
    if ( $screen && $screen->id === 'page' ) :
        ?>

<script>
    jQuery( "#page_template" ).change(
        function() {
            jQuery( "#postdivrich" ).toggle( jQuery( this ).val() === "my-template.php" );
        }
    ).trigger( "change" );
</script>

<?php
    endif;
}

add_action( 'admin_print_footer_scripts', 'wpse_189693_hide_on_template_toggle' );

The reason you can't keep your hide_editor_function is, whilst this will work to initially hide the editor, once the user saves and reloads the page the editor will no longer be in the source to "toggle". So it always has to be there, even if it's just hidden.

  • Will this work for adding/removing metaboxes as well? Or should I be really stupid and reload the page on template changed and do the hiding I am already doing (plus adding/removing meta boxes). – Lyphiix May 28 '15 at 21:25
  • Yes, just change the jQuery selectors. I think reloading the page is overkill and asking for trouble. – TheDeadMedic May 28 '15 at 21:50
  • Yes... As I said, 'stupidly reload'. How do I find the selectors I want? – Lyphiix May 28 '15 at 21:56
  • Just view source or inspect element with your browser to get the id of the metaboxes – TheDeadMedic May 28 '15 at 22:16
  • 1
    For Gutenberg the #page_template selector no longer exists. The best way I could find to select the select box in this case is either .editor-page-attributes__template select or .editor-page-attributes__template #inspector-select-control-0. The latter seems better for specificity, but "inspector-select-control-0" seems like it's generated by the order of the select in that section, so may be less reliable in future. – James Cushing Sep 12 '19 at 9:22
0

For anyone using the Gutenberg editor, I found that (in addition to my comment on the accepted answer) there's more work which needs doing here.

Gutenberg injects children of .block-editor__container on the fly, so it's not enough to amend the selectors to catch the change event, you have to watch for the correct element being inserted. Using MutationObserver (since this is the better practice which replaces the soon-deprecated DOM Mutation Events and has full browser support), this is how I accomplished catching the template change:

$ = $ || jQuery; // Allow non-conflicting use of '$'

$(function(){

    // Create an observer to watch for Gutenberg editor changes
    const observer = new MutationObserver( function( mutationsList, observer ){

        // Template select box element
        let $templateField = $( '.editor-page-attributes__template select' );

        // Once we have the select in the DOM...
        if( $templateField.length ){

            // ...add the handler, then...
            $templateField.on( 'change', function(){

                // ...do your on-change work here
                console.log( 'The template was changed to ' + $( this ).val() );

            });
            observer.disconnect();

        }

    });
    // Trigger the observer on the nearest parent that exists at 'DOMReady' time
    observer.observe( document.getElementsByClassName( 'block-editor__container' )[0], {
        childList: true, // One of the required-to-be-true attributes (throws error if not set)
        subtree: true // Watches for the target element's subtree (where the select lives)
    });

});

Hope this helps someone!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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