Adding Options to the Theme Customizer

In the last few days our product roadmap has seen us spending a lot of time getting to grips with the WordPress Customizer API and more specifically, with adding theme customisation options that we want, but aren’t there yet. In this tutorial we’re going to show you how you can use the theme customizer to give the end user complete control of your custom coding.

Building a footer links editor

A topic that comes up all the time in the Divi / Extra forums: How do I change the footer links? For the most part, I’ve encouraged users when asked, to install a child theme and use a custom footer.php file. Simply change the code and you’re good. The two issues with that are:

  1. What if the client want to change them again?
  2. What if Divi updates the footer and I’m losing functionality unless I update my child footer.php file?

In either scenario, if you’re building / maintaining a lot of sites it could get annoying.

So my new approach has been to change the footer links using JS. That way, you no longer need the footer.php file included in your child theme (unless you’re editing other stuff too) and we can include that code in the functions.php file and register a new customizer option to control the output. The following script has been around in some form or another since around Divi 2.2 but still works a treat.

jQuery(document).ready(function(){
jQuery("#footer-info").text(' ');
jQuery('<p id="footer-info">Designed By <a href="http://eleganthemes.com/">Elegant Themes</a> | Powered By <a href="http://wordpress.org/">WordPress</a></p>').insertAfter("#footer-info");
});

What this does is search for the ID ‘footer-info’ and empties it of its current text, it then adds custom text in its place. You could change the links and text in the above code and it’ll override what’s currently there. The beauty of this is its exactly the same for Extra too so we have a scenario where one solution fits all.

You still have the problem that its not exactly an easy change for someone that doesn’t like dipping into code, so what we’re going to do is swap out the text, links and link divider for php variables which we can then attach to customizer options. Sounds complicated but follow along.

Variables are just containers for storing information held somewhere else. For example:

<?php
$black = "#010101";
?>
<style type="text/css">
#main-header {
    background: <?php echo $black; ?>;
}

In this example we have replaced the color value in the CSS with a variable. We could use that $black variable throughout our document and only have to change what the value is equal to in one place. So now let’s look how we can assign variables to our JS code.

We’re going to replace 7 pieces of information with variables;

function ds_tutorial_footer() {

$footer_one = 'Designed By';
$footer_two = 'Elegant Themes';
$footer_link_one = 'http://www.elegantthemes.com/';
$footer_three = 'Powered By';
$footer_four = 'WordPress';
$footer_link_two = 'https://wordpress.org/';
$footer_divider = '|';

?>

<script type="text/javascript">
jQuery(document).ready(function(){
jQuery("#footer-info").text(' ');
jQuery('<p id="footer-info"><?php echo $footer_one; ?> <a href="<?php echo $footer_link_one; ?>"><?php echo $footer_two; ?></a> <?php echo $footer_divider; ?> <?php echo $footer_three; ?> <a href="<?php echo $footer_link_two; ?>"><?php echo $footer_four; ?></a></p>').insertAfter("#footer-info");
});
</script>

<?php
}

add_action( 'wp_head', 'ds_tutorial_footer' );

So as you can see, in the JS script we have replaced each link, the text before each link and the link divider with variables and have entered their default text as the variable values for now.

The next step is to register a new customizer option where the end user can update the value associated with each of those variables to anything they like.

Registering a new customizer option

function ds_tutorial_links_editor($wp_customize) {
 
 $wp_customize->add_panel( 'footer_links_option', array(
 'priority' => 30,
 'capability' => 'edit_theme_options',
 'title' => __('Edit Footer Links', footer_links_title),
 'description' => __('Customize the login of your website.', footer_links_title),
 ));

This is how we register a new panel. A panel is the top most level available in the theme customizer and looks like this:

panel
  • Google+
  • Facebook
  • Twitter

In the panel set-up we need to pass some information:

add_panel = give the panel a name.

Priority = where we would like it to appear in the list of other theme option panels. Adjust this number to move it up and down the list.

Capability = leave set to ‘edit theme options’.

Title and description should be self explanatory. The description will appear when you hover over the small question mark next to the title.

Each panel will be made up of a section or series of sections. We’re just going to add one section called ‘Footer Links Editor.

 $wp_customize->add_section('ds_footer_links_section', array(
 'priority' => 5,
 'title' => __('Footer Links Editor', footer_links_title),
 'panel' => 'footer_links_option',
 ));

Sections have their own information we need to include too.

Priority = Where it should appear in the list of other sections in the panel. As we’re only registering one, this isn’t a big deal.

Title = Self explanatory

Panel = What is the name of the panel the section should be added to?

So a panel houses a section / sections and a section houses settings. Here’s what our settings will look like:

options
  • Google+
  • Facebook
  • Twitter

Each option has ‘settings’ and ‘controls’. This is how they are set…

 // Before Link One
 $wp_customize->add_setting('ds_footer_links_before_link_one', array(
 'default' => 'Designed By',
 'type' => 'option',
 'capability' => 'edit_theme_options',
 ));

 $wp_customize->add_control('ds_footer_links_before_link_one', array(
 'label' => __('Text Before First Link', footer_links_title),
 'section' => 'ds_footer_links_section',
 'type' => 'option',
 'priority' => 5,
 'settings' => 'ds_footer_links_before_link_one'
 ));

And again we need to add some information to get our option working –

We need to name the setting and the control. We need to assign what we want the default text in our box to be and what ‘type’ of box it should be. The customizer comes with a bunch of prebuilt options such as colour picker, text area, check-box etc. You can learn more about what else is possible here.

We can organise the controls in each section with a priority too. Our seven controls will each have a different priority starting at 5 (top) going down to 35 (bottom).

So our panel, section, settings and controls look like this:

function ds_tutorial_links_editor($wp_customize) {
 
 $wp_customize->add_panel( 'footer_links_option', array(
 'priority' => 30,
 'capability' => 'edit_theme_options',
 'title' => __('Edit Footer Links', footer_links_title),
 'description' => __('Customize the login of your website.', footer_links_title),
 ));
 
 $wp_customize->add_section('ds_footer_links_section', array(
 'priority' => 5,
 'title' => __('Footer Links Editor', footer_links_title),
 'panel' => 'footer_links_option',
 ));
 // Before Link One
 $wp_customize->add_setting('ds_footer_links_before_link_one', array(
 'default' => 'Designed By',
 'type' => 'option',
 'capability' => 'edit_theme_options',
 ));

 $wp_customize->add_control('ds_footer_links_before_link_one', array(
 'label' => __('Text Before First Link', footer_links_title),
 'section' => 'ds_footer_links_section',
 'type' => 'option',
 'priority' => 5,
 'settings' => 'ds_footer_links_before_link_one'
 ));
 // Link One 
 $wp_customize->add_setting('ds_footer_links_link_one', array(
 'default' => 'Elegant Themes',
 'type' => 'option',
 'capability' => 'edit_theme_options',
 ));

 $wp_customize->add_control('ds_footer_links_link_one', array(
 'label' => __('First Link Text', footer_links_title),
 'section' => 'ds_footer_links_section',
 'type' => 'option',
 'priority' => 10,
 'settings' => 'ds_footer_links_link_one'
 ));
 // Link One URL 
 $wp_customize->add_setting('ds_footer_link_one_url', array(
 'default' => '#',
 'type' => 'option',
 'capability' => 'edit_theme_options',
 ));

 $wp_customize->add_control('ds_footer_link_one_url', array(
 'label' => __('First Link URL', footer_links_title),
 'section' => 'ds_footer_links_section',
 'type' => 'option',
 'priority' => 15,
 'settings' => 'ds_footer_link_one_url'
 ));
// Before Link Two
 $wp_customize->add_setting('ds_footer_links_before_link_two', array(
 'default' => 'Powered By',
 'type' => 'option',
 'capability' => 'edit_theme_options',
 ));

 $wp_customize->add_control('ds_footer_links_before_link_two', array(
 'label' => __('Text Before Second Link', footer_links_title),
 'section' => 'ds_footer_links_section',
 'type' => 'option',
 'priority' => 20,
 'settings' => 'ds_footer_links_before_link_two'
 ));
 // Link Two
 $wp_customize->add_setting('ds_footer_links_link_two', array(
 'default' => 'WordPress',
 'type' => 'option',
 'capability' => 'edit_theme_options',
 ));

 $wp_customize->add_control('ds_footer_links_link_two', array(
 'label' => __('Second Link Text', footer_links_title),
 'section' => 'ds_footer_links_section',
 'type' => 'option',
 'priority' => 25,
 'settings' => 'ds_footer_links_link_two'
 ));
 // Link Two URL 
 $wp_customize->add_setting('ds_footer_link_two_url', array(
 'default' => '###',
 'type' => 'option',
 'capability' => 'edit_theme_options',
 ));
 
 $wp_customize->add_control('ds_footer_link_two_url', array(
 'label' => __('Second Link URL', footer_links_title),
 'section' => 'ds_footer_links_section',
 'type' => 'option',
 'priority' => 30,
 'settings' => 'ds_footer_link_two_url'
 ));
 // Footer Divider 
 $wp_customize->add_setting('ds_footer_link_divider', array(
 'default' => '|',
 'type' => 'option',
 'capability' => 'edit_theme_options',
 ));
 
 $wp_customize->add_control('ds_footer_link_divider', array(
 'label' => __('Footer Link Divider', footer_links_title),
 'section' => 'ds_footer_links_section',
 'type' => 'option',
 'priority' => 35,
 'settings' => 'ds_footer_link_divider'
 ));
}

add_action('customize_register', 'ds_tutorial_links_editor');

The important part we haven’t mentioned is to finish off with an action, registering our new customizer option.

Attaching variables to customizer settings

So we’re almost there. We have a new customizer panel registered with seven new ‘options’, ready to attach to the seven variables we created earlier, that in turn will populate the content of our new JS powered footer text. Here’s how we edit our variables from earlier:

// before
$footer_one = 'Designed By';

//after
$footer_one = get_option('ds_footer_links_before_link_one','Designed By');

There’s a few things going on here:

Firstly, we’ve told the variable to get it’s data from the ‘ds_footer_links_before_link_one’ option we created earlier, if you scroll back up you’ll see that that was the name we gave to the first setting and control in our new customizer options array.

Next, we’ve added the ‘Designed By’ text to the secondary position, which means the variable will only show that until we override it by updating it in the customizer options.

We can go through and link each of our variables to their option and then we can change the variable value from the customizer! Perfect for those who don’t want their clients digging around in the code to make changes.

If you’d like to add this functionality to your child theme, here is the complete code for your functions.php file.

<?php

// ====================== Footer Editor ======================

function ds_footer_links_editor($wp_customize) {
 
 $wp_customize->add_panel( 'footer_links_option', array(
 'priority' => 30,
 'capability' => 'edit_theme_options',
 'title' => __('Edit Footer Links', footer_links_title),
 'description' => __('Customize the login of your website.', footer_links_title),
 ));
 
 $wp_customize->add_section('ds_footer_links_section', array(
 'priority' => 5,
 'title' => __('Footer Links Editor', footer_links_title),
 'panel' => 'footer_links_option',
 ));
 // Before Link One
 $wp_customize->add_setting('ds_footer_links_before_link_one', array(
 'default' => 'Designed By',
 'type' => 'option',
 'capability' => 'edit_theme_options',
 ));

 $wp_customize->add_control('ds_footer_links_before_link_one', array(
 'label' => __('Text Before First Link', footer_links_title),
 'section' => 'ds_footer_links_section',
 'type' => 'option',
 'priority' => 5,
 'settings' => 'ds_footer_links_before_link_one'
 ));
 // Link One 
 $wp_customize->add_setting('ds_footer_links_link_one', array(
 'default' => 'Elegant Themes',
 'type' => 'option',
 'capability' => 'edit_theme_options',
 ));

 $wp_customize->add_control('ds_footer_links_link_one', array(
 'label' => __('First Link Text', footer_links_title),
 'section' => 'ds_footer_links_section',
 'type' => 'option',
 'priority' => 10,
 'settings' => 'ds_footer_links_link_one'
 ));
 // Link One URL 
 $wp_customize->add_setting('ds_footer_link_one_url', array(
 'default' => '#',
 'type' => 'option',
 'capability' => 'edit_theme_options',
 ));

 $wp_customize->add_control('ds_footer_link_one_url', array(
 'label' => __('First Link URL', footer_links_title),
 'section' => 'ds_footer_links_section',
 'type' => 'option',
 'priority' => 15,
 'settings' => 'ds_footer_link_one_url'
 ));
// Before Link Two
 $wp_customize->add_setting('ds_footer_links_before_link_two', array(
 'default' => 'Powered By',
 'type' => 'option',
 'capability' => 'edit_theme_options',
 ));

 $wp_customize->add_control('ds_footer_links_before_link_two', array(
 'label' => __('Text Before Second Link', footer_links_title),
 'section' => 'ds_footer_links_section',
 'type' => 'option',
 'priority' => 20,
 'settings' => 'ds_footer_links_before_link_two'
 ));
 // Link Two
 $wp_customize->add_setting('ds_footer_links_link_two', array(
 'default' => 'WordPress',
 'type' => 'option',
 'capability' => 'edit_theme_options',
 ));

 $wp_customize->add_control('ds_footer_links_link_two', array(
 'label' => __('Second Link Text', footer_links_title),
 'section' => 'ds_footer_links_section',
 'type' => 'option',
 'priority' => 25,
 'settings' => 'ds_footer_links_link_two'
 ));
 // Link Two URL 
 $wp_customize->add_setting('ds_footer_link_two_url', array(
 'default' => '###',
 'type' => 'option',
 'capability' => 'edit_theme_options',
 ));
 
 $wp_customize->add_control('ds_footer_link_two_url', array(
 'label' => __('Second Link URL', footer_links_title),
 'section' => 'ds_footer_links_section',
 'type' => 'option',
 'priority' => 30,
 'settings' => 'ds_footer_link_two_url'
 ));
 // Footer Divider 
 $wp_customize->add_setting('ds_footer_link_divider', array(
 'default' => '|',
 'type' => 'option',
 'capability' => 'edit_theme_options',
 ));
 
 $wp_customize->add_control('ds_footer_link_divider', array(
 'label' => __('Footer Link Divider', footer_links_title),
 'section' => 'ds_footer_links_section',
 'type' => 'option',
 'priority' => 35,
 'settings' => 'ds_footer_link_divider'
 ));
}

add_action('customize_register', 'ds_footer_links_editor');

function ds_new_bottom_footer() {
 
$footer_one = get_option('ds_footer_links_before_link_one','Designed By');
$footer_two = get_option('ds_footer_links_link_one','Elegant Themes');
$footer_link_one = get_option('ds_footer_link_one_url','http://www.elegantthemes.com/');
$footer_three = get_option('ds_footer_links_before_link_two','Powered By');
$footer_four = get_option('ds_footer_links_link_two', 'WordPress');
$footer_link_two = get_option('ds_footer_link_two_url', 'https://wordpress.org/');
$footer_divider = get_option('ds_footer_link_divider','|');
 
?>

<script type="text/javascript">
jQuery(document).ready(function(){
jQuery("#footer-info").text(' ');
jQuery('<p id="footer-info"><?php echo $footer_one; ?> <a href="<?php echo $footer_link_one; ?>"><?php echo $footer_two; ?></a> <?php echo $footer_divider; ?> <?php echo $footer_three; ?> <a href="<?php echo $footer_link_two; ?>"><?php echo $footer_four; ?></a></p>').insertAfter("#footer-info");
});
</script>

<?php
}

add_action( 'wp_head', 'ds_new_bottom_footer' );
?>

I hope you found this useful 🙂 Let me know in the comments if you use it.

Stephen James

SJ is a web developer living in the coastal town of Southsea, England. He is a Divi and WordPress advocate and the founder of Divi Space.

Previous post
Next post

6 Comments

  1. Michael Langham

    Thanks for this shortcut Stephen.

    Much appreciated. You have just earned an image-optimizing credit in exchange should you have a need. 🙂

    Reply
  2. Sue F

    How about posting instructions as to exactly how to install and use your plug-in, Pagebuilder Everywhere?

    Reply
  3. jason

    SWEET! I’ve been waiting for a tutorial like this!

    Reply
  4. John

    Hi, Stephen.

    Thanks for the article, really useful info here. Can you explain why you use ‘type’ => ‘option’and get_option() but not the ‘type’ => ‘theme_mode’ and get_theme_mod() ?
    And the second question: will these additional settings of Child Theme be exported/imported together with the rest of settings(Divi’s native Customizer settings) in the same .json file?
    Thanks.

    Reply
  5. Bill

    Thanks Stephen for this great tutorial

    Reply

Submit a Comment

Your email address will not be published. Required fields are marked *

Receive notifications about our new blog posts.