WordPress.org

Make WordPress Core

Opened 3 years ago

Closed 3 years ago

#31484 closed defect (bug) (fixed)

Widgets in Customizer during theme preview fail to preview widgets with prior sidebars_widgets theme mod and fail to apply upon activation

Reported by: westonruter Owned by: ocean90
Milestone: 4.2 Priority: normal
Severity: normal Version: 4.1
Component: Customize Keywords: has-patch dev-feedback fixed-major
Focuses: javascript Cc:

Description (last modified by westonruter)

When testing the new Theme Switcher in the Customizer, I noticed when previewing another theme that the widget controls appearing in the Widgets panel were sometimes largely appearing as inactive (partially transparent) and the widgets appearing in the Customizer preview did not correspond to the widget controls I saw in the Widgets pane. In fact, the widgets in the Panel reflected the widgets that were actually from the previously-cached widgets configuration (via retrieve_widgets() and stored in the sidebars_widgets theme mod), but the widgets appearing in the Customizer preview corresponded to the widget configuration in the currently-active theme.

The problem was introduced in WordPress 4.1, specifically in r29905 for #29983, since we're no longer posting all of the settings from the Customizer pane to the preview for performance reasons: only the changed (dirty) settings get POSTed to the Preview when it is loaded.

Additionally, when attempting to activate the previous theme that had a cached widgets configuration in the sidebars_widgets theme mod, this prior configuration is not getting restored when activating the previously-active theme: the sidebar configuration from the current theme is overwriting the previous theme's configuration. I believe this is due to the old_sidebars_widgets_data not being marked as dirty, and so it is not being submitted when saving the settings.

Steps to reproduce:

  1. Activate Twenty Fourteen via the Themes admin page
  2. Add multiple widgets to each sidebar via the Widgets admin page; let them have "2014" in their titles
  3. Activate Twenty Thirteen via the Themes admin page
  4. Add multiple widgets to each sidebar (Main Widget Area, Secondary Widget Area) via the Widgets admin page; let them have "2013" in their titles
  5. Try switching between Twenty Thirteen and Twenty Fourteen and note each theme's respective sidebar configurations.
  6. Switch back to Twenty Fourteen via the Themes admin page.
  7. Live-preview the Twenty Thirteen theme either via the Themes admin page, or via the new Customizer theme previewer
  8. Open the Widgets panel and note that the widgets listed are correctly those for Twenty Thirteen, but notice in the Preview that the widgets from Twenty Fourteen are unexpectedly showing.
  9. Press *Save & Activate* when redirected to the frontend with the Twenty Thirteen theme active, notice that the Twenty Fourteen widgets are incorrectly shown.

For previous issues related to widgets in the Customizer being lost during a theme switch, see #27897.

Attachments (3)

31484.diff (3.9 KB) - added by westonruter 3 years ago.
https://github.com/xwp/wordpress-develop/pull/74
31484.2.diff (4.6 KB) - added by westonruter 3 years ago.
Additional changes: https://github.com/xwp/wordpress-develop/compare/52ff30b...df2f03f
31484.3.diff (20.2 KB) - added by westonruter 3 years ago.
Additional changes: https://github.com/xwp/wordpress-develop/compare/df2f03f...21c7e5

Download all attachments as: .zip

Change History (17)

#1 @westonruter
3 years ago

There is a simple workaround, for which I've written a monkey-patch plugin, which simply involves making all sidebars_widgets settings initially dirty when loading the Customizer for a theme preview.

The plugin is located here: https://gist.github.com/westonruter/c0b94561ec1adac966af

However, the best solution would be to make sure the WordPress initializes the Customizer preview with the proper previewed-theme's sidebars instead of using the ones from the currently-active theme. I'm not sure why the Customizer Pane is showing the previewed theme's widgets while the Customizer preview is retaining the active theme's widgets.

This ticket was mentioned in Slack in #core-customize by westonruter. View the logs.


3 years ago

#3 @westonruter
3 years ago

  • Description modified (diff)

#4 @westonruter
3 years ago

  • Description modified (diff)
  • Summary changed from Widgets appearing in Customizer preview during a theme preview may not correspond to controls in Widgets panel to Widgets in Customizer during theme preview fail to preview widgets with prior sidebars_widgets theme mod and fail to apply upon activation

#5 @westonruter
3 years ago

  • Keywords has-patch added; needs-patch removed
  • Owner set to ocean90
  • Status changed from new to assigned

In 31484.diff:

  • Unset wp_get_sidebars_widgets()' non-admin cache var $_wp_sidebars_widgets in Customize theme preview so that we can override.
  • Add WP_Customize_Setting::$dirty so that settings can be initially-dirty when the Customizer loads, and use on the old_sidebars_widgets_data setting.
  • Mark all sidebars_widgets settings as initially-dirty during theme switch.

This ticket was mentioned in Slack in #core-customize by westonruter. View the logs.


3 years ago

This ticket was mentioned in Slack in #core-customize by ocean90. View the logs.


3 years ago

#8 @westonruter
3 years ago

It's not looking promising to be able to sanely unit test widget changes in a Customizer theme switch. Current state: https://github.com/xwp/wordpress-develop/pull/74/files

#9 @westonruter
3 years ago

Maybe I spoke too soon. Please take a look at where I'm headed: https://github.com/xwp/wordpress-develop/pull/74/files

#10 @westonruter
3 years ago

  • Keywords dev-feedback added

OK, that was hard. Unit tests for theme switch in Customizer have been added.

Additional changes:

  • Use object cache instead of static var for WP_Theme::get_allowed_on_network() and WP_Theme::get_allowed_on_site(). This allows unit test to update the allowed themes.
  • Include $_REQUEST in WP_UnitTestCase::clean_up_global_scope()
  • Add test_override_sidebars_widgets_for_theme_switch and test_override_sidebars_widgets_for_non_theme_switch
  • Add $options param to WP_Customize_Manager::save() to bypass Ajax-specific behaviors
  • Introduce new customize_save_before_switch_theme action instead of having WP look at Ajax-specific action wp_ajax_customize_save
  • Test saving the customizer and ensuring the new theme and old theme have expected states

#11 @westonruter
3 years ago

As mentioned in Slack, changes introduced in 31484.3.diff were to support the writing of unit tests. So nothing from .3 should be needed to be added to 31484.2.diff for the 4.1.2 bugfix release:

Initial changes in .2: https://github.com/xwp/wordpress-develop/compare/22179be...df2f03f
Additional changes in .3: https://github.com/xwp/wordpress-develop/compare/df2f03f...21c7e5

The .3 changes could be committed separately for the 4.2 release.

#12 @ocean90
3 years ago

In 31705:

Customizer: Fix previewing and applying widgets when previewing another theme.

  • Unset wp_get_sidebars_widgets()' non-admin cache var $_wp_sidebars_widgets in Customize theme preview.
  • Add WP_Customize_Setting::$dirty so that settings can be initially-dirty when the Customizer loads.
  • Mark old_sidebars_widgets_data setting initially-dirty.
  • Mark all sidebars_widgets settings as initially-dirty during theme switch.

props westonruter.
see #31484.

#13 @ocean90
3 years ago

  • Keywords fixed-major added

#14 @pento
3 years ago

  • Milestone changed from 4.1.2 to 4.2
  • Resolution set to fixed
  • Status changed from assigned to closed

With 4.2 being just around the corner, we're going to skip this for 4.1.2.

Note: See TracTickets for help on using tickets.