{"id":4345,"date":"2017-12-22T11:57:38","date_gmt":"2017-12-22T10:57:38","guid":{"rendered":"https:\/\/florianbrinkmann.com\/en\/?p=4345"},"modified":"2020-02-09T10:59:39","modified_gmt":"2020-02-09T09:59:39","slug":"settings-customize-js-api","status":"publish","type":"post","link":"https:\/\/florianbrinkmann.com\/en\/settings-customize-js-api-4345\/","title":{"rendered":"Creating settings with the Customize JS API"},"content":{"rendered":"\n<p>My article from last week was about<a href=\"https:\/\/florianbrinkmann.com\/5071\/customize-js-api-panels-sections-controls\/\"> creating panels, sections, and controls with the JS API of the customizer<\/a>. This post describes how to register settings with the Customize JS API, which usually are created via the PHP API.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>Mostly you know exactly which settings are needed, so it is not a problem to create them via PHP. But, for example, currently, I have the case that I want to let the user create additional instances of sections with controls, similar to the menu management in the customizer. So I do not know how many settings I need to save the values, and for that, it is useful to create the settings via JS, but that is slightly more complicated than registering panels, sections, and controls.<\/p>\n\n\n\n<p>For preparation, we enqueue a JS file into the customizer like described in the post from last week, and insert the following code:<\/p>\n\n\n<pre class=\"wp-block-code lang-js\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/**\n * Custom JavaScript functions for the customizer controls.\n *\n * <span class=\"hljs-doctag\">@version<\/span> 2.0.0\n *\n * <span class=\"hljs-doctag\">@package<\/span> Hannover\n *\/<\/span>\n;(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-params\">(api)<\/span> <\/span>{\n\tapi.bind(<span class=\"hljs-string\">'ready'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-params\">()<\/span> <\/span>{\n\t\t<span class=\"hljs-comment\">\/\/ Create a setting.<\/span>\n\t\t<span class=\"hljs-keyword\">var<\/span> setting = <span class=\"hljs-keyword\">new<\/span> api.Setting( <span class=\"hljs-string\">'portfolio_category_page'<\/span> );\n\t\tapi.add( setting );\n\t});\n})(wp.customize);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>That is the JS part for creating a setting with the ID <code class=\"lang-php\">portfolio_category_page<\/code>. That looks easier than the part of last week\u2019s article, but we need to use a PHP filter to get the <code class=\"lang-php\">portfolio_category_page<\/code> setting working. For that, we add the following code into an appropriate PHP file, for example, the file you used for enqueuing the JS file:<\/p>\n\n\n<pre class=\"wp-block-code lang-php\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ Filter the dynamically created customizer settings.<\/span>\nadd_filter( <span class=\"hljs-string\">'customize_dynamic_setting_args'<\/span>, <span class=\"hljs-string\">'hannover_filter_dynamic_setting_args'<\/span>, <span class=\"hljs-number\">10<\/span>, <span class=\"hljs-number\">2<\/span> );\n\n<span class=\"hljs-comment\">\/**\n * Filters a dynamic setting\u2019s constructor args.\n *\n * For a dynamic setting to be registered, this filter must be employed\n * to override the default false value with an array of args to pass to\n * the WP_Customize_Setting constructor.\n *\n * <span class=\"hljs-doctag\">@link<\/span> https:\/\/wordpress.stackexchange.com\/a\/286503\/112824\n *\n * <span class=\"hljs-doctag\">@param<\/span> false|array $setting_args The arguments to the WP_Customize_Setting constructor.\n * <span class=\"hljs-doctag\">@param<\/span> string      $setting_id   ID for dynamic setting, usually coming from `$_POST&#91;'customized']`.\n *\n * <span class=\"hljs-doctag\">@return<\/span> array|false\n *\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">hannover_filter_dynamic_setting_args<\/span><span class=\"hljs-params\">( $setting_args, $setting_id )<\/span> <\/span>{\n\t<span class=\"hljs-keyword\">if<\/span> ( <span class=\"hljs-string\">'portfolio_category_page'<\/span> === $setting_id ) {\n\t\t$setting_args = &#91;\n\t\t\t<span class=\"hljs-string\">'type'<\/span> =&gt; <span class=\"hljs-string\">'theme_mod'<\/span>,\n\t\t];\n\t}\n\t<span class=\"hljs-keyword\">return<\/span> $setting_args;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>We hook the <code class=\"lang-php\">hannover_filter_dynamic_setting_args()<\/code> function to the <code class=\"lang-php\">customize_dynamic_setting_args<\/code> filter, which gets the arguments of the setting and the ID as params. This function now gets called for every setting \u2013 <code class=\"lang-php\">$setting_args<\/code> is <code class=\"lang-php\">false<\/code> by default for settings that are registered via the JS API, and if this is the value that gets returned, the setting is not registered.<\/p>\n\n\n\n<p>So we need to modify <code class=\"lang-php\">$setting_args<\/code> for all settings we registered via the JS API and convert it to an array. In our example, we check for the exact ID <code class=\"lang-php\">portfolio_category_page<\/code> and modify <code class=\"lang-php\">$setting_args<\/code> in that case. Here you can use all options from the <a href=\"https:\/\/developer.wordpress.org\/reference\/classes\/wp_customize_manager\/add_setting\/\">PHP method to add a setting<\/a>, so for example, define a sanitize callback.<\/p>\n\n\n\n<p>If you have settings with the format <code class=\"lang-php\">portfolio_category_page[1]<\/code>, <code class=\"lang-php\">portfolio_category_page[2]<\/code>, and <code class=\"lang-php\">portfolio_category_page[3]<\/code>, the check in <code class=\"lang-php\">hannover_filter_dynamic_setting_args()<\/code> should be done via a regex, to match multiple settings. Weston Ruter linked to various examples in core and plugin <a href=\"https:\/\/wordpress.stackexchange.com\/questions\/280561\/customizer-instantiating-settings-and-controls-via-javascript\/280744#280744\">in an answer on wordpress.stackexchange.com<\/a>.<\/p>\n\n\n\n<p>Now it should be possible to use the setting <code class=\"lang-php\">portfolio_category_page<\/code> for a control.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>My article from last week was about creating panels, sections, and controls with the JS API of the customizer. This post describes how to register settings with the Customize JS API, which usually are created via the PHP API.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"wpf_show_in_dewp_planet_feed":false,"flobn_post_versions":"","webmentions_disabled_pings":false,"webmentions_disabled":false,"lazy_load_responsive_images_disabled":false,"footnotes":""},"categories":[115],"tags":[],"class_list":["post-4345","post","type-post","status-publish","format-standard","hentry","category-wordpress-snippets"],"wp-worthy-pixel":{"ignored":false,"public":"02f6c3c9f5af46ea8c827460a6eac627","server":"vg07.met.vgwort.de","url":"https:\/\/vg07.met.vgwort.de\/na\/02f6c3c9f5af46ea8c827460a6eac627"},"wp-worthy-type":"normal","_links":{"self":[{"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/posts\/4345","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/comments?post=4345"}],"version-history":[{"count":6,"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/posts\/4345\/revisions"}],"predecessor-version":[{"id":5823,"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/posts\/4345\/revisions\/5823"}],"wp:attachment":[{"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/media?parent=4345"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/categories?post=4345"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/tags?post=4345"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}