{"id":134097,"date":"2014-11-27T08:00:59","date_gmt":"2014-11-27T13:00:59","guid":{"rendered":"http:\/\/premium.wpmudev.org\/blog\/?p=134097"},"modified":"2022-03-11T01:21:59","modified_gmt":"2022-03-11T01:21:59","slug":"wordpress-theme-customization-api","status":"publish","type":"post","link":"https:\/\/wpmudev.com\/blog\/wordpress-theme-customization-api\/","title":{"rendered":"Creating WordPress Theme Options With the Theme Customization API"},"content":{"rendered":"<p>Creating WordPress Theme Options With the Theme Customization API is easy to do. This article shows you how it&#8217;s done.<\/p>\n<p>The WordPress Theme Customization API was released with WordPress 3.4, back in 2012. It promised developers a standardized way of adding rich options themes, and users a way of tweaking their website in a, well, user-friendly fashion.<\/p>\n<p>For users, the front-end theme customizer allows you to quickly change the look of your site, and even get a live preview.<\/p>\n<p>The success of this project is debatable but it is being improved upon and is gaining traction. It has been built on a solid foundation and there is no reason not to get started with it.<\/p>\n<p>So let&#8217;s take a look at how we can easily add settings\u00a0to themes using\u00a0the API.<\/p>\n<p>Here\u2019s what we\u2019re going to cover today:<\/p>\n<ul>\n<li><a href=\"#foundation\">Building Our Foundation<\/a><\/li>\n<li><a href=\"#components-theme-settings\">The Components Of A Theme Setting<\/a><\/li>\n<li><a href=\"#using-setting-values\">Using Setting Values<\/a><\/li>\n<li><a href=\"#live-previews\">Live Previews<\/a><\/li>\n<li><a href=\"#encapsulating-in-a-class\">Encapsulating In a Class<\/a><\/li>\n<li><a href=\"#further-options\">Further Options<\/a><\/li>\n<\/ul>\n<figure id=\"attachment_134541\" class=\"wp-caption aligncenter\" data-caption=\"true\"><a rel=\"lightbox[134097]\" class=\"blog-thumbnail\" href=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2014\/11\/theme-customizer.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-134541\" src=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2014\/11\/theme-customizer.png\" alt=\"Theme Customizer\" width=\"800\" height=\"220\" \/><\/a><figcaption class=\"wp-caption-text\">Customize the theme customizer.<\/figcaption><\/figure>\n<h2 id=\"foundation\">Building Our Foundation<\/h2>\n<p>The key to the customization API is the <code> WP_Customize_Manager<\/code> class, which can be accessed through the <code>$wp_customize<\/code> object. We will be using various methods defined in this class to add settings sections and controls within them.<\/p>\n<p>The recommended way of creating theme settings is to encapsulate them in a class. In our initial examples, I will <em>not<\/em> be adhering to this recommendation to make sure it is clear what\u00a0is part of the customization API and what isn&#8217;t. I will complete the article with a class-based implementation.<\/p>\n<p>Let&#8217;s begin by creating a function in our theme&#8217;s <code>functions.php<\/code> file, which will allow us to include our additions in the customizer. This function needs to be hooked to <code>customize_register.<\/code><\/p>\n<p><span style=\"font-weight: 400;\"><div class=\"gist\" data-gist=\"bc16fe2e46d064f4c00578b2a50ed535\" data-gist-file=\"gistfile 1\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/bc16fe2e46d064f4c00578b2a50ed535.js?file=gistfile+1\">Loading gist bc16fe2e46d064f4c00578b2a50ed535<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/span><\/p>\n<h2 id=\"components-theme-settings\">The Components Of A Theme Setting<\/h2>\n<p>As mentioned in the example, each item you add to the customizer consists of three parts:<\/p>\n<ul>\n<li>A <strong>section<\/strong> must be created to place it in. This section may be one of the pre-existing ones of course<\/li>\n<li>A <strong>setting<\/strong> must be registered in the database, and<\/li>\n<li>A\u00a0<strong>control<\/strong> needs to be created which is used to manipulate the defined setting<\/li>\n<\/ul>\n<p>If the separation between a control and a setting seems confusing, think of it like this: When you create a setting you tell WordPress that there is indeed a setting for font color and the default value for this is #444444. In itself, this already means that this setting can be used.<\/p>\n<p>However, the theme customizer needs to know how to manipulate this setting. You could create a text field for it where the user enters new colors manually as &#8220;#ff9900&#8221; but you could also specify a color control, which would output a color selector. On a database level it will all still boil down to a hex color, but the user-facing side is different.<\/p>\n<h3>Creating A Section<\/h3>\n<p>The <code>add_section()<\/code> is used to create sections. It takes two parameters, a section slug and an array of arguments. Here&#8217;s an example of how I set up a section for footer options in a theme.<\/p>\n<p><span style=\"font-weight: 400;\"><div class=\"gist\" data-gist=\"cbdd466861a75ddf2015f708897e39c3\" data-gist-file=\"gistfile 1\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/cbdd466861a75ddf2015f708897e39c3.js?file=gistfile+1\">Loading gist cbdd466861a75ddf2015f708897e39c3<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/span><\/p>\n<p>Most of this is pretty self-explanatory. Note the priority, though! This determines the order of the section on the screen. I like to increment my options in tens. If I need to insert a section between two existing sections I won&#8217;t need to re-index everything, I can just assign the new one 95.<\/p>\n<figure id=\"attachment_134392\" class=\"wp-caption aligncenter\" data-caption=\"true\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-134392\" src=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2014\/11\/sections.png\" alt=\"Custom Theme Customizer Sections\" width=\"298\" height=\"295\" \/><figcaption class=\"wp-caption-text\">A couple of custom sections in the theme customizer<\/figcaption><\/figure>\n<p>Note that sections will <em>not<\/em> show up when empty. You must add a setting and a control to them before they are shown.<\/p>\n<h3>Adding Settings<\/h3>\n<p>Settings are created with the <code>add_setting()<\/code> method. They, too, take a slug as the first parameter and an array of arguments as the second. Take a look below for an example of adding a background color to our section above.<\/p>\n<p><span style=\"font-weight: 400;\"><div class=\"gist\" data-gist=\"e8265fcdbd93be1c15d6f82f9c2177fa\" data-gist-file=\"gistfile 1\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/e8265fcdbd93be1c15d6f82f9c2177fa.js?file=gistfile+1\">Loading gist e8265fcdbd93be1c15d6f82f9c2177fa<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/span><\/p>\n<p>There are a bunch of options we could add here but for now this will do just fine. Note that settings are not tied to section. As I mentioned settings are simply registered with WordPress. It is up to controls, which are tied to sections to manipulate them.<\/p>\n<h3>Creating A Control<\/h3>\n<p>Controls are put in place with the <code>add_control()<\/code> method. This method takes a slug and an argument array or it can also receive a dedicated control object. A control object is used for more complex controls such as color selectors or file uploaders.<\/p>\n<p>Here&#8217;s how I created the control which modifies the footer background color:<\/p>\n<div class=\"gist\" data-gist=\"c99ca66b1042995063cd1dd325ec0824\" data-gist-file=\"footer-control.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/c99ca66b1042995063cd1dd325ec0824.js?file=footer-control.php\">Loading gist c99ca66b1042995063cd1dd325ec0824<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>I&#8217;ve passed a control object to the <code>add_control()<\/code> method. This object should be constructed by passing the <code>$wp_customize<\/code> object as the first parameter, a unique ID\u00a0for the control as the second and an array of arguments as the third.<\/p>\n<p>Note that the control is where it all comes together. <code>section<\/code> is set to the id of the section we created and <code>settings<\/code> is set to the id of the setting.<\/p>\n<p>Once all three have been set up, you should be able to reload the customizer and see your work.<\/p>\n<figure id=\"attachment_134390\" class=\"wp-caption aligncenter\" data-caption=\"true\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-134390\" src=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2014\/11\/customizer-controls.png\" alt=\"Some custom options added to a custom section in the customizer\" width=\"293\" height=\"526\" \/><figcaption class=\"wp-caption-text\">Some custom options added to a custom section in the customizer<\/figcaption><\/figure>\n<h2 id=\"using-setting-values\">Using Setting Values<\/h2>\n<p>By default, settings are saved in a theme_mod. Theme_mods are an alternative to the Settings API, they provide an easy way of handling theme-specific settings. All you need to do to retrieve the value of a setting is use the <code>get_theme_mod()<\/code> function with the id of the setting passed to it.<\/p>\n<p>Let&#8217;s add some dynamic CSS to our website by hooking into <code>wp_head<\/code> and using our saved setting:<\/p>\n<p><span style=\"font-weight: 400;\"><div class=\"gist\" data-gist=\"99ce959a70fe6a28c23304ce2174e08b\" data-gist-file=\"user settings\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/99ce959a70fe6a28c23304ce2174e08b.js?file=user+settings\">Loading gist 99ce959a70fe6a28c23304ce2174e08b<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/span><\/p>\n<h2 id=\"live-previews\">Live Previews<\/h2>\n<p>Live previews for settings are not enabled by default. To use them you must do three things:<\/p>\n<ul>\n<li>Enqueue a Javascript file that handles the previews<\/li>\n<li>Add live preview support for setting, and<\/li>\n<li>Create the Javascript code to take care of each setting<\/li>\n<\/ul>\n<h3>Enqueueing The Live Preview Script<\/h3>\n<p>The only irregular thing about this step is that we need to use the <code>customize_preview_init<\/code> and we <em>must<\/em> make sure that &#8216;jquery&#8217; and &#8216;customize-preview&#8217; are loaded before our script. Other than that it&#8217;s a standard enqueue pointing to a javascript file in our theme:<\/p>\n<p><span style=\"font-weight: 400;\"><div class=\"gist\" data-gist=\"335b427cfe9daefe9678c36bc6687aa0\" data-gist-file=\"enqueue\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/335b427cfe9daefe9678c36bc6687aa0.js?file=enqueue\">Loading gist 335b427cfe9daefe9678c36bc6687aa0<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/span><\/p>\n<h3>Add live preview support for setting<\/h3>\n<p>This one is pretty easy. In the arguments for our settings we need to define a <code>transport<\/code> key and set its value to <code>postMessage<\/code>. Let&#8217;s revise our code from before:<\/p>\n<p><span style=\"font-weight: 400;\"><div class=\"gist\" data-gist=\"f303802930a21700861196f420180d62\" data-gist-file=\"gistfile 1\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/f303802930a21700861196f420180d62.js?file=gistfile+1\">Loading gist f303802930a21700861196f420180d62<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/span><\/p>\n<h3>Create the Javascript code to take care of each setting<\/h3>\n<p>We&#8217;ll need to use the <code>wp.customize()<\/code> function in Javascript. This function should be given the id of the setting as the first parameter, the second is a callback function. Inside we bind a function to the change of the setting and write our code which will take care of the change.<\/p>\n<p><span style=\"font-weight: 400;\"><div class=\"gist\" data-gist=\"54cb9e6ea340d7e29cd3132b5449001b\" data-gist-file=\"gistfile 1\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/54cb9e6ea340d7e29cd3132b5449001b.js?file=gistfile+1\">Loading gist 54cb9e6ea340d7e29cd3132b5449001b<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/span><\/p>\n<p>Out of all that we only need to write a line, use this copy-paste template for live preview writing speed:<\/p>\n<p><span style=\"font-weight: 400;\"><div class=\"gist\" data-gist=\"a6b221d151ece2142132e81725e10d26\" data-gist-file=\"gistfile 1\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/a6b221d151ece2142132e81725e10d26.js?file=gistfile+1\">Loading gist a6b221d151ece2142132e81725e10d26<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/span><\/p>\n<h2 id=\"encapsulating-in-a-class\">Encapsulating In a Class<\/h2>\n<p>Encapsulating in a class is a good idea because it allows you to write better function names and to make your code more cross-theme compliant, should you have multiple themes in the works. Here&#8217;s how I did it for our example above.<\/p>\n<p><span style=\"font-weight: 400;\"><div class=\"gist\" data-gist=\"831d2bf7072bca398a0dc36cf8e44363\" data-gist-file=\"gistfile 1\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/831d2bf7072bca398a0dc36cf8e44363.js?file=gistfile+1\">Loading gist 831d2bf7072bca398a0dc36cf8e44363<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/span><\/p>\n<p>Note that everything is exactly the same, all that has changed is the name of some functions and we are referring to methods inside the class instead of functions scattered around in our <code>functions.php<\/code> file.<\/p>\n<h2 id=\"further-options\">Further Options<\/h2>\n<p>I highly recommend reading the documentation on the <a href=\"https:\/\/developer.wordpress.org\/themes\/customize-api\/\" rel=\"noopener\" target=\"_blank\">Theme Customization API<\/a>\u00a0in the WordPress Codex. It contains a lot of additional settings and ways to work with the API.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Creating WordPress Theme Options With the Theme Customization API is easy to do. This article shows you how it&#8217;s done. The WordPress Theme Customization API was released with WordPress 3.4, back in 2012. It promised developers a standardized way of adding rich options themes, and users a way of tweaking their website in a, well, [&hellip;]<\/p>\n","protected":false},"author":344049,"featured_media":206840,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"blog_reading_time":"","wds_primary_category":0,"wds_primary_tutorials_categories":0,"footnotes":""},"categories":[263],"tags":[641,193],"tutorials_categories":[],"class_list":["post-134097","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","tag-free-themes","tag-premium-themes"],"_links":{"self":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts\/134097","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/users\/344049"}],"replies":[{"embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/comments?post=134097"}],"version-history":[{"count":9,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts\/134097\/revisions"}],"predecessor-version":[{"id":206756,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts\/134097\/revisions\/206756"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/media\/206840"}],"wp:attachment":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/media?parent=134097"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/categories?post=134097"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/tags?post=134097"},{"taxonomy":"tutorials_categories","embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/tutorials_categories?post=134097"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}