[wp-trac] [WordPress Trac] #38799: Normalize the registration of settings and control dependencies in the customize api

WordPress Trac noreply at wordpress.org
Tue Nov 15 11:27:54 UTC 2016


#38799: Normalize the registration of settings and control dependencies in the
customize api
-------------------------+-----------------------------
 Reporter:  nikeo        |      Owner:
     Type:  enhancement  |     Status:  new
 Priority:  normal       |  Milestone:  Awaiting Review
Component:  Customize    |    Version:
 Severity:  normal       |   Keywords:
  Focuses:  javascript   |
-------------------------+-----------------------------
 As the customizer is more and more prominent to design the WordPress
 websites, there's a growing need for making the settings and controls of
 the customize api interact one with another.
 And as a a theme developer, I find it difficult to implement those setting
 and control dependencies in the current customize api, in a normalized
 way.

 '''Example :'''
 For example, it's quite complex to define dependencies like :
 - Event : Setting A gets modified
 - Reactions :
   - Visibility of Control B is set to hidden
   - Control C displays a notice
   - value of setting D gets changed

 The following is a proposition of possible implementation to help solving
 this problem.

 '''What is a setting dependency ?'''
 A dependency is typically described by :
 - A master setting id, the one for which the value is listened to, let's
 call it dominus.
 - A set of "slaves" setting id, the one that are dependant of the dominus,
 let's call them servi.
 - A visiblity callback : handling the possible servi control visiblity
 reaction
 - An action callback : handling the possible servi settings or controls
 reaction like value change,
 ''Note : Even it sounds a little pedantic :), I'll use dominus and servi,
 rather than master and slaves which are way to negatively connoted
 words...''

 '''General principles of the enhancement'''
 A possible solution to simplify this dependency management would be to
 have :
 1. a simple way to populate a collection of dependencies actions
 (visibility or specific action) as normalized objects,
 2. fire those dependency callbacks when the dominus or servi sections are
 expanded

 '''Populating the collection of dependencies'''
 A posible improvement would be to have a new utility named
 `api.registerDependencies()`, which job would be to populate a collection
 of dependency objects looking like :


 {{{
 {
     dominus : 'setting_A',
     servi : ['setting_B', 'setting_C', 'setting_D' ],
     visibility : function( to, servusSettingId, dominusSettingId ) {
         if ( 'setting_B' == servusSettingId )
           return 'dominus_value_1' == to;
         else
           return 'dominus_value_2' == to;
     },
     actions : function( to, servusSettingId, dominusSettingId ) {
         if ( 'setting_A' == servusSettingId && 'dominus_value_2' == to)
           api.control('setting_A').container.append( '</div>', { html :
 '<p>I am a notice<p>'} );
         if ( 'setting_D' == servusSettingId && 'dominus_value_3' == to )
           api('setting_D').set('setting_D_value_2');
     }
 }
 }}}

 Registering dependencies could then be done with the following code :


 {{{
 api.registerDependencies(
   [
      { dominus : '', servi : [], visibility : function(){}, actions :
 function(){} },
      { ... },
      ...
   ]
 );
 }}}

 The `api.registerDepencies()` utility would store the collection in a
 static api property, like `api._dependencies`, or better, as an observable
 value like `api.dependencies = new api.Value( [ //the collection ] )`, to
 let us react to possible dynamic changes (like settings being dynamically
 added) happening to this collection during a customization session.



 '''Firing the dependencies'''
 The idea would be to fire the relevant registered setting dependencies of
 the currently active section() only, to optimize performances.

 To wrap the code and initialize it, a new Class could be introduced, let's
 call it `api.Visibilities = api.Class.extend( {} )`.
 Why a class ? => even if it would have only one instance in the api,
 instantiating this code as a class would offer a convenient and clean way
 to initializing it and wrapping the various methods.

 The job of this `new api.Visibilities()` object would be to :
 1. grab the `api.dependencies()` and make sure the registered dependencies
 are well formed
 2. listen to the current section expansion
 3. may be fire dependencies callbacks : visibility and custom actions
 4. make sure that the callbacks are bound to registered and embedded
 controls ( or registered settings ) with the following type of syntax :

 {{{

 api.control.when( setId, function() {
       api.control( setId ).deferred.embedded.then( function(){
             callback();//dependency callback
       });
 });

 }}}


 Any feedbacks and additions are welcome !

--
Ticket URL: <https://core.trac.wordpress.org/ticket/38799>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list