{"id":4337,"date":"2017-12-16T17:30:30","date_gmt":"2017-12-16T16:30:30","guid":{"rendered":"https:\/\/florianbrinkmann.com\/en\/?p=4337"},"modified":"2020-02-09T10:59:40","modified_gmt":"2020-02-09T09:59:40","slug":"panels-sections-controls-customize-js-api","status":"publish","type":"post","link":"https:\/\/florianbrinkmann.com\/en\/panels-sections-controls-customize-js-api-4337\/","title":{"rendered":"Creating panels, sections, and controls with the Customize JS API"},"content":{"rendered":"<p>Until now I mostly used the PHP API of the customizer. Since Weston Ruter\u2019s post about the <a href=\"https:\/\/make.wordpress.org\/core\/2017\/11\/01\/improvements-to-the-customize-js-api-in-4-9\/\">improvements of the Customize JS API in WordPress 4.9<\/a>, I wanted to change that and learn more about the Customize JS API. This post shows you how to create panels, sections, and controls with that API.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Why the Customize JS API has advantages against the PHP API<\/h2>\n\n\n\n<p>I did not think about that much \u2013 I began with the PHP API and stayed with it. But the PHP API is \u2013 like Weston writes in his post \u2013 just a wrapper for the JS API. He also writes:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>\u00bbThe point here is that in order for the Customizer to scale, the JavaScript API must be used directly. So this is why the Customizer JS API improvements in 4.9 are important as they fix many longstanding annoyances and shortcomings with the JS API.\u00ab<\/p><p><cite>Weston Ruter in <a href=\"https:\/\/make.wordpress.org\/core\/2017\/11\/01\/improvements-to-the-customize-js-api-in-4-9\/\">Improvements to the Customize JS API in 4.9<\/a><\/cite><\/p><cite>Weston Ruter in <a href=\"https:\/\/make.wordpress.org\/core\/2017\/11\/01\/improvements-to-the-customize-js-api-in-4-9\/\">Improvements to the Customize JS API in 4.9<\/a><\/cite><\/blockquote>\n\n\n\n<p>So I thought to myself, I will try it out at the next opportunity. And because my Hannover and Bornholm themes need a visual and technical update, I already had it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Disadvantage of the Customize JS API<\/h2>\n\n\n\n<p>There is also a disadvantage of the Customize JS API: currently, it is not very well documented, so it takes some time to find information, even if the API is entirely written in one (or just some) core files, so theoretically one could extract its functioning from there. For me, that was just a little help.<\/p>\n\n\n\n<p>More helpful was Google, and frequently appearing answers and posts from Weston Ruter \ud83d\ude42<\/p>\n\n\n\n<p>But now let us come to the main topic of this post:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Creating panels, sections, and controls with the JS API<\/h2>\n\n\n\n<p>At first, we need to enqueue a JS file into the customizer\u2019s control area. For that we use the following code:<\/p>\n\n\n<pre class=\"wp-block-code lang-php\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-comment\">\/\/ Include scripts into the customizer.<\/span>\nadd_action( <span class=\"hljs-string\">'customize_controls_enqueue_scripts'<\/span>, <span class=\"hljs-string\">'hannover_customizer_controls_script'<\/span> );\n\n<span class=\"hljs-comment\">\/**\n * Prints styles inside the customizer view.\n *\/<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">hannover_customizer_controls_script<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\t<span class=\"hljs-comment\">\/\/ Add script control section.<\/span>\n\twp_enqueue_script( <span class=\"hljs-string\">'hannover-customize-controls'<\/span>, get_theme_file_uri( <span class=\"hljs-string\">'assets\/js\/customize-controls.js'<\/span> ), &#91;], <span class=\"hljs-literal\">null<\/span>, <span class=\"hljs-literal\">true<\/span> );\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Now we create the <code class=\"lang-markup\">customize-controls.js<\/code> in the <code class=\"lang-markup\">assets\/js<\/code> folder with the following content:<\/p>\n\n\n<pre class=\"wp-block-code lang-js\" 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\">\/**\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 theme options panel.<\/span>\n\t\tapi.panel.add(\n\t\t\t<span class=\"hljs-keyword\">new<\/span> api.Panel(<span class=\"hljs-string\">'hannover_theme_options'<\/span>, {\n\t\t\t\ttitle: <span class=\"hljs-string\">'Theme Options'<\/span>,\n\t\t\t})\n\t\t);\n\n\t\t<span class=\"hljs-comment\">\/\/ Add section.<\/span>\n\t\tapi.section.add(\n\t\t\t<span class=\"hljs-keyword\">new<\/span> api.Section(<span class=\"hljs-string\">'hannover_example_section'<\/span>, {\n\t\t\t\ttitle: <span class=\"hljs-string\">'Example Section'<\/span>,\n\t\t\t\tpanel: <span class=\"hljs-string\">'hannover_theme_options'<\/span>,\n\t\t\t\tcustomizeAction: <span class=\"hljs-string\">'Customizing \u25b8 Theme Options'<\/span>\n\t\t\t})\n\t\t);\n\n\t\t<span class=\"hljs-comment\">\/\/ Add checkbox control.<\/span>\n\t\tapi.control.add(\n\t\t\t<span class=\"hljs-keyword\">new<\/span> api.Control(<span class=\"hljs-string\">'hannover_example_control'<\/span>, {\n\t\t\t\tsetting: <span class=\"hljs-string\">'hannover_example_setting'<\/span>,\n\t\t\t\ttype: <span class=\"hljs-string\">'checkbox'<\/span>,\n\t\t\t\tsection: <span class=\"hljs-string\">'hannover_example_section'<\/span>,\n\t\t\t\tlabel: <span class=\"hljs-string\">'Check this box to do something.'<\/span>\n\t\t\t})\n\t\t);\n\t});\n})(wp.customize);\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 wait until the Customizer is ready and add a panel, section, and control. You can see that the code for adding each of the elements is quite similar. The first parameter of the new call is the ID, after that, there comes an object with the options, like known from the PHP API.<\/p>\n\n\n\n<p>One exception from that: <code class=\"lang-js\">customizeAction<\/code> for <code class=\"lang-js\">new api.Section<\/code> defines the string that is shown above the title in the section view:<\/p>\n\n\n\n<figure class=\"wp-block-image alignnone size-full wp-image-4338\"><noscript><img decoding=\"async\" width=\"345\" height=\"230\" src=\"https:\/\/florianbrinkmann.com\/en\/wp-content\/uploads\/sites\/11\/2017\/12\/customize-js-api-customizeaction.png\" alt class=\"wp-image-4338\" srcset=\"https:\/\/florianbrinkmann.com\/en\/wp-content\/uploads\/sites\/11\/2017\/12\/customize-js-api-customizeaction.png 345w, https:\/\/florianbrinkmann.com\/en\/wp-content\/uploads\/sites\/11\/2017\/12\/customize-js-api-customizeaction-300x200.png 300w\" sizes=\"(max-width: 345px) 100vw, 345px\"><\/noscript><img decoding=\"async\" width=\"345\" height=\"230\" src=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20345%20230%22%3E%3C%2Fsvg%3E\" alt class=\"wp-image-4338 lazyload\" srcset=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20345%20230%22%3E%3C%2Fsvg%3E 345w\" sizes=\"(max-width: 345px) 100vw, 345px\" data-srcset=\"https:\/\/florianbrinkmann.com\/en\/wp-content\/uploads\/sites\/11\/2017\/12\/customize-js-api-customizeaction.png 345w, https:\/\/florianbrinkmann.com\/en\/wp-content\/uploads\/sites\/11\/2017\/12\/customize-js-api-customizeaction-300x200.png 300w\" data-src=\"https:\/\/florianbrinkmann.com\/en\/wp-content\/uploads\/sites\/11\/2017\/12\/customize-js-api-customizeaction.png\"><figcaption>Above the title of the customizer section, the <code class=\"lang-js\">customizeAction<\/code> string is displayed. (Screenshot: own installation)<\/figcaption><\/figure>\n\n\n\n<p>And with that, we are at the end of this small introduction to the Customize JS API. <strong>Important is, that \u2013 generally \u2013 you define the settings with the PHP API \u2013 otherwise, the values are not stored in the database<\/strong>. There is a way to create settings via the JS API dynamically, but that is the topic of another article.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Until now I mostly used the PHP API of the customizer. Since Weston Ruter\u2019s post about the improvements of the Customize JS API in WordPress 4.9, I wanted to change that and learn more about the Customize JS API. This post shows you how to create panels, sections, and controls with that 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-4337","post","type-post","status-publish","format-standard","hentry","category-wordpress-snippets"],"wp-worthy-pixel":{"ignored":false,"public":"49ddf9259dbc4ccb9fa6d808ee2913fd","server":"vg07.met.vgwort.de","url":"https:\/\/vg07.met.vgwort.de\/na\/49ddf9259dbc4ccb9fa6d808ee2913fd"},"wp-worthy-type":"normal","_links":{"self":[{"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/posts\/4337","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=4337"}],"version-history":[{"count":4,"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/posts\/4337\/revisions"}],"predecessor-version":[{"id":5825,"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/posts\/4337\/revisions\/5825"}],"wp:attachment":[{"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/media?parent=4337"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/categories?post=4337"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/tags?post=4337"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}