WordPress.org

Make WordPress Core

Opened 4 months ago

Last modified 4 months ago

#41126 new enhancement

Customizer does not work if both wp_footer() and wp_head() functions are not present in the theme.

Reported by: mdifelice Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version: 4.7
Component: Customize Keywords:
Focuses: administration Cc:

Description

I know there is another ticket (#14752) that refers to when wp_head() and wp_footer() are not present in the theme and it was discarded. But in this case, I refer specifically to the Customizer. Since it will not work when those functions are missing, maybe we can disable it completely (maybe with a dismissible notice in the head) or find a way to include the necessary files and data and make it work even when those functions are missing.

Change History (13)

#1 @brentjett@…
4 months ago

It wouldn't necessarily fix a mal-formed theme, but I would suggest core offering the ability for a theme author to opt-in to the system rendering the document wrapper and the theme only be responsible for what outputs inside the <body>.
From an api footprint perspective it could be as simple as:

add_theme_support( 'html-document' );

Letting the system render the doctype, head, etc... would ensure more well-formed themes and take the burden off the theme author to implement the majority of the hooks the system requires.

#2 @mdifelice
4 months ago

Nice one @brentjett@…. I think that could be another ticket by itself. It is a great idea.

#3 @westonruter
4 months ago

@mdifelice if you have a template that lacks wp_head() and wp_footer(), then currently you have to manually print the required scripts and call the methods that would normally get output. For example, the following should account for most of what is required:

<?php
global $wp_customize;
if ( is_customize_preview() ) {

        // Enqueue assets for components.
        $wp_customize->selective_refresh->enqueue_preview_scripts();
        if ( $wp_customize->widgets ) {
                $wp_customize->widgets->customize_preview_enqueue();
        }
        if ( $wp_customize->nav_menus ) {
                $wp_customize->nav_menus->customize_preview_enqueue_deps();
        }

        // Print customize-preview style and all styles that depend on it.
        $styles = array( 'customize-preview' );
        foreach ( wp_styles()->registered as $handle => $asset ) {
                if ( in_array( 'customize-preview', $asset->deps, true ) ) {
                        $styles[] = $handle;
                }
        }
        wp_print_styles( $styles );

        // Print customize-preview script and all scripts that depend on it.
        $scripts = array( 'customize-preview' );
        foreach ( wp_scripts()->registered as $handle => $asset ) {
                if ( in_array( 'customize-preview', $asset->deps, true ) ) {
                        $scripts[] = $handle;
                }
        }
        wp_print_scripts( $scripts );

        // Call methods normally done by wp_head and wp_footer.
        $wp_customize->remove_frameless_preview_messenger_channel();
        $wp_customize->customize_preview_settings();
        $wp_customize->customize_preview_loading_style();
        $wp_customize->selective_refresh->export_preview_data();
        if ( $wp_customize->widgets ) {
                $wp_customize->widgets->print_preview_css();
                $wp_customize->widgets->export_preview_data();
        }
        if ( $wp_customize->nav_menus ) {
                $wp_customize->nav_menus->export_preview_data();
        }
}

#4 @SergeyBiryukov
4 months ago

  • Summary changed from Customizer does not work if both wp_footer() and wp_head() functions are present in the theme. to Customizer does not work if both wp_footer() and wp_head() functions are not present in the theme.

#5 @mdifelice
4 months ago

Yes @westonruter, my idea is to give the administrator or devop a warning, because it is not intuitive to figure out why the Customizer is not working in those cases.

#6 @westonruter
4 months ago

  • Milestone changed from Awaiting Review to Future Release
  • Type changed from defect (bug) to enhancement
  • Version changed from trunk to 4.7

@mdifelice as of 4.7 there's actually a facility for this. Namely, the wp.customize.state( 'previewerAlive' ) value. See https://github.com/WordPress/wordpress-develop/blob/c321e10c1642fabed623292d1d157d341662b7d9/src/wp-admin/js/customize-controls.js#L3888-L3936

So what a patch here could look like is:

wp.customize.state( 'previewerAlive' ).bind( function( isAlive ) {
    if ( isAlive ) {
        // Hide notification.
    } else {
        // Show notification.
    }
});

The notification could be displayed via #35210.

#7 @mdifelice
4 months ago

Thanks @westonruter. I will make something on that.

#8 @mdifelice
4 months ago

Hi @westonruter. I was making some tests and the previewerAlive state is set to true even if wp_head() is missing. And if wp_footer() is missing too, it is executed only once. I do not think that event will work for what I am asking for.

This is something it could be detected in the page loading, since if wp_head() or wp_footer() are missing in the theme files, there is no way to dynamically load them.

#9 @westonruter
4 months ago

@mdifelice I'm not sure I understand. If wp_footer is missing then what is executed once? The key thing you're needing to account for is whether or not the keep-alive messages are being sent from the preview to the pane. See https://github.com/WordPress/wordpress-develop/blob/4.8.0/src/wp-includes/js/customize-preview.js#L537-L595

If customize-preview.js gets written out to the preview window (either via wp_head() or wp_footer()), then these messages will get sent and the Customizer will keep the previewerAlive state as true.

#10 @mdifelice
4 months ago

Sorry @westonruter. Maybe I was a little asleep when I wrote that :). What I meant is that even when wp_head() is missing the keep alive tick is still being executed. So, that validation would not work given that without a wp_head() output the customizer will not work properly.

#11 @westonruter
4 months ago

@mdifelice but doesn't the customizer preview still work when wp_head() is not present? It seems to work fine for me, aside from styling not being applied as expected.

#12 @mdifelice
4 months ago

I did a little test with wp_head() missing and the theme containing a sidebar with a widget displaying the menu, and the Customizer does not recognize it. If you want I can share the test.

#13 @westonruter
4 months ago

@mdifelice ah, good point. The issue is that some of the Customizer scripts are enqueued at the wp_enqueue_scripts action, so if wp_head() is not present then this action is not triggered. So to work around this, all you need to do is manually call wp_enqueue_scripts().

Note: See TracTickets for help on using tickets.