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.
Here are some examples of creating settings:
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:
Note that the APIs for instantiating settings and controls will be getting better in core.
1- How is the value being passed into the field/saved when there is no
data-customize-setting-link
? Is that handled by JScontent_template
?
Then you have to then create the Element
link between the Setting
and the input
yourself manually, like this:
element = new wp.customize.Element( input );
element.sync( setting );
element.set( setting() );
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.
For example, consider a template added via:
add_action( 'customize_controls_print_footer_scripts', function() {
?>
<script id="tmpl-site-identity-control-content" type="text/html">
<# var elementIdPrefix = _.uniqueId( 'site-identity-' ); #>
<details>
<summary class="customize-control-title">{{ data.label }}</summary>
<ul>
<li>
<label for="{{ elementIdPrefix }}_title">Title:</label>
<input id="{{ elementIdPrefix }}_title" type="text" data-customize-setting-key-link="title">
</li>
<li>
<label for="{{ elementIdPrefix }}_tagline">Tagline:</label>
<input id="{{ elementIdPrefix }}_tagline" type="text" data-customize-setting-key-link="tagline">
</li>
<li>
<label for="{{ elementIdPrefix }}_founded">Year founded:</label>
<input for="{{ elementIdPrefix }}_founded" type="number" min="1" max="9999" data-customize-setting-key-link="founded">
</li>
</ul>
</details>
</script>
<?php
} );
You can add a control that uses this template simply be passing its ID as templateId
along with the desired settings
:
var foundedValue = new api.Value( 2017 );
var control = new api.Control( 'site_identity', {
templateId: 'site-identity-control-content',
label: 'Site Identity',
priority: 5,
section: sectionId,
settings: {
title: 'blogname', // Setting ID which may not be registered yet.
tagline: api( 'blogdescription' ), // Existing registered Setting object.
founded: foundedValue // Non-setting Value.
}
} );
api.control.add( control );
foundedValue.bind( function( newYear ) {
console.info( 'The year is now', newYear );
} );
And it then looks like this:
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.