I am trying to dynamically load a ton of controls based on the value of a dropdown and I do not want to load them in via PHP because the initial page load takes well over 15 seconds. I have a lot of controls.

So what exactly are the requirements for instantiating settings and (custom) controls via JS?

Does my custom control class need to be registered and have the content_template method fleshed out? My class needs the "type" set right? (I've done both of these things)

Can I register the settings in PHP (this is what I've done) and then instantiate the controls via JS later or do I also need to instantiate the settings in JS?

What about the JS? Do I need to repeat my markup code in the JS instantiation?

This is what I have thus far, but nothing actually shows up.. I'm clearly missing some fundamental thing but I'm not sure what:

@weston-ruter got me on the right track, but I'm still a little confused by a couple things:

1- How is the value being passed into the field/saved when there is no data-customize-setting-link? Is that handled by JS content_template

2- I see that when a single setting is used for a control, the "default" key in the settings param is used, but what about when multiple settings and how do we grab the values for each setting: default

for 2, I was able to get it working with:
settings:{
variable : controlId+'[variable]',
control: controlId+'[control]',
value: controlId+'[value]',
percentage: controlId+'[percentage]'
}
I'm thinking something like this in the to_json() function:

1 Answer
1

If you register your settings on the server then you do not need to register them on the client in JS, as this will be done for you. Here are some examples creating controls after you have created the settings:

In the first example for Customize Posts CSS this actually uses a new Code Editor control that is brand new in WordPress 4.9. You can refer to this pull request to see what is required. In particular, make sure you call $wp_customize->register_control_type( 'My_Custom_Control' ) to ensure the content template is actually output.

When you are dynamically creating settings on the client, then you should instantiate them first in JS before you instantiate their related controls.

When you are dynamically creating settings and controls, the other key thing to implement is “dynamic settings” on the server. If you aren't creating the setting on the server, then it won't be recognized. This is what the customize_dynamic_setting_args and customize_dynamic_setting_class filters are for. Some examples:

You can see from core that the data-customize-setting-link is just a shortcut to do that automatically for you.

2- I see that when a single setting is used for a control, the "default" key in the settings param is used, but what about when multiple settings and how do we grab the values for each setting: default

Yes, you define other non-default keys. There are some key improvements coming in WordPress 4.9 to how this all works which will make it much easier to instantiate controls with JS. In addition to a data-customize-setting-link attribute there is now support for a data-customize-setting-key-link attribute, which allows you to use the actual key in the template as opposed to the setting ID. In addition, the settings you pass can reference either setting IDs, or Setting objects, or even just arbitrary Value instances.

The founded year being a Value is just for demonstration purposes. It being a Value and not a registered Setting means that it would not be saved in the database. But a Value like this could be useful for meta controls in a given theme, like picking from among preset color schemes. This is also how the changeset status and date get populated in WordPress 4.9.

Please watch make.wordpress.org/core for a dev note that dives into all of the specific improvements to the JS APIs in WordPress 4.9.

oh man this is great, thanks! I now have customizer loading in 10-20 fields when switching "tabs", values are passed in, and I have things saving (using obj.set instead of elm.sync)
– rugbertOct 23 '17 at 15:58