Make WordPress Core

Opened 8 years ago

Last modified 5 years ago

#37274 new enhancement

Facilitate updating/extending Customizer setting values that are objects

Reported by: westonruter's profile westonruter Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version: 3.4
Component: Customize Keywords: needs-patch
Focuses: javascript Cc:

Description (last modified by westonruter)

There is bit of a dance to work with setting values that are objects.

Consider a mailing_address setting that represents a street address:

    "street": "123 Fictional St.",
    "city": "Portland",
    "state": "OR",
    "zip": "97201"

Getting the value is as simple as wp.customize( 'mailing_address' ).get(), but updating the value is not so simple. To change the street part of this setting, the following is required:

var value = wp.customize( 'mailing_address' ).get();
value = _.clone( value );
value.street = '123 Imaginary Ave';
wp.customize( 'mailing_address' ).set( value );

The clone is required because objects are passed by reference, and if the value were to set directly, the subsequent set would not trigger a change event.

Widgets and nav menus use objects as values in Core. Widgets aren't manipulated directly in JS (until #33507) but nav menus and nav menu items are. Here's the code for managing how a nav menu's name gets changed when the nav menu's name field is updated:

control.nameElement.bind(function( value ) {
        var settingValue = control.setting();
        if ( settingValue && !== value ) {
                settingValue = _.clone( settingValue );
       = value;
                control.setting.set( settingValue );

To make it easier to work with setting values as objects, we could introduce a wp.customize.Value#setExtend method that allows an object value to be extended in the same way that setState works in React, take an object of key/value pairs that are merged on top of the existing value.

Here is an example implementation:

wp.customize.Value.prototype.setExtend = function( props ) {
    var value = _.clone( this.get() );
    _.extend( value, props );
    this.set( value );

With this, to update the mailing_address setting value property in the above example could be changed to simply:

wp.customize( 'mailing_address' ).setExtend( { street: '123 Imaginary Ave' } )

See #26061.
Related #37275.

Change History (3)

#1 @westonruter
8 years ago

  • Description modified (diff)

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

8 years ago

#3 @celloexpressions
8 years ago

  • Keywords needs-patch added

This sounds good to me in theory, although I'll probably understand it better once there's a patch.

Note: See TracTickets for help on using tickets.