16

Say I have a single custom control, but this control has 2 inputs that require saving, e.g.:

  • Currency type and value
  • Size and unit of measurement
  • First and last name
  • Text and style
  • Image and image size
  • Font family & font weight

How would I do it? I see there is a settings option when creating a control, but there is no documentation to suggest how it's used, and the only example of it being done in the wild is Easy Google Fonts, which has no explanation as to how it's done, and is difficult to read. Is it possible to nest controls and sections?

So far all the tutorials and documentation I've found talk about a control with a single html input, none mention controls that have multiple inputs/settings, despite it being suggested by the API

2

1 Answer 1

18

This plugin demonstrates how to do it. Of note, the steps involved are:

  • Register each setting to update/change
  • When creating the control, pass an array as the setting argument
  • When rendering the inputs, pass in the settings key to link and value
  • The settings key is not the name of the setting, but the indices of the array, e.g. 0, 1, 2
  • Access the settings registered to a control via $this->settings

Here's the code:

<?php
/*
Plugin Name: TJN Typography Control Demo
Author: Tom J Nowell
Author URI: https://www.tomjn.com/
Version: 1.1
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
*/

add_action( 'customize_register', 'tjn_customize_register' );
function tjn_customize_register( $wp_customize ) {
    if ( ! isset( $wp_customize ) ) {
        return;
    }
    if ( class_exists( 'WP_Customize_Control' ) ) {

        class Toms_Control_Builder extends WP_Customize_Control {

            public $html = array();

            public function build_field_html( $key, $setting ) {
                $value = '';
                if ( isset( $this->settings[ $key ] ) ) {
                    $value = $this->settings[ $key ]->value();
                }

                $this->html[] = '<div><input type="text" value="' . esc_attr( $value ) . '" '.$this->get_link( $key ).' /></div>';
            }

            public function render_content() {
                echo '<label>' . esc_html( $this->label ) . '</label>';
                foreach( $this->settings as $key => $value ) {
                    $this->build_field_html( $key, $value );
                }
                echo implode( '', $this->html );
            }

        }

        $section = new TJN_Customizer_Section( $wp_customize, 'test', 'Test', 11 );
        $field = new TJN_Customizer_Field( 'testfield', '', __( 'Test Control', 'wpse_tomjn' ) );
        $field->add_to_section( $wp_customize, $section );
    }
}

class TJN_Customizer_Section {
    public $name='';
    public $pretty_name='';

    public function __construct( WP_Customize_Manager $wp_customize, $name, $pretty_name, $priority=25 ) {
        $this->name = $name;
        $this->pretty_name = $pretty_name;

        $wp_customize->add_section( $this->getName(), array(
            'title'          => $pretty_name,
            'priority'       => $priority,
            'transport'      => 'refresh'
        ) );
    }

    public function getName() : string {
        return $this->name;
    }

    public function getPrettyName() : string {
        return $this->pretty_name;
    }
}

class TJN_Customizer_Field {

    private $name;
    private $default;
    private $pretty_name;

    public function __construct( $name, $default, $pretty_name ) {
        $this->name = $name;
        $this->default = $default;
        $this->pretty_name = $pretty_name;
    }

    public function add_to_section( WP_Customize_Manager $wp_customize, TJN_Customizer_Section $section ) : void {

        $wp_customize->add_setting( $this->name, array(
            'default'        => $this->default,
            'type'           => 'theme_mod',
            'capability'     => 'edit_theme_options'
        ) );
        $wp_customize->add_setting( 'moomins', array(
            'default'        => $this->default,
            'type'           => 'theme_mod',
            'capability'     => 'edit_theme_options'
        ) );
        $wp_customize->add_setting( 'papa', array(
            'default'        => $this->default,
            'type'           => 'theme_mod',
            'capability'     => 'edit_theme_options'
        ) );

        $control = new Toms_Control_Builder(
            $wp_customize, $this->name, array(
            'label'    => $this->pretty_name,
            'section'  => $section->getName(),
            'settings'   => array (
                $this->name,
                'moomins',
                'papa'
            )
        ) );

        $wp_customize->add_control( $control );
    }
}

Note though that in modern WP the example of typography is best handled using theme.json and global styles

1
  • 2
    Just what I needed, Now I can go to sleep in peace
    – chifliiiii
    Commented Jul 3, 2015 at 3:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.