Opened 7 years ago
Last modified 7 years 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)
#2
@
7 years ago
Nice one @brentjett@…. I think that could be another ticket by itself. It is a great idea.
#3
@
7 years 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
@
7 years 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
@
7 years 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
@
7 years 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.
#8
@
7 years 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
@
7 years 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
@
7 years 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
@
7 years 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.
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.