WordPress.org

Make WordPress Core

Opened 3 years ago

Last modified 10 months ago

#29071 reopened enhancement

Make it easier to include an instance of the Customizer outside of customize.php

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

Description

A lot of the bootstrapping of the customizer goes on either in customize.php or in function calls that are hardwired to this instance.

We should make this code more modular, so there isn't so much boilerplate required to load a customizer instance on a different page.

Attachments (4)

29071.diff (846 bytes) - added by ericlewis 3 years ago.
customize-preview-posts.php (1.6 KB) - added by celloexpressions 3 years ago.
Experimental plugin that opens the Customizer via customize-loader when previewing posts, for demo purposes.
29071.2.diff (7.5 KB) - added by ericlewis 3 years ago.
29071.3.diff (1.5 KB) - added by ericlewis 3 years ago.

Download all attachments as: .zip

Change History (28)

@ericlewis
3 years ago

#1 @ericlewis
3 years ago

In attachment:29071.diff, move inclusion of the WP_Customize_Manager file and the $wp_customize global into a single responsibility function for this, wp_bootstrap_customize_manager()

@celloexpressions
3 years ago

Experimental plugin that opens the Customizer via customize-loader when previewing posts, for demo purposes.

#2 follow-up: @celloexpressions
3 years ago

A few alternative things to consider:

  • Rather than being able to have entirely separate instances of the Customizer, what about making the Customizer more adaptable to different contexts?
  • Customizer Panels provide different contexts for the Customizer; deep-linking (#28650) into a certain panel on load, and possibly having the option to prevent users from leaving a given panel could effectively give you multiple customizer instances for different purposes. The new support for contextual controls probably helps here, especially once it's extended to sections and panels.
  • customize-loader.js provides a way to open the customizer without losing too much context of the current screen. It could probably be improved to provide the option for looking more like a modal if that's desirable for a given situation. See customize-preview-posts.php for an example of leveraging customize-loader to essentially create a new Customizer instance, and also think about that with a deep-linked panel (demo plugin for previewing posts, not 100% functional but that's the idea + amount of code required).
  • The Customizer should eventually be incorporated into WP-API, and should theoretically be much more portable when that happens.

#3 in reply to: ↑ 2 ; follow-up: @westonruter
3 years ago

Replying to celloexpressions:

  • The Customizer should eventually be incorporated into WP-API, and should theoretically be much more portable when that happens.

How do you see this working?

#4 in reply to: ↑ 3 @celloexpressions
3 years ago

Replying to westonruter:

Replying to celloexpressions:

  • The Customizer should eventually be incorporated into WP-API, and should theoretically be much more portable when that happens.

How do you see this working?

Not exactly sure, but I know that's in the WP-API team's longer-term plans. I'm guessing it would involve being able to get all registered settings, controls, sections, and panels, and being able to save those, although previewing would probably need to be implemented separately. And not sure if/how it would handle things like custom controls and custom setting types.

Of course, while we could potentially make use of that some in core, the primary use would be implementing the Customizer in external things like mobile apps.

@ericlewis
3 years ago

#5 follow-up: @ericlewis
3 years ago

  • Keywords has-patch added

In attachment:29071.2.diff, move the settings array building to a single-responsibility method WP_Customize_Manager->get_settings_for_js()

#6 @westonruter
3 years ago

  • Milestone changed from Awaiting Review to Future Release
  • Version changed from trunk to 3.4

This ticket was mentioned in IRC in #wordpress-dev by ericandrewlewis1. View the logs.


3 years ago

@ericlewis
3 years ago

#8 follow-up: @ericlewis
3 years ago

In attachment:29071.3.diff, wrap bootstrapping code for the default customizer experience into a function, and return early if its not the default customizer instance (customize.php).

#9 in reply to: ↑ 5 @westonruter
3 years ago

Replying to ericlewis:

In attachment:29071.2.diff, move the settings array building to a single-responsibility method WP_Customize_Manager->get_settings_for_js()

Might I suggest something other than “settings” in the naming of get_settings_for_js. The term has been unfortunately overloaded in the Customizer to not only refer to the configuration of the customizer, but also the models (settings) which are being customized. Case in point: wp.customize.settings.setting. For the former sense of “settings” I think “config” makes more sense. So perhaps WP_Customize_Manager->get_config_for_js() or WP_Customize_Manager->export_js_config().

#10 in reply to: ↑ 8 @westonruter
3 years ago

Replying to ericlewis:

In attachment:29071.3.diff, wrap bootstrapping code for the default customizer experience into a function, and return early if its not the default customizer instance (customize.php).

There's an awful lot of code that is going to be unreusable if we go this route. The majority of the code in bootstrapDefaultCustomizerInstance would only be usable on the main Customizer page.

Should bootstrapDefaultCustomizerInstance() perhaps instead be replaced with something like wp.customize.init()? The customizer.php page could then manually invoke it at the end after all scripts are printed, something like:

<script type="text/javascript">
var _wpCustomizeSettings = <?php echo json_encode( $settings ); ?>;
</script>
<script>
$(function () {
    wp.customize.init({
        settings: window._wpCustomizeSettings, // or 'config' instead
        l10n: window._wpCustomizeControlsL10n // not 100% sure on this one 
    }); // or window._wpCustomizeSettings could be the only argument passed into init
});
</script>

This would keep customize-controls.js from attempting to bootstrap itself, which would improve reusability.

#11 @wonderboymusic
3 years ago

man, those iOS-length method names...

I like the @westonruter approach. For most of our JS in WP, we should be creating libraries, and then have the page they are loaded on instantiate them, either inline or a new file for the instance. That way, something like post.js or whatever just instantiates instances, instead of the library file having a docReady blob.

#12 @westonruter
3 years ago

Another idea, one which would make the Customizer even more reusable, even to allow multiple instances appearing on the same page: instead of adding a wp.customize.init(), which is kinda following a “singletony” paradigm, it would be interesting to explore if the Customizer was a function prototype that could be instantiated. For instance:

wp.customize = new wp.Customizer( window._wpCustomizeSettings );

A challenge here, of course, is that there is a lot of code that adds stuff to wp.customize as a global namespace. So it could be difficult to encapsulate the Customizer in this way. So something like this might need to be used instead:

wp.customize = $.extend( new wp.Customizer( window._wpCustomizeSettings ), wp.customize );

In this way, other instances of the Customizer could be created but assigned to other variables to live alongside any primary customizer. Any pieces of code that refer to wp.customize (i.e. api) would need to be updated to be explicitly passed a Customizer instance that they should be referring to.

#13 @westonruter
3 years ago

Discussed wp.customize.init() in context of splitting up JS files, Customizer code reusability, and unit testing in #30277.

#14 follow-up: @wonderboymusic
3 years ago

  • Keywords needs-refresh added

These vars should be renamed to something that isn't 400 chars long

#15 in reply to: ↑ 14 @westonruter
3 years ago

Replying to wonderboymusic:

These vars should be renamed to something that isn't 400 chars long

What's wrong with long variable names?

#16 @wonderboymusic
3 years ago

That would the longest symbol in the WordPress JS codebase, second only to wp.customize.Widgets.getSidebarWidgetControlContainingWidget, which I also dislike.

At this point, I'm not even sure that the approach is correct. The main problem here is that the file provides an API and produces side-effects. It should not produce side effects (as we discussed at the Community Summit).

#17 @ericlewis
2 years ago

  • Keywords has-patch needs-refresh removed
  • Milestone Future Release deleted
  • Resolution set to wontfix
  • Status changed from new to closed

@westonruter and I have riffed on the idea of booting the Customizer in alternative, specific contexts (see our Custom CSS per post plugin).

We should not support the approach suggested in this ticket.

#18 @westonruter
2 years ago

  • Resolution changed from wontfix to maybelater

I'm going to change the resolution to maybelater because with inline controls and transactions, the Customizer would eventually be more seamless and able to be added to an existing page, meaning that it could easily exist other places than customize.php

#19 @westonruter
18 months ago

  • Milestone set to Future Release
  • Resolution maybelater deleted
  • Status changed from closed to reopened

Allowing controls to be used outside of the Customizer context is key for re-using components across WordPress, such as using controls in a frontend context or using Customizer controls for shortcode UI.

#20 @westonruter
18 months ago

In 37867:

Customize: Always define functions reflowPaneContents, findControlsForSettings, and _handleSettingValidities on wp.customize.

Moves definitions of functions outside of a jQuery.ready() callback, as these functions needn't be deferred to DOM ready. This change also ensures that the functions are available if customize-controls is enqueued outside of the Customizer context, as the ready callback short-circuits if _wpCustomizeSettings is not defined. The findControlsForSettings and _handleSettingValidities functions were misplaced in r37700.

See #34893.
See #36944.
See #29071.

#21 @westonruter
18 months ago

@ericlewis I've created a new plugin that starts putting together examples for standalone Customizer controls, and uncovering some of the rough edges for doing this: https://github.com/xwp/standalone-customizer-controls

#22 @westonruter
15 months ago

Related: #38077 (Facilitating embedding customizer controls outside of sections)

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


10 months ago

#24 @westonruter
10 months ago

There's a good amount of overlap in this ticket with bootstrapping the customizer onto the frontend. If the customizer is more componentized then it would be facilitated to load onto the frontend or to bootstrap into the admin, though in the latter case it should be left to plugins to facilitate embedding a customizer preview in the admin. Core's focus would be on the single-page app experience, which now is at customize.php but which eventually could overtake any given URL rendered on the frontend.

Note: See TracTickets for help on using tickets.