Cutomize Colors utility: How to add more configurable colors to a theme

So I wrote down the whole process of how I found the answer myself, hope it’s useful to someone (assumes basic unix and programming skills).

Finding where the current color options are defined:

grep -ir 'Header and Sidebar Text Color' .
./wp-content/themes/twentyfifteen/inc/customizer.php:   // Add custom header and sidebar text color setting and control.
./wp-content/themes/twentyfifteen/inc/customizer.php:       'label'       => __( 'Header and Sidebar Text Color', 'twentyfifteen' ),
./wp-content/themes/twentyfifteen/languages/twentyfifteen.pot:msgid "Header and Sidebar Text Color"

So it should be in wp-content/themes/twentyfifteen/inc/customizer.php, the .pot file is for translations which is nice to have, but not important right now.

In wp-content/themes/twentyfifteen/inc/customizer.php there is a comment which explains that there are 6 colors in the color schemes what they are:

The order of colors in a colors array:

  1. Main Background Color.
  2. Sidebar Background Color.
  3. Box Background Color.
  4. Main Text and Link Color.
  5. Sidebar Text and Link Color.
  6. Meta Box Background Color.

Below this comment there is the code which probably could be edited to add more color schemes or change default ones.

Farther down in the file there is this:

'background_color'            => $color_scheme[0],
'header_background_color'     => $color_scheme[1],
'box_background_color'        => $color_scheme[2],
'textcolor'                   => $color_scheme[3],
'secondary_textcolor'         => vsprintf( 'rgba( %1$s, %2$s, %3$s, 0.7)', $color_textcolor_rgb ),
'border_color'                => vsprintf( 'rgba( %1$s, %2$s, %3$s, 0.1)', $color_textcolor_rgb ),
'border_focus_color'          => vsprintf( 'rgba( %1$s, %2$s, %3$s, 0.3)', $color_textcolor_rgb ),
'sidebar_textcolor'           => $color_scheme[4],
'sidebar_border_color'        => vsprintf( 'rgba( %1$s, %2$s, %3$s, 0.1)', $color_sidebar_textcolor_rgb ),
'sidebar_border_focus_color'  => vsprintf( 'rgba( %1$s, %2$s, %3$s, 0.3)', $color_sidebar_textcolor_rgb ),
'secondary_sidebar_textcolor' => vsprintf( 'rgba( %1$s, %2$s, %3$s, 0.7)', $color_sidebar_textcolor_rgb ),
'meta_box_background_color'   => $color_scheme[5],

Which shows that there are additional colours being drived from those 6 variable colors. That could be modified too to make it directly configurable.

Now I need to find out how to register those first 6 colors with the system so I can customize them.

For two of the system provided ones the code seems to be this:

// Add custom header and sidebar text color setting and control.
$wp_customize->add_setting( 'sidebar_textcolor', array(
    'default'           => $color_scheme[4],
    'sanitize_callback' => 'sanitize_hex_color',
    'transport'         => 'postMessage',
) );

$wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'sidebar_textcolor', array(
    'label'       => __( 'Header and Sidebar Text Color', 'twentyfifteen' ),
    'description' => __( 'Applied to the header on small screens and the sidebar on wide screens.', 'twentyfifteen' ),
    'section'     => 'colors',
) ) );

From this I gather:

"$color_scheme[1]" is "Header and Sidebar Background Color"
"$color_scheme[4]" is "Header and Sidebar Text Color"

and I haven’t found the code, but probably

"$color_scheme[0]" is "Background Color"

because that one is labeled “Main Background Color” in the earlier comment.

So I’ll try adding a similar stanza for one of the other entries. I added:

// Add "Box Background Color" color setting and control.
$wp_customize->add_setting( 'box_background_color', array(
    'default'           => $color_scheme[2],
    'sanitize_callback' => 'sanitize_hex_color',
    'transport'         => 'postMessage',
) );

$wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'box_background_color', array(
    'label'       => __( 'Box Background Color', 'twentyfifteen' ),
    'description' => __( 'I don\'t know, maybe the background color of posts/pages?.', 'twentyfifteen' ),
    'section'     => 'colors',
) ) );

“box_background_color” and the $color_scheme[] index are from the array I quoted above, this line:

'box_background_color'        => $color_scheme[2]

The label I took from the comment describing $color_scheme[] and the description I made up.
This adds the controls, but using the controls has no effect. So there must be more code.
In wp-content/themes/twentyfifteen/inc/customizer.php I can’t find anything more, so I compared the outputs of

grep -ir 'box_background_color' .

for several of those color variables. Those which are configurable seem to have more hits in wp-content/themes/twentyfifteen/js/color-scheme-control.js than the others, so I’ll take a look at that file:

/**
 * Add a listener to the Color Scheme control to update other color controls to new values/defaults.
 * Also trigger an update of the Color Scheme CSS when a color is changed.
 */

This seems right, that’s exactly what is still missing. That file had entries for the three already working color pickers in two places:

    colorSettings = [
        'background_color',
        'header_background_color',
        'sidebar_textcolor'
    ];

and here:

                // Update Background Color.
                api( 'background_color' ).set( colorScheme[value].colors[0] );
                api.control( 'background_color' ).container.find( '.color-picker-hex' )
                    .data( 'data-default-color', colorScheme[value].colors[0] )
                    .wpColorPicker( 'defaultColor', colorScheme[value].colors[0] );

(other two omitted)

So I added ‘box_background_color’ to the array:

    colorSettings = [
        'background_color',
        'header_background_color',
        'box_background_color',
        'sidebar_textcolor'
    ];

and duplicated the other section, just changing the color variable name and the color scheme array index:

                // Update Box Background Color Color.
                api( 'box_background_color' ).set( colorScheme[value].colors[2] );
                api.control( 'box_background_color' ).container.find( '.color-picker-hex' )
                    .data( 'data-default-color', colorScheme[value].colors[2] )
                    .wpColorPicker( 'defaultColor', colorScheme[value].colors[2] );

That’s it. Works. đŸ™‚