How to Add Customizer Panels, Sections & Controls

WordPress Customizer Controls are the form elements that you see inside the WordPress Customizer which provide options such as color pickers, layouts, styling and widget area selectors . These Controls get assigned to accordion-like groups for organization (panels), making it easier for user to find the options they want.

Customizer controls may be added in both Extensions and Child Themes. The following assumes you have already setup your Child Theme or Layers Extension and are at the point where you are adding custom functions.

Defaults

You may add defaults for the pre-existing Layers controls via the layers_customizer_control_defaults hook as described in the Styling section of this guide. This is recommended in Child Themes where you need to reset the default color controls to ensure your CSS is honored. Click the hook link above to view detailed instructions.

Panels, Sections and Controls

To understand where your customizations will appear, and which element you need to add, the following illustrates the terms we use:

Panel

Section

Control

Option

The first tier, high level, groups are know as Panels, and those inside them are called Sections, and finally those open up to reveal the Controls containing all the options. WordPress allows theme and plugin developers to add sections and panels using the add_section() function. Controls are then added to these sections by first registering a ‘theme_mod’ type setting using add_setting() and then assigning the setting to a Control usingadd_control() that will decide how the setting is presented to the user.

We make this process easier by providing a set of filters and keys for building custom controls in a more efficient way.

You can choose to add custom panels to house your new sections and controls, or you can add sections to existing panels or controls to existing sections. Adding to our config array will neatly initialize your controls at the same time the Layers controls are initialized.

Filter Structure

Plugin

You first need to create a custom class to hold your controls inside a new file which we call controls.php.This class is setup just like the main plugin class.

Back to your controls class, setup a handful of helper filters for the panels, sections and controls inside your constructor or initializer. For demonstration we will use init() here so you can see the (small) difference between init() and __construct(). These filters can be used as shown here.

Line 1: Safety condition ensures a conflict does not occur if a function with the same name is already run. Choosing unique function names helps avoid this too.

Line 2: setup your function to modify the $panels index.

Line 3: Set the key or name for your panel, ie ‘mytheme-theme-options’. These should be lower-case and use only – or _ to separate words.

Line 4: Set the ‘title’ for your section that displays in the Customizer. Strings should always use l10n methods, ie__('string','textdomain')

Line 5: Set the ‘description’ (optional). This is a short bit of text you can use as instruction or clarification.

Line 6: Set the ‘priority’ which is a numeric value that determines where the panel sits sin the list. 130 is a safe choice as it ensures your panel loads below and after the core Layers panels.

Custom Sections

Reference: layers_customizer_sections

Plugin

PHP

1

2

3

4

5

6

7

8

9

10

11

12

/**

* Add Customizer Section

*/

publicfunctionmodify_customizer_sections($sections){

$sections['cpt-options']=array(

'title'=>__('Custom Post Type Options',LAYERS_DEMO_EXTENSION_SLUG),

'panel'=>'demoextension',

);

return$sections;

}

The panel value corresponds to the $panels key, set in the above section as demoextension . If you are not creating a custom panel, then this would be a layers panel ID (see the linked reference above)

Child Theme

Each section should define a title and the panel it will be added to. This example shows how you would add a custom section called header-social-media (Social Media Profiles) to our custom panel called demoextension (Demo Extension)

PHP

1

2

3

4

5

6

7

8

9

if(!function_exists('layers_child_customizer_sections')){

functionlayers_child_customizer_sections($sections){

$sections['header-social-media']=array(

'title'=>__('Social Media Profiles','layers-child-demo'),

'panel'=>'demoextension',

);

return$sections;

}

}

Adding Sections to Existing Panels

This example shows how you would add our custom section called header-social-media (Social Media Profiles) to the existing Header ( header ) panel in Layers. The primary difference here is the array_merge which takes your section and merges it with the existing ones. You must merge on existing panels, whereas you don’t if using a custom panel.

PHP

1

2

3

4

5

6

7

8

9

10

11

if(!function_exists('layers_child_customizer_sections')){

functionlayers_child_customizer_sections($sections){

$sections['header-social-media']=array(

'title'=>__('Social Media Profiles','layers-child-demo'),

'panel'=>'header',

);

$sections=array_merge($sections,$sections['header-social-media']);

return$sections;

}

}

The following panels are created by Layers:

Panel: Site Settingssite-settings
Panel: Headerheader
Panel: Blog

PHP

1

blog-archive-single

Panel: Footerfooter
Panel: WooCommercewoocommerce
You can also add custom sections to existing non-Layers panels like the default WordPress panels using the WordPress Core API instead of the Layers filters.

Custom Controls

Reference: layers_customizer_controls

Plugin

In our extension tutorial, we create a custom post type and add a few custom fields to it like a Credit Name, URL and Photo description. Our custom controls will add the option to show or hide this meta on single posts using our post type, in addition to basic meta like the date or sidebars.

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

/**

* Add Customizer Controls

*/

publicfunctionmodify_customizer_controls($controls){

$demo_extension_controls['cpt-options']=array(

'demo-post-options-heading-styling'=>array(

'type'=>'layers-heading',

'heading_divider'=>__('Display','layers-pro').$showcase_badge,

'description'=>__('Choose what you display on your single demoextension page.',LAYERS_DEMO_EXTENSION_SLUG),

),

'demo-post-single-credit'=>array(

'type'=>'layers-checkbox',

'label'=>__('Credit',LAYERS_DEMO_EXTENSION_SLUG),

'default'=>'yes',

),

'demo-post-single-source'=>array(

'type'=>'layers-checkbox',

'label'=>__('Source',LAYERS_DEMO_EXTENSION_SLUG),

'default'=>'yes',

),

'demo-post-description'=>array(

'type'=>'layers-checkbox',

'label'=>__('Description',LAYERS_DEMO_EXTENSION_SLUG),

'default'=>'yes',

),

'demo-post-single-date'=>array(

'type'=>'layers-checkbox',

'label'=>__('Dates',LAYERS_DEMO_EXTENSION_SLUG),

'default'=>'yes',

),

'demo-post-single-sidebar'=>array(

'type'=>'layers-checkbox',

'label'=>__('Sidebar',LAYERS_DEMO_EXTENSION_SLUG),

'default'=>'yes',

),

);

returnarray_merge_recursive($controls,$demo_extension_controls);

}

The important bit here is the array merge, which takes these custom controls and adds them to the overall controls array for loading.

Each control group uses an array to define itself, ie demo-post-options . At a minimum you need a type and label within each individual option.

Child Theme

This example shows how you would add some text fields for entering Social Network URLs in the custom section header-social-media referenced in our custom section above:

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

if(!function_exists('layers_child_customizer_controls')){

functionlayers_child_customizer_controls($controls){

$controls['header-social-media']=array(

'social-twitter'=>array(

'type'=>'layers-text',

'label'=>__('Twitter Username','layers-child-demo')

),

'social-facebook'=>array(

'type'=>'layers-text',

'label'=>__('Facebook Vanity URL','layers-child-demo')

),

'social-instagram'=>array(

'type'=>'layers-text',

'label'=>__('Instagram Username','layers-child-demo')

)

);

return$controls;

}

}

$controls [‘section-name’] = In our example, our section is called header-social-media . Each option sets up its own array that must have a title and label.

label

placeholder

Used in combination with a type of layers-text , layers-textarea , layers-rte or layers-code element, and sets some default text inside the field to use an example or instructions.

PHP

1

'placeholder'=>"Enter URL",

description

Long-form text describing what your control is used for (optional). Descriptions should be formatted with sprintf and use l10n

PHP

1

2

'description'=>sprintf(__('For more information, see <a href="%s" target="_blank">follow this link</a>.','yourtheme_textdonmain'),'http://www.your-url.com'),

)

choices

Used in combination with a selecttype to define the drop-down options. The below example shows how we add a Widget Areas option using the layers-select type and populate the drop-down with 0-4 using choices.

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

'footer-sidebar-count'=>array(

'type'=>'layers-select',

'label'=>__('Widget Areas','layerswp'),

'default'=>4,

'sanitize_callback'=>'layers_sanitize_number',

'choices'=>array(

'0'=>__('None','layerswp'),

'1'=>__('1','layerswp'),

'2'=>__('2','layerswp'),

'3'=>__('3','layerswp'),

'4'=>__('4','layerswp'),

)

)// layout

Adding Controls to Existing Sections

In the above example we set the section name in the $controls array, then return $controls. When adding controls to an existing section, we need to use an array_merge before returning the $controls to set the section.

Removing or De-registering Existing Controls

Setting Selectors for Color Controls

If you have setup a custom control with a type of layers-color , you will need to link it to the element it needs to modify, then output the CSS correctly using layers_inline_styles . This ensures the customizer option overrides everything else, absolutely. It also allows you to tap into the invert control that helps text elements adjust automatically depending on if the user chooses a light or dark background color. This can help you set shortcuts and cut down on the number of color controls.

The first value wp_enqueue_scripts allows you to hook your function into the pre-existing lineup of scripts and let’s WordPress manage when the script fires and where in the source it is output. The second value defines your function name and the third is the priority. 100 is a safe number and is more important to plugin authors.

Line 1-2 : The above example creates a new functionlayers_child_customizer_styles

Line 3: Set up a variable$widget_title_color
that will represent the user’s choice. We uselayers_get_theme_mod()
to grab our custom controlwidget-title-color
defined on line 4 (assuming we created one with this key name using the above Custom Control methods)

Line 5:TRUE corresponds to$allow_empty and should always be true for colors, so don’t worry about that!

Line 7: A condition to ensure the option is set. If it is blank, no inline CSS will be output.

Using Option Settings on the Front-End

To utilize a setting in the front end on Layers, we use a helper function called layers_get_theme_mod() which works just like the WordPress core get_option().

Plugin

Each $option for layers_get_theme_mod($option) is the custom option name you setup in your custom controls array. This example shows how we would use a condition to determine whether a sidebar is added to the demo post view depending on the option choice.

PHP

1

2

3

<?phpif(''!=layers_get_theme_mod('demo-post-single-sidebar')){

get_sidebar('right');

}?>

Child Theme

In the following example we will add some social icons, corresponding to the networks set in these options, to the header of Layers using the layers_after_logo hook. This goes into your functons.php or plugin class where all other hooks are set.