Initial commit

This commit is contained in:
Alexander Agnarson 2020-03-11 14:44:42 +01:00
commit b0607606ae
369 changed files with 85494 additions and 0 deletions

View file

@ -0,0 +1,126 @@
<?php
/**
* Customizer Control: background.
*
* Creates a new custom control.
* Custom controls contains all background-related options.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 1.0
*/
/**
* Adds multiple input fiels that combined make up the background control.
*/
class Kirki_Control_Background extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-background';
/**
* An Underscore (JS) template for this control's content (but not its container).
*
* Class variables for this control class are available in the `data` JS object;
* export custom variables by overriding {@see WP_Customize_Control::to_json()}.
*
* @see WP_Customize_Control::print_template()
*
* @access protected
*/
protected function content_template() {
?>
<label>
<span class="customize-control-title">{{{ data.label }}}</span>
<# if ( data.description ) { #><span class="description customize-control-description">{{{ data.description }}}</span><# } #>
</label>
<div class="background-wrapper">
<!-- background-color -->
<div class="background-color">
<h4><?php esc_html_e( 'Background Color', 'kirki' ); ?></h4>
<input type="text" data-default-color="{{ data.default['background-color'] }}" data-alpha="true" value="{{ data.value['background-color'] }}" class="kirki-color-control"/>
</div>
<!-- background-image -->
<div class="background-image">
<h4><?php esc_html_e( 'Background Image', 'kirki' ); ?></h4>
<div class="attachment-media-view background-image-upload">
<# if ( data.value['background-image'] ) { #>
<div class="thumbnail thumbnail-image"><img src="{{ data.value['background-image'] }}"/></div>
<# } else { #>
<div class="placeholder"><?php esc_html_e( 'No File Selected', 'kirki' ); ?></div>
<# } #>
<div class="actions">
<button class="button background-image-upload-remove-button<# if ( ! data.value['background-image'] ) { #> hidden <# } #>"><?php esc_html_e( 'Remove', 'kirki' ); ?></button>
<button type="button" class="button background-image-upload-button"><?php esc_html_e( 'Select File', 'kirki' ); ?></button>
</div>
</div>
</div>
<!-- background-repeat -->
<div class="background-repeat">
<h4><?php esc_html_e( 'Background Repeat', 'kirki' ); ?></h4>
<select {{{ data.inputAttrs }}}>
<option value="no-repeat"<# if ( 'no-repeat' === data.value['background-repeat'] ) { #> selected <# } #>><?php esc_html_e( 'No Repeat', 'kirki' ); ?></option>
<option value="repeat"<# if ( 'repeat' === data.value['background-repeat'] ) { #> selected <# } #>><?php esc_html_e( 'Repeat All', 'kirki' ); ?></option>
<option value="repeat-x"<# if ( 'repeat-x' === data.value['background-repeat'] ) { #> selected <# } #>><?php esc_html_e( 'Repeat Horizontally', 'kirki' ); ?></option>
<option value="repeat-y"<# if ( 'repeat-y' === data.value['background-repeat'] ) { #> selected <# } #>><?php esc_html_e( 'Repeat Vertically', 'kirki' ); ?></option>
</select>
</div>
<!-- background-position -->
<div class="background-position">
<h4><?php esc_html_e( 'Background Position', 'kirki' ); ?></h4>
<select {{{ data.inputAttrs }}}>
<option value="left top"<# if ( 'left top' === data.value['background-position'] ) { #> selected <# } #>><?php esc_html_e( 'Left Top', 'kirki' ); ?></option>
<option value="left center"<# if ( 'left center' === data.value['background-position'] ) { #> selected <# } #>><?php esc_html_e( 'Left Center', 'kirki' ); ?></option>
<option value="left bottom"<# if ( 'left bottom' === data.value['background-position'] ) { #> selected <# } #>><?php esc_html_e( 'Left Bottom', 'kirki' ); ?></option>
<option value="right top"<# if ( 'right top' === data.value['background-position'] ) { #> selected <# } #>><?php esc_html_e( 'Right Top', 'kirki' ); ?></option>
<option value="right center"<# if ( 'right center' === data.value['background-position'] ) { #> selected <# } #>><?php esc_html_e( 'Right Center', 'kirki' ); ?></option>
<option value="right bottom"<# if ( 'right bottom' === data.value['background-position'] ) { #> selected <# } #>><?php esc_html_e( 'Right Bottom', 'kirki' ); ?></option>
<option value="center top"<# if ( 'center top' === data.value['background-position'] ) { #> selected <# } #>><?php esc_html_e( 'Center Top', 'kirki' ); ?></option>
<option value="center center"<# if ( 'center center' === data.value['background-position'] ) { #> selected <# } #>><?php esc_html_e( 'Center Center', 'kirki' ); ?></option>
<option value="center bottom"<# if ( 'center bottom' === data.value['background-position'] ) { #> selected <# } #>><?php esc_html_e( 'Center Bottom', 'kirki' ); ?></option>
</select>
</div>
<!-- background-size -->
<div class="background-size">
<h4><?php esc_html_e( 'Background Size', 'kirki' ); ?></h4>
<div class="buttonset">
<input {{{ data.inputAttrs }}} class="switch-input screen-reader-text" type="radio" value="cover" name="_customize-bg-{{{ data.id }}}-size" id="{{ data.id }}cover" <# if ( 'cover' === data.value['background-size'] ) { #> checked="checked" <# } #>>
<label class="switch-label switch-label-<# if ( 'cover' === data.value['background-size'] ) { #>on <# } else { #>off<# } #>" for="{{ data.id }}cover"><?php esc_html_e( 'Cover', 'kirki' ); ?></label>
</input>
<input {{{ data.inputAttrs }}} class="switch-input screen-reader-text" type="radio" value="contain" name="_customize-bg-{{{ data.id }}}-size" id="{{ data.id }}contain" <# if ( 'contain' === data.value['background-size'] ) { #> checked="checked" <# } #>>
<label class="switch-label switch-label-<# if ( 'contain' === data.value['background-size'] ) { #>on <# } else { #>off<# } #>" for="{{ data.id }}contain"><?php esc_html_e( 'Contain', 'kirki' ); ?></label>
</input>
<input {{{ data.inputAttrs }}} class="switch-input screen-reader-text" type="radio" value="auto" name="_customize-bg-{{{ data.id }}}-size" id="{{ data.id }}auto" <# if ( 'auto' === data.value['background-size'] ) { #> checked="checked" <# } #>>
<label class="switch-label switch-label-<# if ( 'auto' === data.value['background-size'] ) { #>on <# } else { #>off<# } #>" for="{{ data.id }}auto"><?php esc_html_e( 'Auto', 'kirki' ); ?></label>
</input>
</div>
</div>
<!-- background-attachment -->
<div class="background-attachment">
<h4><?php esc_html_e( 'Background Attachment', 'kirki' ); ?></h4>
<div class="buttonset">
<input {{{ data.inputAttrs }}} class="switch-input screen-reader-text" type="radio" value="scroll" name="_customize-bg-{{{ data.id }}}-attachment" id="{{ data.id }}scroll" <# if ( 'scroll' === data.value['background-attachment'] ) { #> checked="checked" <# } #>>
<label class="switch-label switch-label-<# if ( 'scroll' === data.value['background-attachment'] ) { #>on <# } else { #>off<# } #>" for="{{ data.id }}scroll"><?php esc_html_e( 'Scroll', 'kirki' ); ?></label>
</input>
<input {{{ data.inputAttrs }}} class="switch-input screen-reader-text" type="radio" value="fixed" name="_customize-bg-{{{ data.id }}}-attachment" id="{{ data.id }}fixed" <# if ( 'fixed' === data.value['background-attachment'] ) { #> checked="checked" <# } #>>
<label class="switch-label switch-label-<# if ( 'fixed' === data.value['background-attachment'] ) { #>on <# } else { #>off<# } #>" for="{{ data.id }}fixed"><?php esc_html_e( 'Fixed', 'kirki' ); ?></label>
</input>
</div>
</div>
<input class="background-hidden-value" type="hidden" {{{ data.link }}}>
<?php
}
}

View file

@ -0,0 +1,249 @@
<?php
/**
* Customizer Controls Base.
*
* Extend this in other controls.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 3.0.12
*/
/**
* A base for controls.
*/
class Kirki_Control_Base extends WP_Customize_Control {
/**
* Used to automatically generate all CSS output.
*
* @access public
* @var array
*/
public $output = array();
/**
* Data type
*
* @access public
* @var string
*/
public $option_type = 'theme_mod';
/**
* Option name (if using options).
*
* @access public
* @var string
*/
public $option_name = false;
/**
* The kirki_config we're using for this control
*
* @access public
* @var string
*/
public $kirki_config = 'global';
/**
* Whitelisting the "required" argument.
*
* @since 3.0.17
* @access public
* @var array
*/
public $required = array();
/**
* Whitelisting the "preset" argument.
*
* @since 3.0.26
* @access public
* @var array
*/
public $preset = array();
/**
* Whitelisting the "css_vars" argument.
*
* @since 3.0.28
* @access public
* @var string
*/
public $css_vars = '';
/**
* Extra script dependencies.
*
* @since 3.1.0
* @return array
*/
public function kirki_script_dependencies() {
return array();
}
/**
* Enqueue control related scripts/styles.
*
* @access public
*/
public function enqueue() {
// Build the suffix for the script.
$suffix = '';
$suffix .= ( ! defined( 'SCRIPT_DEBUG' ) || true !== SCRIPT_DEBUG ) ? '.min' : '';
// The Kirki plugin URL.
$kirki_url = trailingslashit( Kirki::$url );
// Enqueue ColorPicker.
wp_enqueue_script( 'wp-color-picker-alpha', trailingslashit( Kirki::$url ) . 'assets/vendor/wp-color-picker-alpha/wp-color-picker-alpha.js', array( 'wp-color-picker' ), KIRKI_VERSION, true );
wp_enqueue_style( 'wp-color-picker' );
// Enqueue selectWoo.
wp_enqueue_script( 'selectWoo', trailingslashit( Kirki::$url ) . 'assets/vendor/selectWoo/js/selectWoo.full.js', array( 'jquery' ), '1.0.1', true );
wp_enqueue_style( 'selectWoo', trailingslashit( Kirki::$url ) . 'assets/vendor/selectWoo/css/selectWoo.css', array(), '1.0.1' );
wp_enqueue_style( 'kirki-selectWoo', trailingslashit( Kirki::$url ) . 'assets/vendor/selectWoo/kirki.css', array(), KIRKI_VERSION );
// Enqueue the script.
wp_enqueue_script(
'kirki-script',
"{$kirki_url}controls/js/script{$suffix}.js",
array(
'jquery',
'customize-base',
'wp-color-picker-alpha',
'selectWoo',
'jquery-ui-button',
'jquery-ui-datepicker',
),
KIRKI_VERSION,
false
);
wp_localize_script(
'kirki-script',
'kirkiL10n',
array(
'isScriptDebug' => ( defined( 'SCRIPT_DEBUG' ) && true === SCRIPT_DEBUG ),
'noFileSelected' => esc_html__( 'No File Selected', 'kirki' ),
'remove' => esc_html__( 'Remove', 'kirki' ),
'default' => esc_html__( 'Default', 'kirki' ),
'selectFile' => esc_html__( 'Select File', 'kirki' ),
'standardFonts' => esc_html__( 'Standard Fonts', 'kirki' ),
'googleFonts' => esc_html__( 'Google Fonts', 'kirki' ),
'defaultCSSValues' => esc_html__( 'CSS Defaults', 'kirki' ),
'defaultBrowserFamily' => esc_html__( 'Default Browser Font-Family', 'kirki' ),
)
);
$suffix = str_replace( '.min', '', $suffix );
// Enqueue the style.
wp_enqueue_style(
'kirki-styles',
"{$kirki_url}controls/css/styles{$suffix}.css",
array(),
KIRKI_VERSION
);
}
/**
* Refresh the parameters passed to the JavaScript via JSON.
*
* @see WP_Customize_Control::to_json()
*/
public function to_json() {
// Get the basics from the parent class.
parent::to_json();
// Default value.
$this->json['default'] = $this->setting->default;
if ( isset( $this->default ) ) {
$this->json['default'] = $this->default;
}
// Required.
$this->json['required'] = $this->required;
// Output.
$this->json['output'] = $this->output;
// Value.
$this->json['value'] = $this->value();
// Choices.
$this->json['choices'] = $this->choices;
// The link.
$this->json['link'] = $this->get_link();
// The ID.
$this->json['id'] = $this->id;
// Translation strings.
$this->json['l10n'] = $this->l10n();
// The ajaxurl in case we need it.
$this->json['ajaxurl'] = admin_url( 'admin-ajax.php' );
// Input attributes.
$this->json['inputAttrs'] = '';
foreach ( $this->input_attrs as $attr => $value ) {
$this->json['inputAttrs'] .= $attr . '="' . esc_attr( $value ) . '" ';
}
// The kirki-config.
$this->json['kirkiConfig'] = $this->kirki_config;
// The option-type.
$this->json['kirkiOptionType'] = $this->option_type;
// The option-name.
$this->json['kirkiOptionName'] = $this->option_name;
// The preset.
$this->json['preset'] = $this->preset;
// The CSS-Variables.
$this->json['css-var'] = $this->css_vars;
}
/**
* Render the control's content.
*
* Allows the content to be overridden without having to rewrite the wrapper in `$this::render()`.
*
* Control content can alternately be rendered in JS. See WP_Customize_Control::print_template().
*
* @since 3.4.0
*/
protected function render_content() {}
/**
* An Underscore (JS) template for this control's content (but not its container).
*
* Class variables for this control class are available in the `data` JS object;
* export custom variables by overriding {@see WP_Customize_Control::to_json()}.
*
* @see WP_Customize_Control::print_template()
*
* @access protected
*/
protected function content_template() {}
/**
* Returns an array of translation strings.
*
* @access protected
* @since 3.0.0
* @return array
*/
protected function l10n() {
return array();
}
}

View file

@ -0,0 +1,56 @@
<?php
/**
* Customizer Control: checkbox.
*
* Creates a new custom control.
* Custom controls contains all background-related options.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 3.0.26
*/
/**
* Adds a checkbox control.
*
* @since 3.0.26
*/
class Kirki_Control_Checkbox extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-checkbox';
/**
* Render the control's content.
* Verbatim copy from WP_Customize_Control->render_content.
*
* @since 3.0.26
*/
protected function render_content() {
$input_id = '_customize-input-' . $this->id;
$description_id = '_customize-description-' . $this->id;
?>
<span class="customize-inside-control-row">
<input
id="<?php echo esc_attr( $input_id ); ?>"
<?php echo ( ! empty( $this->description ) ) ? ' aria-describedby="' . esc_attr( $description_id ) . '" ' : ''; ?>
type="checkbox"
value="<?php echo esc_attr( $this->value() ); ?>"
<?php $this->link(); ?>
<?php checked( $this->value() ); ?>
/>
<label for="<?php echo esc_attr( $input_id ); ?>"><?php echo esc_html( $this->label ); ?></label>
<?php if ( ! empty( $this->description ) ) : ?>
<span id="<?php echo esc_attr( $description_id ); ?>" class="description customize-control-description"><?php echo wp_kses_post( $this->description ); ?></span>
<?php endif; ?>
</span>
<?php
}
}

View file

@ -0,0 +1,47 @@
<?php
/**
* Customizer Control: code.
*
* Creates a new custom control.
* Custom controls accept raw HTML/JS.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 1.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Adds a "code" control, alias of the WP_Customize_Code_Editor_Control class.
*/
class Kirki_Control_Code extends WP_Customize_Code_Editor_Control {
/**
* Whitelisting the "required" argument.
*
* @since 3.0.17
* @access public
* @var array
*/
public $required = array();
/**
* Refresh the parameters passed to the JavaScript via JSON.
*
* @see WP_Customize_Control::to_json()
*/
public function to_json() {
// Get the basics from the parent class.
parent::to_json();
// Required.
$this->json['required'] = $this->required;
}
}

View file

@ -0,0 +1,79 @@
<?php
/**
* Customizer Control: color-palette.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 2.2.6
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Adds a color-palette control.
* This is essentially a radio control, styled as a palette.
*/
class Kirki_Control_Color_Palette extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-color-palette';
/**
* Refresh the parameters passed to the JavaScript via JSON.
*
* @access public
*/
public function to_json() {
parent::to_json();
// If no palette has been defined, use Material Design Palette.
if ( ! isset( $this->json['choices']['colors'] ) || empty( $this->json['choices']['colors'] ) ) {
$this->json['choices']['colors'] = Kirki_Helper::get_material_design_colors( 'primary' );
}
if ( ! isset( $this->json['choices']['size'] ) || empty( $this->json['choices']['size'] ) ) {
$this->json['choices']['size'] = 20;
}
}
/**
* An Underscore (JS) template for this control's content (but not its container).
*
* Class variables for this control class are available in the `data` JS object;
* export custom variables by overriding {@see WP_Customize_Control::to_json()}.
*
* @see WP_Customize_Control::print_template()
*
* @access protected
*/
protected function content_template() {
?>
<# if ( ! data.choices ) { return; } #>
<span class="customize-control-title">
{{{ data.label }}}
</span>
<# if ( data.description ) { #>
<span class="description customize-control-description">{{{ data.description }}}</span>
<# } #>
<div id="input_{{ data.id }}" class="colors-wrapper <# if ( ! _.isUndefined( data.choices.style ) && 'round' === data.choices.style ) { #>round<# } else { #>square<# } #><# if ( ! _.isUndefined( data.choices['box-shadow'] ) && true === data.choices['box-shadow'] ) { #> box-shadow<# } #><# if ( ! _.isUndefined( data.choices['margin'] ) && true === data.choices['margin'] ) { #> with-margin<# } #>">
<# for ( key in data.choices['colors'] ) { #>
<input type="radio" {{{ data.inputAttrs }}} value="{{ data.choices['colors'][ key ] }}" name="_customize-color-palette-{{ data.id }}" id="{{ data.id }}{{ key }}" {{{ data.link }}}<# if ( data.value == data.choices['colors'][ key ] ) { #> checked<# } #>>
<label for="{{ data.id }}{{ key }}" style="width: {{ data.choices['size'] }}px; height: {{ data.choices['size'] }}px;">
<span class="color-palette-color" style='background: {{ data.choices['colors'][ key ] }};'>{{ data.choices['colors'][ key ] }}</span>
</label>
</input>
<# } #>
</div>
<?php
}
}

View file

@ -0,0 +1,60 @@
<?php
/**
* Customizer Control: color.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 1.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Adds a color & color-alpha control
*
* @see https://github.com/23r9i0/wp-color-picker-alpha
*/
class Kirki_Control_Color extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-color';
/**
* Colorpicker palette
*
* @access public
* @var bool
*/
public $palette = true;
/**
* Mode.
*
* @since 3.0.12
* @var string
*/
public $mode = 'full';
/**
* Refresh the parameters passed to the JavaScript via JSON.
*
* @access public
*/
public function to_json() {
parent::to_json();
$this->json['palette'] = $this->palette;
$this->json['choices']['alpha'] = ( isset( $this->choices['alpha'] ) && $this->choices['alpha'] ) ? 'true' : 'false';
$this->json['mode'] = $this->mode;
}
}

View file

@ -0,0 +1,37 @@
<?php
/**
* Customizer Control: cropped-image.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 3.0.23
*/
/**
* Adds the image control.
*/
class Kirki_Control_Cropped_Image extends WP_Customize_Cropped_Image_Control {
/**
* Whitelisting the "required" argument.
*
* @since 3.0.17
* @access public
* @var array
*/
public $required = array();
/**
* Refresh the parameters passed to the JavaScript via JSON.
*
* @since 3.0.23
*
* @uses WP_Customize_Media_Control::to_json()
*/
public function to_json() {
parent::to_json();
$this->json['required'] = $this->required;
}
}

View file

@ -0,0 +1,61 @@
<?php
/**
* Customizer Control: custom.
*
* Creates a new custom control.
* Custom controls accept raw HTML/JS.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 1.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* The "custom" control allows you to add any raw HTML.
*/
class Kirki_Control_Custom extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-custom';
/**
* An Underscore (JS) template for this control's content (but not its container).
*
* Class variables for this control class are available in the `data` JS object;
* export custom variables by overriding {@see WP_Customize_Control::to_json()}.
*
* @see WP_Customize_Control::print_template()
*
* @access protected
*/
protected function content_template() {
?>
<label>
<# if ( data.label ) { #><span class="customize-control-title">{{{ data.label }}}</span><# } #>
<# if ( data.description ) { #><span class="description customize-control-description">{{{ data.description }}}</span><# } #>
<?php
/**
* The value is defined by the developer in the field configuration as 'default'.
* There is no user input on this field, it's a raw HTML/JS field and we do not sanitize it.
* Do not be alarmed, this is not a security issue.
* In order for someone to be able to change this they would have to have access to your filesystem.
* If that happens, they can change whatever they want anyways. This field is not a concern.
*/
?>
{{{ data.value }}}
</label>
<?php
}
}

View file

@ -0,0 +1,156 @@
<?php
/**
* Customizer Control: dashicons.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 2.2.4
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Dashicons control (modified radio).
*/
class Kirki_Control_Dashicons extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-dashicons';
/**
* Refresh the parameters passed to the JavaScript via JSON.
*
* @access public
*/
public function to_json() {
parent::to_json();
$this->json['icons'] = Kirki_Helper::get_dashicons();
}
/**
* An Underscore (JS) template for this control's content (but not its container).
*
* Class variables for this control class are available in the `data` JS object;
* export custom variables by overriding {@see WP_Customize_Control::to_json()}.
*
* @see WP_Customize_Control::print_template()
*
* @access protected
*/
protected function content_template() {
?>
<# if ( data.label ) { #><span class="customize-control-title">{{{ data.label }}}</span><# } #>
<# if ( data.description ) { #><span class="description customize-control-description">{{{ data.description }}}</span><# } #>
<div class="icons-wrapper">
<# if ( ! _.isUndefined( data.choices ) && 1 < _.size( data.choices ) ) { #>
<# for ( key in data.choices ) { #>
<input {{{ data.inputAttrs }}} class="dashicons-select" type="radio" value="{{ key }}" name="_customize-dashicons-radio-{{ data.id }}" id="{{ data.id }}{{ key }}" {{{ data.link }}}<# if ( data.value === key ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}{{ key }}"><span class="dashicons dashicons-{{ data.choices[ key ] }}"></span></label>
</input>
<# } #>
<# } else { #>
<h4>Admin Menu</h4>
<# for ( key in data.icons['admin-menu'] ) { #>
<input {{{ data.inputAttrs }}} class="dashicons-select" type="radio" value="{{ data.icons['admin-menu'][ key ] }}" name="_customize-dashicons-radio-{{ data.id }}" id="{{ data.id }}{{ data.icons['admin-menu'][ key ] }}" {{{ data.link }}}<# if ( data.value === data.icons['admin-menu'][ key ] ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}{{ data.icons['admin-menu'][ key ] }}"><span class="dashicons dashicons-{{ data.icons['admin-menu'][ key ] }}"></span></label>
</input>
<# } #>
<h4>Welcome Screen</h4>
<# for ( key in data.icons['welcome-screen'] ) { #>
<input {{{ data.inputAttrs }}} class="dashicons-select" type="radio" value="{{ data.icons['welcome-screen'][ key ] }}" name="_customize-dashicons-radio-{{ data.id }}" id="{{ data.id }}{{ data.icons['welcome-screen'][ key ] }}" {{{ data.link }}}<# if ( data.value === data.icons['welcome-screen'][ key ] ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}{{ data.icons['welcome-screen'][ key ] }}"><span class="dashicons dashicons-{{ data.icons['welcome-screen'][ key ] }}"></span></label>
</input>
<# } #>
<h4>Post Formats</h4>
<# for ( key in data.icons['post-formats'] ) { #>
<input {{{ data.inputAttrs }}} class="dashicons-select" type="radio" value="{{ data.icons['post-formats'][ key ] }}" name="_customize-dashicons-radio-{{ data.id }}" id="{{ data.id }}{{ data.icons['post-formats'][ key ] }}" {{{ data.link }}}<# if ( data.value === data.icons['post-formats'][ key ] ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}{{ data.icons['post-formats'][ key ] }}"><span class="dashicons dashicons-{{ data.icons['post-formats'][ key ] }}"></span></label>
</input>
<# } #>
<h4>Media</h4>
<# for ( key in data.icons['media'] ) { #>
<input {{{ data.inputAttrs }}} class="dashicons-select" type="radio" value="{{ data.icons['media'][ key ] }}" name="_customize-dashicons-radio-{{ data.id }}" id="{{ data.id }}{{ data.icons['media'][ key ] }}" {{{ data.link }}}<# if ( data.value === data.icons['media'][ key ] ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}{{ data.icons['media'][ key ] }}"><span class="dashicons dashicons-{{ data.icons['media'][ key ] }}"></span></label>
</input>
<# } #>
<h4>Image Editing</h4>
<# for ( key in data.icons['image-editing'] ) { #>
<input {{{ data.inputAttrs }}} class="dashicons-select" type="radio" value="{{ data.icons['image-editing'][ key ] }}" name="_customize-dashicons-radio-{{ data.id }}" id="{{ data.id }}{{ data.icons['image-editing'][ key ] }}" {{{ data.link }}}<# if ( data.value === data.icons['image-editing'][ key ] ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}{{ data.icons['image-editing'][ key ] }}"><span class="dashicons dashicons-{{ data.icons['image-editing'][ key ] }}"></span></label>
</input>
<# } #>
<h4>TinyMCE</h4>
<# for ( key in data.icons['tinymce'] ) { #>
<input {{{ data.inputAttrs }}} class="dashicons-select" type="radio" value="{{ data.icons['tinymce'][ key ] }}" name="_customize-dashicons-radio-{{ data.id }}" id="{{ data.id }}{{ data.icons['tinymce'][ key ] }}" {{{ data.link }}}<# if ( data.value === data.icons['tinymce'][ key ] ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}{{ data.icons['tinymce'][ key ] }}"><span class="dashicons dashicons-{{ data.icons['tinymce'][ key ] }}"></span></label>
</input>
<# } #>
<h4>Posts</h4>
<# for ( key in data.icons['posts'] ) { #>
<input {{{ data.inputAttrs }}} class="dashicons-select" type="radio" value="{{ data.icons['posts'][ key ] }}" name="_customize-dashicons-radio-{{ data.id }}" id="{{ data.id }}{{ data.icons['posts'][ key ] }}" {{{ data.link }}}<# if ( data.value === data.icons['posts'][ key ] ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}{{ data.icons['posts'][ key ] }}"><span class="dashicons dashicons-{{ data.icons['posts'][ key ] }}"></span></label>
</input>
<# } #>
<h4>Sorting</h4>
<# for ( key in data.icons['sorting'] ) { #>
<input {{{ data.inputAttrs }}} class="dashicons-select" type="radio" value="{{ data.icons['sorting'][ key ] }}" name="_customize-dashicons-radio-{{ data.id }}" id="{{ data.id }}{{ data.icons['sorting'][ key ] }}" {{{ data.link }}}<# if ( data.value === data.icons['sorting'][ key ] ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}{{ data.icons['sorting'][ key ] }}"><span class="dashicons dashicons-{{ data.icons['sorting'][ key ] }}"></span></label>
</input>
<# } #>
<h4>Social</h4>
<# for ( key in data.icons['social'] ) { #>
<input {{{ data.inputAttrs }}} class="dashicons-select" type="radio" value="{{ data.icons['social'][ key ] }}" name="_customize-dashicons-radio-{{ data.id }}" id="{{ data.id }}{{ data.icons['social'][ key ] }}" {{{ data.link }}}<# if ( data.value === data.icons['social'][ key ] ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}{{ data.icons['social'][ key ] }}"><span class="dashicons dashicons-{{ data.icons['social'][ key ] }}"></span></label>
</input>
<# } #>
<h4>WordPress</h4>
<# for ( key in data.icons['wordpress_org'] ) { #>
<input {{{ data.inputAttrs }}} class="dashicons-select" type="radio" value="{{ data.icons['wordpress_org'][ key ] }}" name="_customize-dashicons-radio-{{ data.id }}" id="{{ data.id }}{{ data.icons['wordpress_org'][ key ] }}" {{{ data.link }}}<# if ( data.value === data.icons['wordpress_org'][ key ] ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}{{ data.icons['wordpress_org'][ key ] }}"><span class="dashicons dashicons-{{ data.icons['wordpress_org'][ key ] }}"></span></label>
</input>
<# } #>
<h4>Products</h4>
<# for ( key in data.icons['products'] ) { #>
<input {{{ data.inputAttrs }}} class="dashicons-select" type="radio" value="{{ data.icons['products'][ key ] }}" name="_customize-dashicons-radio-{{ data.id }}" id="{{ data.id }}{{ data.icons['products'][ key ] }}" {{{ data.link }}}<# if ( data.value === data.icons['products'][ key ] ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}{{ data.icons['products'][ key ] }}"><span class="dashicons dashicons-{{ data.icons['products'][ key ] }}"></span></label>
</input>
<# } #>
<h4>Taxonomies</h4>
<# for ( key in data.icons['taxonomies'] ) { #>
<input {{{ data.inputAttrs }}} class="dashicons-select" type="radio" value="{{ data.icons['taxonomies'][ key ] }}" name="_customize-dashicons-radio-{{ data.id }}" id="{{ data.id }}{{ data.icons['taxonomies'][ key ] }}" {{{ data.link }}}<# if ( data.value === data.icons['taxonomies'][ key ] ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}{{ data.icons['taxonomies'][ key ] }}"><span class="dashicons dashicons-{{ data.icons['taxonomies'][ key ] }}"></span></label>
</input>
<# } #>
<h4>Widgets</h4>
<# for ( key in data.icons['widgets'] ) { #>
<input {{{ data.inputAttrs }}} class="dashicons-select" type="radio" value="{{ data.icons['widgets'][ key ] }}" name="_customize-dashicons-radio-{{ data.id }}" id="{{ data.id }}{{ data.icons['widgets'][ key ] }}" {{{ data.link }}}<# if ( data.value === data.icons['widgets'][ key ] ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}{{ data.icons['widgets'][ key ] }}"><span class="dashicons dashicons-{{ data.icons['widgets'][ key ] }}"></span></label>
</input>
<# } #>
<h4>Notifications</h4>
<# for ( key in data.icons['notifications'] ) { #>
<input {{{ data.inputAttrs }}} class="dashicons-select" type="radio" value="{{ data.icons['notifications'][ key ] }}" name="_customize-dashicons-radio-{{ data.id }}" id="{{ data.id }}{{ data.icons['notifications'][ key ] }}" {{{ data.link }}}<# if ( data.value === data.icons['notifications'][ key ] ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}{{ data.icons['notifications'][ key ] }}"><span class="dashicons dashicons-{{ data.icons['notifications'][ key ] }}"></span></label>
</input>
<# } #>
<h4>Misc</h4>
<# for ( key in data.icons['misc'] ) { #>
<input {{{ data.inputAttrs }}} class="dashicons-select" type="radio" value="{{ data.icons['misc'][ key ] }}" name="_customize-dashicons-radio-{{ data.id }}" id="{{ data.id }}{{ data.icons['misc'][ key ] }}" {{{ data.link }}}<# if ( data.value === data.icons['misc'][ key ] ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}{{ data.icons['misc'][ key ] }}"><span class="dashicons dashicons-{{ data.icons['misc'][ key ] }}"></span></label>
</input>
<# } #>
<# } #>
</div>
<?php
}
}

View file

@ -0,0 +1,51 @@
<?php
/**
* Customizer Control: kirki-date.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 2.2
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* A simple date control, using jQuery UI.
*/
class Kirki_Control_Date extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-date';
/**
* An Underscore (JS) template for this control's content (but not its container).
*
* Class variables for this control class are available in the `data` JS object;
* export custom variables by overriding {@see WP_Customize_Control::to_json()}.
*
* @see WP_Customize_Control::print_template()
*
* @access protected
*/
protected function content_template() {
?>
<label>
<# if ( data.label ) { #><span class="customize-control-title">{{{ data.label }}}</span><# } #>
<# if ( data.description ) { #><span class="description customize-control-description">{{{ data.description }}}</span><# } #>
<div class="customize-control-content">
<input {{{ data.inputAttrs }}} class="datepicker" type="text" id="{{ data.id }}" value="{{ data.value }}" {{{ data.link }}} />
</div>
</label>
<?php
}
}

View file

@ -0,0 +1,68 @@
<?php
/**
* Customizer Control: dimension
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 2.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* A text control with validation for CSS units.
*/
class Kirki_Control_Dimension extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-dimension';
/**
* Enqueue control related scripts/styles.
*
* @access public
*/
public function enqueue() {
parent::enqueue();
wp_localize_script(
'kirki-script',
'dimensionkirkiL10n',
array(
'invalid-value' => esc_html__( 'Invalid Value', 'kirki' ),
)
);
}
/**
* An Underscore (JS) template for this control's content (but not its container).
*
* Class variables for this control class are available in the `data` JS object;
* export custom variables by overriding {@see WP_Customize_Control::to_json()}.
*
* @see WP_Customize_Control::print_template()
*
* @access protected
*/
protected function content_template() {
?>
<label class="customizer-text">
<# if ( data.label ) { #><span class="customize-control-title">{{{ data.label }}}</span><# } #>
<# if ( data.description ) { #><span class="description customize-control-description">{{{ data.description }}}</span><# } #>
<div class="input-wrapper">
<# var val = ( data.value && _.isString( data.value ) ) ? data.value.replace( '%%', '%' ) : ''; #>
<input {{{ data.inputAttrs }}} type="text" value="{{ val }}"/>
</div>
</label>
<?php
}
}

View file

@ -0,0 +1,141 @@
<?php
/**
* Customizer Control: dimensions.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 2.1
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Dimensions control.
* multiple fields with CSS units validation.
*/
class Kirki_Control_Dimensions extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-dimensions';
/**
* Refresh the parameters passed to the JavaScript via JSON.
*
* @see WP_Customize_Control::to_json()
*/
public function to_json() {
parent::to_json();
if ( is_array( $this->choices ) ) {
foreach ( $this->choices as $choice => $value ) {
if ( 'labels' !== $choice && true === $value ) {
$this->json['choices'][ $choice ] = true;
}
}
}
if ( is_array( $this->json['default'] ) ) {
foreach ( $this->json['default'] as $key => $value ) {
if ( isset( $this->json['choices'][ $key ] ) && ! isset( $this->json['value'][ $key ] ) ) {
$this->json['value'][ $key ] = $value;
}
}
}
}
/**
* Enqueue control related scripts/styles.
*
* @access public
*/
public function enqueue() {
wp_enqueue_style( 'kirki-styles', trailingslashit( Kirki::$url ) . 'controls/css/styles.css', array(), KIRKI_VERSION );
wp_localize_script( 'kirki-script', 'dimensionskirkiL10n', $this->l10n() );
}
/**
* An Underscore (JS) template for this control's content (but not its container).
*
* Class variables for this control class are available in the `data` JS object;
* export custom variables by overriding {@see WP_Customize_Control::to_json()}.
*
* @see WP_Customize_Control::print_template()
*
* @access protected
*/
protected function content_template() {
?>
<label>
<# if ( data.label ) { #><span class="customize-control-title">{{{ data.label }}}</span><# } #>
<# if ( data.description ) { #><span class="description customize-control-description">{{{ data.description }}}</span><# } #>
<div class="wrapper">
<div class="control">
<# for ( choiceKey in data.default ) { #>
<div class="{{ choiceKey }}">
<h5>
<# if ( ! _.isUndefined( data.choices.labels ) && ! _.isUndefined( data.choices.labels[ choiceKey ] ) ) { #>
{{ data.choices.labels[ choiceKey ] }}
<# } else if ( ! _.isUndefined( data.l10n[ choiceKey ] ) ) { #>
{{ data.l10n[ choiceKey ] }}
<# } else { #>
{{ choiceKey }}
<# } #>
</h5>
<div class="{{ choiceKey }} input-wrapper">
<# var val = ( ! _.isUndefined( data.value ) && ! _.isUndefined( data.value[ choiceKey ] ) ) ? data.value[ choiceKey ].toString().replace( '%%', '%' ) : ''; #>
<input {{{ data.inputAttrs }}} type="text" data-choice="{{ choiceKey }}" value="{{ val }}"/>
</div>
</div>
<# } #>
</div>
</div>
</label>
<?php
}
/**
* Returns an array of translation strings.
*
* @access protected
* @since 3.0.0
* @return array
*/
protected function l10n() {
return array(
'left-top' => esc_html__( 'Left Top', 'kirki' ),
'left-center' => esc_html__( 'Left Center', 'kirki' ),
'left-bottom' => esc_html__( 'Left Bottom', 'kirki' ),
'right-top' => esc_html__( 'Right Top', 'kirki' ),
'right-center' => esc_html__( 'Right Center', 'kirki' ),
'right-bottom' => esc_html__( 'Right Bottom', 'kirki' ),
'center-top' => esc_html__( 'Center Top', 'kirki' ),
'center-center' => esc_html__( 'Center Center', 'kirki' ),
'center-bottom' => esc_html__( 'Center Bottom', 'kirki' ),
'font-size' => esc_html__( 'Font Size', 'kirki' ),
'font-weight' => esc_html__( 'Font Weight', 'kirki' ),
'line-height' => esc_html__( 'Line Height', 'kirki' ),
'font-style' => esc_html__( 'Font Style', 'kirki' ),
'letter-spacing' => esc_html__( 'Letter Spacing', 'kirki' ),
'word-spacing' => esc_html__( 'Word Spacing', 'kirki' ),
'top' => esc_html__( 'Top', 'kirki' ),
'bottom' => esc_html__( 'Bottom', 'kirki' ),
'left' => esc_html__( 'Left', 'kirki' ),
'right' => esc_html__( 'Right', 'kirki' ),
'center' => esc_html__( 'Center', 'kirki' ),
'size' => esc_html__( 'Size', 'kirki' ),
'spacing' => esc_html__( 'Spacing', 'kirki' ),
'width' => esc_html__( 'Width', 'kirki' ),
'height' => esc_html__( 'Height', 'kirki' ),
'invalid-value' => esc_html__( 'Invalid Value', 'kirki' ),
);
}
}

View file

@ -0,0 +1,55 @@
<?php
/**
* Customizer Control: editor.
*
* Creates a TinyMCE textarea.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 1.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* A TinyMCE control.
*/
class Kirki_Control_Editor extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-editor';
/**
* An Underscore (JS) template for this control's content (but not its container).
*
* Class variables for this control class are available in the `data` JS object;
* export custom variables by overriding {@see WP_Customize_Control::to_json()}.
*
* The actual editor is added from the Kirki_Field_Editor class.
* All this template contains is a button that triggers the global editor on/off
* and a hidden textarea element that is used to mirror save the options.
*
* @see WP_Customize_Control::print_template()
*
* @access protected
*/
protected function content_template() {
?>
<label>
<# if ( data.label ) { #><span class="customize-control-title">{{{ data.label }}}</span><# } #>
<# if ( data.description ) { #><span class="description customize-control-description">{{{ data.description }}}</span><# } #>
</label>
<textarea id="kirki-editor-{{{ data.id.replace( '[', '' ).replace( ']', '' ) }}}" {{{ data.inputAttrs }}} {{{ data.link }}}>{{ data.value }}</textarea>
<?php
}
}

View file

@ -0,0 +1,30 @@
<?php
/**
* Customizer Control: kirki-generic.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 2.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* A generic and pretty abstract control.
* Allows for great manipulation using the field's "choices" argumnent.
*/
class Kirki_Control_Generic extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-generic';
}

View file

@ -0,0 +1,24 @@
<?php
/**
* Customizer Control: image.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 3.0.0
*/
/**
* Adds the image control.
*/
class Kirki_Control_Image extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-image';
}

View file

@ -0,0 +1,57 @@
<?php
/**
* Customizer Control: multicheck.
*
* Multiple checkbox customize control class.
* Props @ Justin Tadlock: http://justintadlock.com/archives/2015/05/26/multiple-checkbox-customizer-control
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 1.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Adds a multicheck control.
*/
class Kirki_Control_MultiCheck extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-multicheck';
/**
* An Underscore (JS) template for this control's content (but not its container).
*
* Class variables for this control class are available in the `data` JS object;
* export custom variables by overriding {@see WP_Customize_Control::to_json()}.
*
* @see WP_Customize_Control::print_template()
*
* @access protected
*/
protected function content_template() {
?>
<# if ( ! data.choices ) { return; } #>
<# if ( data.label ) { #><span class="customize-control-title">{{{ data.label }}}</span><# } #>
<# if ( data.description ) { #><span class="description customize-control-description">{{{ data.description }}}</span><# } #>
<ul>
<# for ( key in data.choices ) { #>
<li><label<# if ( _.contains( data.value, key ) ) { #> class="checked"<# } #>><input {{{ data.inputAttrs }}} type="checkbox" value="{{ key }}"<# if ( _.contains( data.value, key ) ) { #> checked<# } #> />{{ data.choices[ key ] }}</label></li>
<# } #>
</ul>
<?php
}
}

View file

@ -0,0 +1,78 @@
<?php
/**
* Customizer Control: multicolor.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 2.2.7
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Multicolor control.
*/
class Kirki_Control_Multicolor extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-multicolor';
/**
* Enable/Disable Alpha channel on color pickers
*
* @access public
* @var boolean
*/
public $alpha = true;
/**
* Refresh the parameters passed to the JavaScript via JSON.
*
* @access public
*/
public function to_json() {
parent::to_json();
$this->json['alpha'] = (bool) $this->alpha;
}
/**
* An Underscore (JS) template for this control's content (but not its container).
*
* Class variables for this control class are available in the `data` JS object;
* export custom variables by overriding {@see WP_Customize_Control::to_json()}.
*
* @see WP_Customize_Control::print_template()
*
* @access protected
*/
protected function content_template() {
?>
<span class="customize-control-title">
{{{ data.label }}}
</span>
<# if ( data.description ) { #>
<span class="description customize-control-description">{{{ data.description }}}</span>
<# } #>
<div class="multicolor-group-wrapper">
<# for ( key in data.choices ) { #>
<# if ( 'irisArgs' !== key ) { #>
<div class="multicolor-single-color-wrapper">
<input {{{ data.inputAttrs }}} id="{{ data.id }}-{{ key }}" type="text" data-palette="{{ data.palette }}" data-default-color="{{ data.default[ key ] }}" data-alpha="{{ data.alpha }}" value="{{ data.value[ key ] }}" class="kirki-color-control color-picker multicolor-index-{{ key }}" data-label="<# if ( data.choices[ key ] ) { #>{{ data.choices[ key ] }}<# } else { #>{{ key }}<# } #>" />
</div>
<# } #>
<# } #>
</div>
<input class="multicolor-hidden-value" type="hidden" {{{ data.link }}}>
<?php
}
}

View file

@ -0,0 +1,29 @@
<?php
/**
* Customizer Control: number.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 1.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Create a simple number control
*/
class Kirki_Control_Number extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-number';
}

View file

@ -0,0 +1,62 @@
<?php
/**
* Customizer Control: palette.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 1.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Palette control (modified radio).
*/
class Kirki_Control_Palette extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-palette';
/**
* An Underscore (JS) template for this control's content (but not its container).
*
* Class variables for this control class are available in the `data` JS object;
* export custom variables by overriding {@see WP_Customize_Control::to_json()}.
*
* @see WP_Customize_Control::print_template()
*
* @access protected
*/
protected function content_template() {
?>
<# if ( ! data.choices ) { return; } #>
<span class="customize-control-title">
{{{ data.label }}}
</span>
<# if ( data.description ) { #>
<span class="description customize-control-description">{{{ data.description }}}</span>
<# } #>
<div id="input_{{ data.id }}" class="buttonset">
<# for ( key in data.choices ) { #>
<input {{{ data.inputAttrs }}} type="radio" value="{{ key }}" name="_customize-palette-{{ data.id }}" id="{{ data.id }}{{ key }}" {{{ data.link }}}<# if ( data.value == key ) { #> checked<# } #>>
<label for="{{ data.id }}{{ key }}">
<# for ( color in data.choices[ key ] ) { #>
<span style='background: {{ data.choices[ key ][ color ] }}'>{{ data.choices[ key ][ color ] }}</span>
<# } #>
</label>
</input>
<# } #>
</div>
<?php
}
}

View file

@ -0,0 +1,53 @@
<?php
/**
* Customizer Control: radio-buttonset.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 1.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Radio Buttonset control (modified radio)
*/
class Kirki_Control_Radio_Buttonset extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-radio-buttonset';
/**
* An Underscore (JS) template for this control's content (but not its container).
*
* Class variables for this control class are available in the `data` JS object;
* export custom variables by overriding {@see WP_Customize_Control::to_json()}.
*
* @see WP_Customize_Control::print_template()
*
* @access protected
*/
protected function content_template() {
?>
<# if ( data.label ) { #><span class="customize-control-title">{{{ data.label }}}</span><# } #>
<# if ( data.description ) { #><span class="description customize-control-description">{{{ data.description }}}</span><# } #>
<div id="input_{{ data.id }}" class="buttonset">
<# for ( key in data.choices ) { #>
<input {{{ data.inputAttrs }}} class="switch-input screen-reader-text" type="radio" value="{{ key }}" name="_customize-radio-{{{ data.id }}}" id="{{ data.id }}{{ key }}" {{{ data.link }}}<# if ( key === data.value ) { #> checked="checked" <# } #>>
<label class="switch-label switch-label-<# if ( key === data.value ) { #>on <# } else { #>off<# } #>" for="{{ data.id }}{{ key }}">{{{ data.choices[ key ] }}}</label>
</input>
<# } #>
</div>
<?php
}
}

View file

@ -0,0 +1,81 @@
<?php
/**
* Customizer Control: radio-image.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 1.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Radio Image control (modified radio).
*/
class Kirki_Control_Radio_Image extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-radio-image';
/**
* Refresh the parameters passed to the JavaScript via JSON.
*
* @see WP_Customize_Control::to_json()
*/
public function to_json() {
parent::to_json();
foreach ( $this->input_attrs as $attr => $value ) {
if ( 'style' !== $attr ) {
$this->json['inputAttrs'] .= $attr . '="' . esc_attr( $value ) . '" ';
continue;
}
$this->json['labelStyle'] = 'style="' . esc_attr( $value ) . '" ';
}
}
/**
* An Underscore (JS) template for this control's content (but not its container).
*
* Class variables for this control class are available in the `data` JS object;
* export custom variables by overriding {@see WP_Customize_Control::to_json()}.
*
* @see WP_Customize_Control::print_template()
*
* @access protected
*/
protected function content_template() {
?>
<label class="customizer-text">
<# if ( data.label ) { #><span class="customize-control-title">{{{ data.label }}}</span><# } #>
<# if ( data.description ) { #><span class="description customize-control-description">{{{ data.description }}}</span><# } #>
</label>
<div id="input_{{ data.id }}" class="image">
<# for ( key in data.choices ) { #>
<# dataAlt = ( _.isObject( data.choices[ key ] ) && ! _.isUndefined( data.choices[ key ].alt ) ) ? data.choices[ key ].alt : '' #>
<input {{{ data.inputAttrs }}} class="image-select" type="radio" value="{{ key }}" name="_customize-radio-{{ data.id }}" id="{{ data.id }}{{ key }}" {{{ data.link }}}<# if ( data.value === key ) { #> checked="checked"<# } #> data-alt="{{ dataAlt }}">
<label for="{{ data.id }}{{ key }}" {{{ data.labelStyle }}} class="{{{ data.id + key }}}">
<# if ( _.isObject( data.choices[ key ] ) ) { #>
<img src="{{ data.choices[ key ].src }}" alt="{{ data.choices[ key ].alt }}">
<span class="image-label"><span class="inner">{{ data.choices[ key ].alt }}</span></span>
<# } else { #>
<img src="{{ data.choices[ key ] }}">
<# } #>
<span class="image-clickable"></span>
</label>
</input>
<# } #>
</div>
<?php
}
}

View file

@ -0,0 +1,29 @@
<?php
/**
* Customizer Control: kirki-radio.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 1.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Radio control
*/
class Kirki_Control_Radio extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-radio';
}

View file

@ -0,0 +1,481 @@
<?php
/**
* Customizer Control: repeater.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 2.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Repeater control
*/
class Kirki_Control_Repeater extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'repeater';
/**
* The fields that each container row will contain.
*
* @access public
* @var array
*/
public $fields = array();
/**
* Will store a filtered version of value for advenced fields (like images).
*
* @access protected
* @var array
*/
protected $filtered_value = array();
/**
* The row label
*
* @access public
* @var array
*/
public $row_label = array();
/**
* The button label
*
* @access public
* @var string
*/
public $button_label = '';
/**
* Constructor.
* Supplied `$args` override class property defaults.
* If `$args['settings']` is not defined, use the $id as the setting ID.
*
* @param WP_Customize_Manager $manager Customizer bootstrap instance.
* @param string $id Control ID.
* @param array $args {@see WP_Customize_Control::__construct}.
*/
public function __construct( $manager, $id, $args = array() ) {
parent::__construct( $manager, $id, $args );
// Set up defaults for row labels.
$this->row_label = array(
'type' => 'text',
'value' => esc_attr__( 'row', 'kirki' ),
'field' => false,
);
// Validate row-labels.
$this->row_label( $args );
if ( empty( $this->button_label ) ) {
/* translators: %s represents the label of the row. */
$this->button_label = sprintf( esc_html__( 'Add new %s', 'kirki' ), $this->row_label['value'] );
}
if ( empty( $args['fields'] ) || ! is_array( $args['fields'] ) ) {
$args['fields'] = array();
}
// An array to store keys of fields that need to be filtered.
$media_fields_to_filter = array();
foreach ( $args['fields'] as $key => $value ) {
if ( ! isset( $value['default'] ) ) {
$args['fields'][ $key ]['default'] = '';
}
if ( ! isset( $value['label'] ) ) {
$args['fields'][ $key ]['label'] = '';
}
$args['fields'][ $key ]['id'] = $key;
// We check if the filed is an uploaded media ( image , file, video, etc.. ).
if ( isset( $value['type'] ) ) {
switch ( $value['type'] ) {
case 'image':
case 'cropped_image':
case 'upload':
// We add it to the list of fields that need some extra filtering/processing.
$media_fields_to_filter[ $key ] = true;
break;
case 'dropdown-pages':
// If the field is a dropdown-pages field then add it to args.
$dropdown = wp_dropdown_pages(
array(
'name' => '',
'echo' => 0,
'show_option_none' => esc_html__( 'Select a Page', 'kirki' ),
'option_none_value' => '0',
'selected' => '',
)
);
// Hackily add in the data link parameter.
$dropdown = str_replace( '<select', '<select data-field="' . esc_attr( $args['fields'][ $key ]['id'] ) . '"' . $this->get_link(), $dropdown ); // phpcs:ignore Generic.Formatting.MultipleStatementAlignment
$args['fields'][ $key ]['dropdown'] = $dropdown;
break;
}
}
}
$this->fields = $args['fields'];
// Now we are going to filter the fields.
// First we create a copy of the value that would be used otherwise.
$this->filtered_value = $this->value();
if ( is_array( $this->filtered_value ) && ! empty( $this->filtered_value ) ) {
// We iterate over the list of fields.
foreach ( $this->filtered_value as &$filtered_value_field ) {
if ( is_array( $filtered_value_field ) && ! empty( $filtered_value_field ) ) {
// We iterate over the list of properties for this field.
foreach ( $filtered_value_field as $key => &$value ) {
// We check if this field was marked as requiring extra filtering (in this case image, cropped_images, upload).
if ( array_key_exists( $key, $media_fields_to_filter ) ) {
// What follows was made this way to preserve backward compatibility.
// The repeater control use to store the URL for images instead of the attachment ID.
// We check if the value look like an ID (otherwise it's probably a URL so don't filter it).
if ( is_numeric( $value ) ) {
// "sanitize" the value.
$attachment_id = (int) $value;
// Try to get the attachment_url.
$url = wp_get_attachment_url( $attachment_id );
$filename = basename( get_attached_file( $attachment_id ) );
// If we got a URL.
if ( $url ) {
// 'id' is needed for form hidden value, URL is needed to display the image.
$value = array(
'id' => $attachment_id,
'url' => $url,
'filename' => $filename,
);
}
}
}
}
}
}
}
}
/**
* Refresh the parameters passed to the JavaScript via JSON.
*
* @access public
*/
public function to_json() {
parent::to_json();
$fields = $this->fields;
$this->json['fields'] = $fields;
$this->json['row_label'] = $this->row_label;
// If filtered_value has been set and is not empty we use it instead of the actual value.
if ( is_array( $this->filtered_value ) && ! empty( $this->filtered_value ) ) {
$this->json['value'] = $this->filtered_value;
}
$this->json['value'] = apply_filters( "kirki_controls_repeater_value_{$this->id}", $this->json['value'] );
}
/**
* Render the control's content.
* Allows the content to be overriden without having to rewrite the wrapper in $this->render().
*
* @access protected
*/
protected function render_content() {
?>
<label>
<?php if ( ! empty( $this->label ) ) : ?>
<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
<?php endif; ?>
<?php if ( ! empty( $this->description ) ) : ?>
<span class="description customize-control-description"><?php echo wp_kses_post( $this->description ); ?></span>
<?php endif; ?>
<input type="hidden" {{{ data.inputAttrs }}} value="" <?php echo wp_kses_post( $this->get_link() ); ?> />
</label>
<ul class="repeater-fields"></ul>
<?php if ( isset( $this->choices['limit'] ) ) : ?>
<?php /* translators: %s represents the number of rows we're limiting the repeater to allow. */ ?>
<p class="limit"><?php printf( esc_html__( 'Limit: %s rows', 'kirki' ), esc_html( $this->choices['limit'] ) ); ?></p>
<?php endif; ?>
<button class="button-secondary repeater-add"><?php echo esc_html( $this->button_label ); ?></button>
<?php
$this->repeater_js_template();
}
/**
* An Underscore (JS) template for this control's content (but not its container).
* Class variables for this control class are available in the `data` JS object.
*
* @access public
*/
public function repeater_js_template() {
?>
<script type="text/html" class="customize-control-repeater-content">
<# var field; var index = data.index; #>
<li class="repeater-row minimized" data-row="{{{ index }}}">
<div class="repeater-row-header">
<span class="repeater-row-label"></span>
<i class="dashicons dashicons-arrow-down repeater-minimize"></i>
</div>
<div class="repeater-row-content">
<# _.each( data, function( field, i ) { #>
<div class="repeater-field repeater-field-{{{ field.type }}} repeater-field-{{ field.id }}">
<# if ( 'text' === field.type || 'url' === field.type || 'link' === field.type || 'email' === field.type || 'tel' === field.type || 'date' === field.type || 'number' === field.type ) { #>
<# var fieldExtras = ''; #>
<# if ( 'link' === field.type ) { #>
<# field.type = 'url' #>
<# } #>
<# if ( 'number' === field.type ) { #>
<# if ( ! _.isUndefined( field.choices ) && ! _.isUndefined( field.choices.min ) ) { #>
<# fieldExtras += ' min="' + field.choices.min + '"'; #>
<# } #>
<# if ( ! _.isUndefined( field.choices ) && ! _.isUndefined( field.choices.max ) ) { #>
<# fieldExtras += ' max="' + field.choices.max + '"'; #>
<# } #>
<# if ( ! _.isUndefined( field.choices ) && ! _.isUndefined( field.choices.step ) ) { #>
<# fieldExtras += ' step="' + field.choices.step + '"'; #>
<# } #>
<# } #>
<label>
<# if ( field.label ) { #><span class="customize-control-title">{{{ field.label }}}</span><# } #>
<# if ( field.description ) { #><span class="description customize-control-description">{{{ field.description }}}</span><# } #>
<input type="{{field.type}}" name="" value="{{{ field.default }}}" data-field="{{{ field.id }}}"{{ fieldExtras }}>
</label>
<# } else if ( 'number' === field.type ) { #>
<label>
<# if ( field.label ) { #><span class="customize-control-title">{{{ field.label }}}</span><# } #>
<# if ( field.description ) { #><span class="description customize-control-description">{{{ field.description }}}</span><# } #>
<input type="{{ field.type }}" name="" value="{{{ field.default }}}" data-field="{{{ field.id }}}"{{ numberFieldExtras }}>
</label>
<# } else if ( 'hidden' === field.type ) { #>
<input type="hidden" data-field="{{{ field.id }}}" <# if ( field.default ) { #> value="{{{ field.default }}}" <# } #> />
<# } else if ( 'checkbox' === field.type ) { #>
<label>
<input type="checkbox" value="{{{ field.default }}}" data-field="{{{ field.id }}}" <# if ( field.default ) { #> checked="checked" <# } #> /> {{{ field.label }}}
<# if ( field.description ) { #>{{{ field.description }}}<# } #>
</label>
<# } else if ( 'select' === field.type ) { #>
<label>
<# if ( field.label ) { #><span class="customize-control-title">{{{ field.label }}}</span><# } #>
<# if ( field.description ) { #><span class="description customize-control-description">{{{ field.description }}}</span><# } #>
<select data-field="{{{ field.id }}}"<# if ( ! _.isUndefined( field.multiple ) && false !== field.multiple ) { #> multiple="multiple" data-multiple="{{ field.multiple }}"<# } #>>
<# _.each( field.choices, function( choice, i ) { #>
<option value="{{{ i }}}" <# if ( -1 !== jQuery.inArray( i, field.default ) || field.default == i ) { #> selected="selected" <# } #>>{{ choice }}</option>
<# }); #>
</select>
</label>
<# } else if ( 'dropdown-pages' === field.type ) { #>
<label>
<# if ( field.label ) { #><span class="customize-control-title">{{{ data.label }}}</span><# } #>
<# if ( field.description ) { #><span class="description customize-control-description">{{{ field.description }}}</span><# } #>
<div class="customize-control-content repeater-dropdown-pages">{{{ field.dropdown }}}</div>
</label>
<# } else if ( 'radio' === field.type ) { #>
<label>
<# if ( field.label ) { #><span class="customize-control-title">{{{ field.label }}}</span><# } #>
<# if ( field.description ) { #><span class="description customize-control-description">{{{ field.description }}}</span><# } #>
<# _.each( field.choices, function( choice, i ) { #>
<label><input type="radio" name="{{{ field.id }}}{{ index }}" data-field="{{{ field.id }}}" value="{{{ i }}}" <# if ( field.default == i ) { #> checked="checked" <# } #>> {{ choice }} <br/></label>
<# }); #>
</label>
<# } else if ( 'radio-image' === field.type ) { #>
<label>
<# if ( field.label ) { #><span class="customize-control-title">{{{ field.label }}}</span><# } #>
<# if ( field.description ) { #><span class="description customize-control-description">{{{ field.description }}}</span><# } #>
<# _.each( field.choices, function( choice, i ) { #>
<input type="radio" id="{{{ field.id }}}_{{ index }}_{{{ i }}}" name="{{{ field.id }}}{{ index }}" data-field="{{{ field.id }}}" value="{{{ i }}}" <# if ( field.default == i ) { #> checked="checked" <# } #>>
<label for="{{{ field.id }}}_{{ index }}_{{{ i }}}"><img src="{{ choice }}"></label>
</input>
<# }); #>
</label>
<# } else if ( 'color' === field.type ) { #>
<label>
<# if ( field.label ) { #><span class="customize-control-title">{{{ field.label }}}</span><# } #>
<# if ( field.description ) { #><span class="description customize-control-description">{{{ field.description }}}</span><# } #>
</label>
<# var defaultValue = '';
if ( field.default ) {
if ( -1 === field.default.indexOf( 'rgba' ) ) {
defaultValue = ( '#' !== field.default.substring( 0, 1 ) ) ? '#' + field.default : field.default;
defaultValue = ' data-default-color=' + defaultValue; // Quotes added automatically.
} else {
defaultValue = ' data-default-color="' + defaultValue + '" data-alpha="true"';
}
} #>
<input class="color-picker-hex" type="text" maxlength="7" value="{{{ field.default }}}" data-field="{{{ field.id }}}" {{ defaultValue }} />
<# } else if ( 'textarea' === field.type ) { #>
<# if ( field.label ) { #><span class="customize-control-title">{{{ field.label }}}</span><# } #>
<# if ( field.description ) { #><span class="description customize-control-description">{{{ field.description }}}</span><# } #>
<textarea rows="5" data-field="{{{ field.id }}}">{{ field.default }}</textarea>
<# } else if ( field.type === 'image' || field.type === 'cropped_image' ) { #>
<label>
<# if ( field.label ) { #><span class="customize-control-title">{{{ field.label }}}</span><# } #>
<# if ( field.description ) { #><span class="description customize-control-description">{{{ field.description }}}</span><# } #>
</label>
<figure class="kirki-image-attachment" data-placeholder="<?php esc_attr_e( 'No Image Selected', 'kirki' ); ?>" >
<# if ( field.default ) { #>
<# var defaultImageURL = ( field.default.url ) ? field.default.url : field.default; #>
<img src="{{{ defaultImageURL }}}">
<# } else { #>
<?php esc_html_e( 'No Image Selected', 'kirki' ); ?>
<# } #>
</figure>
<div class="actions">
<button type="button" class="button remove-button<# if ( ! field.default ) { #> hidden<# } #>"><?php esc_html_e( 'Remove', 'kirki' ); ?></button>
<button type="button" class="button upload-button" data-label=" <?php esc_attr_e( 'Add Image', 'kirki' ); ?>" data-alt-label="<?php echo esc_attr_e( 'Change Image', 'kirki' ); ?>" >
<# if ( field.default ) { #>
<?php esc_html_e( 'Change Image', 'kirki' ); ?>
<# } else { #>
<?php esc_html_e( 'Add Image', 'kirki' ); ?>
<# } #>
</button>
<# if ( field.default.id ) { #>
<input type="hidden" class="hidden-field" value="{{{ field.default.id }}}" data-field="{{{ field.id }}}" >
<# } else { #>
<input type="hidden" class="hidden-field" value="{{{ field.default }}}" data-field="{{{ field.id }}}" >
<# } #>
</div>
<# } else if ( field.type === 'upload' ) { #>
<label>
<# if ( field.label ) { #><span class="customize-control-title">{{{ field.label }}}</span><# } #>
<# if ( field.description ) { #><span class="description customize-control-description">{{{ field.description }}}</span><# } #>
</label>
<figure class="kirki-file-attachment" data-placeholder="<?php esc_attr_e( 'No File Selected', 'kirki' ); ?>" >
<# if ( field.default ) { #>
<# var defaultFilename = ( field.default.filename ) ? field.default.filename : field.default; #>
<span class="file"><span class="dashicons dashicons-media-default"></span> {{ defaultFilename }}</span>
<# } else { #>
<?php esc_html_e( 'No File Selected', 'kirki' ); ?>
<# } #>
</figure>
<div class="actions">
<button type="button" class="button remove-button<# if ( ! field.default ) { #> hidden<# } #>"><?php esc_html_e( 'Remove', 'kirki' ); ?></button>
<button type="button" class="button upload-button" data-label="<?php esc_attr_e( 'Add File', 'kirki' ); ?>" data-alt-label="<?php esc_attr_e( 'Change File', 'kirki' ); ?>">
<# if ( field.default ) { #>
<?php esc_html_e( 'Change File', 'kirki' ); ?>
<# } else { #>
<?php esc_html_e( 'Add File', 'kirki' ); ?>
<# } #>
</button>
<# if ( field.default.id ) { #>
<input type="hidden" class="hidden-field" value="{{{ field.default.id }}}" data-field="{{{ field.id }}}" >
<# } else { #>
<input type="hidden" class="hidden-field" value="{{{ field.default }}}" data-field="{{{ field.id }}}" >
<# } #>
</div>
<# } else if ( 'custom' === field.type ) { #>
<# if ( field.label ) { #><span class="customize-control-title">{{{ field.label }}}</span><# } #>
<# if ( field.description ) { #><span class="description customize-control-description">{{{ field.description }}}</span><# } #>
<div data-field="{{{ field.id }}}">{{{ field.default }}}</div>
<# } #>
</div>
<# }); #>
<button type="button" class="button-link repeater-row-remove"><?php esc_html_e( 'Remove', 'kirki' ); ?></button>
</div>
</li>
</script>
<?php
}
/**
* Validate row-labels.
*
* @access protected
* @since 3.0.0
* @param array $args {@see WP_Customize_Control::__construct}.
*/
protected function row_label( $args ) {
// Validating args for row labels.
if ( isset( $args['row_label'] ) && is_array( $args['row_label'] ) && ! empty( $args['row_label'] ) ) {
// Validating row label type.
if ( isset( $args['row_label']['type'] ) && ( 'text' === $args['row_label']['type'] || 'field' === $args['row_label']['type'] ) ) {
$this->row_label['type'] = $args['row_label']['type'];
}
// Validating row label type.
if ( isset( $args['row_label']['value'] ) && ! empty( $args['row_label']['value'] ) ) {
$this->row_label['value'] = esc_html( $args['row_label']['value'] );
}
// Validating row label field.
if ( isset( $args['row_label']['field'] ) && ! empty( $args['row_label']['field'] ) && isset( $args['fields'][ sanitize_key( $args['row_label']['field'] ) ] ) ) {
$this->row_label['field'] = esc_html( $args['row_label']['field'] );
} else {
// If from field is not set correctly, making sure standard is set as the type.
$this->row_label['type'] = 'text';
}
}
}
}

View file

@ -0,0 +1,58 @@
<?php
/**
* Customizer Control: kirki-select.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 1.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Select control.
*/
class Kirki_Control_Select extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-select';
/**
* Placeholder text.
*
* @access public
* @since 3.0.21
* @var string|false
*/
public $placeholder = false;
/**
* Maximum number of options the user will be able to select.
* Set to 1 for single-select.
*
* @access public
* @var int
*/
public $multiple = 1;
/**
* Refresh the parameters passed to the JavaScript via JSON.
*
* @see WP_Customize_Control::to_json()
*/
public function to_json() {
parent::to_json();
$this->json['multiple'] = $this->multiple;
$this->json['placeholder'] = $this->placeholder;
}
}

View file

@ -0,0 +1,76 @@
<?php
/**
* Customizer Control: slider.
*
* Creates a jQuery slider control.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 1.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Slider control (range).
*/
class Kirki_Control_Slider extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-slider';
/**
* Refresh the parameters passed to the JavaScript via JSON.
*
* @see WP_Customize_Control::to_json()
*/
public function to_json() {
parent::to_json();
$this->json['choices'] = wp_parse_args(
$this->json['choices'],
array(
'min' => '0',
'max' => '100',
'step' => '1',
'suffix' => '',
)
);
}
/**
* An Underscore (JS) template for this control's content (but not its container).
*
* Class variables for this control class are available in the `data` JS object;
* export custom variables by overriding {@see WP_Customize_Control::to_json()}.
*
* @see WP_Customize_Control::print_template()
*
* @access protected
*/
protected function content_template() {
?>
<label>
<# if ( data.label ) { #><span class="customize-control-title">{{{ data.label }}}</span><# } #>
<# if ( data.description ) { #><span class="description customize-control-description">{{{ data.description }}}</span><# } #>
<div class="wrapper">
<input {{{ data.inputAttrs }}} type="range" min="{{ data.choices['min'] }}" max="{{ data.choices['max'] }}" step="{{ data.choices['step'] }}" value="{{ data.value }}" {{{ data.link }}} />
<span class="slider-reset dashicons dashicons-image-rotate"><span class="screen-reader-text"><?php esc_html_e( 'Reset', 'kirki' ); ?></span></span>
<span class="value">
<input {{{ data.inputAttrs }}} type="text"/>
<span class="suffix">{{ data.choices['suffix'] }}</span>
</span>
</div>
</label>
<?php
}
}

View file

@ -0,0 +1,71 @@
<?php
/**
* Customizer Control: sortable.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 1.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Sortable control (uses checkboxes).
*/
class Kirki_Control_Sortable extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-sortable';
/**
* An Underscore (JS) template for this control's content (but not its container).
*
* Class variables for this control class are available in the `data` JS object;
* export custom variables by overriding {@see WP_Customize_Control::to_json()}.
*
* @see WP_Customize_Control::print_template()
*
* @access protected
*/
protected function content_template() {
?>
<label class='kirki-sortable'>
<span class="customize-control-title">
{{{ data.label }}}
</span>
<# if ( data.description ) { #>
<span class="description customize-control-description">{{{ data.description }}}</span>
<# } #>
<ul class="sortable">
<# _.each( data.value, function( choiceID ) { #>
<li {{{ data.inputAttrs }}} class='kirki-sortable-item' data-value='{{ choiceID }}'>
<i class='dashicons dashicons-menu'></i>
<i class="dashicons dashicons-visibility visibility"></i>
{{{ data.choices[ choiceID ] }}}
</li>
<# }); #>
<# _.each( data.choices, function( choiceLabel, choiceID ) { #>
<# if ( -1 === data.value.indexOf( choiceID ) ) { #>
<li {{{ data.inputAttrs }}} class='kirki-sortable-item invisible' data-value='{{ choiceID }}'>
<i class='dashicons dashicons-menu'></i>
<i class="dashicons dashicons-visibility visibility"></i>
{{{ data.choices[ choiceID ] }}}
</li>
<# } #>
<# }); #>
</ul>
</label>
<?php
}
}

View file

@ -0,0 +1,63 @@
<?php
/**
* Customizer Control: switch.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 1.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Switch control (modified checkbox).
*/
class Kirki_Control_Switch extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-switch';
/**
* An Underscore (JS) template for this control's content (but not its container).
*
* Class variables for this control class are available in the `data` JS object;
* export custom variables by overriding {@see WP_Customize_Control::to_json()}.
*
* @see WP_Customize_Control::print_template()
*
* @access protected
*/
protected function content_template() {
?>
<div class="switch<# if ( data.choices['round'] ) { #> round<# } #>">
<span class="customize-control-title">
{{{ data.label }}}
</span>
<# if ( data.description ) { #>
<span class="description customize-control-description">{{{ data.description }}}</span>
<# } #>
<input class="screen-reader-text" {{{ data.inputAttrs }}} name="switch_{{ data.id }}" id="switch_{{ data.id }}" type="checkbox" value="{{ data.value }}" {{{ data.link }}}<# if ( '1' == data.value ) { #> checked<# } #> />
<label class="switch-label" for="switch_{{ data.id }}">
<span class="switch-on">
<# data.choices.on = data.choices.on || '<?php esc_html_e( 'On', 'kirki' ); ?>' #>
{{ data.choices.on }}
</span>
<span class="switch-off">
<# data.choices.off = data.choices.off || '<?php esc_html_e( 'Off', 'kirki' ); ?>' #>
{{ data.choices.off }}
</span>
</label>
</div>
<?php
}
}

View file

@ -0,0 +1,54 @@
<?php
/**
* Customizer Control: toggle.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 1.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Toggle control (modified checkbox).
*/
class Kirki_Control_Toggle extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-toggle';
/**
* An Underscore (JS) template for this control's content (but not its container).
*
* Class variables for this control class are available in the `data` JS object;
* export custom variables by overriding {@see WP_Customize_Control::to_json()}.
*
* @see WP_Customize_Control::print_template()
*
* @access protected
*/
protected function content_template() {
?>
<label for="toggle_{{ data.id }}">
<span class="customize-control-title">
{{{ data.label }}}
</span>
<# if ( data.description ) { #>
<span class="description customize-control-description">{{{ data.description }}}</span>
<# } #>
<input class="screen-reader-text" {{{ data.inputAttrs }}} name="toggle_{{ data.id }}" id="toggle_{{ data.id }}" type="checkbox" value="{{ data.value }}" {{{ data.link }}}<# if ( '1' == data.value ) { #> checked<# } #> hidden />
<span class="switch"></span>
</label>
<?php
}
}

View file

@ -0,0 +1,254 @@
<?php
/**
* Customizer Control: typography.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 2.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Typography control.
*/
class Kirki_Control_Typography extends Kirki_Control_Base {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'kirki-typography';
/**
* Refresh the parameters passed to the JavaScript via JSON.
*
* @see WP_Customize_Control::to_json()
*/
public function to_json() {
parent::to_json();
if ( is_array( $this->json['value'] ) ) {
foreach ( array_keys( $this->json['value'] ) as $key ) {
if ( ! in_array( $key, array( 'variant', 'font-weight', 'font-style' ), true ) && ! isset( $this->json['default'][ $key ] ) ) {
unset( $this->json['value'][ $key ] );
}
// Fix for https://wordpress.org/support/topic/white-font-after-updateing-to-3-0-16.
if ( ! isset( $this->json['default'][ $key ] ) ) {
unset( $this->json['value'][ $key ] );
}
// Fix for https://github.com/aristath/kirki/issues/1405.
if ( isset( $this->json['default'][ $key ] ) && false === $this->json['default'][ $key ] ) {
unset( $this->json['value'][ $key ] );
}
}
}
$this->json['show_variants'] = ( true === Kirki_Fonts_Google::$force_load_all_variants ) ? false : true;
}
/**
* An Underscore (JS) template for this control's content (but not its container).
*
* Class variables for this control class are available in the `data` JS object;
* export custom variables by overriding {@see WP_Customize_Control::to_json()}.
*
* @see WP_Customize_Control::print_template()
*
* @access protected
*/
protected function content_template() {
?>
<label class="customizer-text">
<# if ( data.label ) { #><span class="customize-control-title">{{{ data.label }}}</span><# } #>
<# if ( data.description ) { #><span class="description customize-control-description">{{{ data.description }}}</span><# } #>
</label>
<div class="wrapper">
<# if ( ! _.isUndefined( data.default['font-family'] ) ) { #>
<# data.value['font-family'] = data.value['font-family'] || data['default']['font-family']; #>
<# if ( data.choices['fonts'] ) { data.fonts = data.choices['fonts']; } #>
<div class="font-family">
<h5><?php esc_html_e( 'Font Family', 'kirki' ); ?></h5>
<select {{{ data.inputAttrs }}} id="kirki-typography-font-family-{{{ data.id }}}" placeholder="<?php esc_attr_e( 'Select Font Family', 'kirki' ); ?>"></select>
</div>
<# if ( ! _.isUndefined( data.choices['font-backup'] ) && true === data.choices['font-backup'] ) { #>
<div class="font-backup hide-on-standard-fonts kirki-font-backup-wrapper">
<h5><?php esc_html_e( 'Backup Font', 'kirki' ); ?></h5>
<select {{{ data.inputAttrs }}} id="kirki-typography-font-backup-{{{ data.id }}}" placeholder="<?php esc_attr_e( 'Select Font Family', 'kirki' ); ?>"></select>
</div>
<# } #>
<# if ( true === data.show_variants || false !== data.default.variant ) { #>
<div class="variant kirki-variant-wrapper">
<h5><?php esc_html_e( 'Variant', 'kirki' ); ?></h5>
<select {{{ data.inputAttrs }}} class="variant" id="kirki-typography-variant-{{{ data.id }}}"></select>
</div>
<# } #>
<# } #>
<# if ( ! _.isUndefined( data.default['font-size'] ) ) { #>
<# data.value['font-size'] = data.value['font-size'] || data['default']['font-size']; #>
<div class="font-size">
<h5><?php esc_html_e( 'Font Size', 'kirki' ); ?></h5>
<input {{{ data.inputAttrs }}} type="text" value="{{ data.value['font-size'] }}"/>
</div>
<# } #>
<# if ( ! _.isUndefined( data.default['line-height'] ) ) { #>
<# data.value['line-height'] = data.value['line-height'] || data['default']['line-height']; #>
<div class="line-height">
<h5><?php esc_html_e( 'Line Height', 'kirki' ); ?></h5>
<input {{{ data.inputAttrs }}} type="text" value="{{ data.value['line-height'] }}"/>
</div>
<# } #>
<# if ( ! _.isUndefined( data.default['letter-spacing'] ) ) { #>
<# data.value['letter-spacing'] = data.value['letter-spacing'] || data['default']['letter-spacing']; #>
<div class="letter-spacing">
<h5><?php esc_html_e( 'Letter Spacing', 'kirki' ); ?></h5>
<input {{{ data.inputAttrs }}} type="text" value="{{ data.value['letter-spacing'] }}"/>
</div>
<# } #>
<# if ( ! _.isUndefined( data.default['word-spacing'] ) ) { #>
<# data.value['word-spacing'] = data.value['word-spacing'] || data['default']['word-spacing']; #>
<div class="word-spacing">
<h5><?php esc_html_e( 'Word Spacing', 'kirki' ); ?></h5>
<input {{{ data.inputAttrs }}} type="text" value="{{ data.value['word-spacing'] }}"/>
</div>
<# } #>
<# if ( ! _.isUndefined( data.default['text-align'] ) ) { #>
<# data.value['text-align'] = data.value['text-align'] || data['default']['text-align']; #>
<div class="text-align">
<h5><?php esc_html_e( 'Text Align', 'kirki' ); ?></h5>
<div class="text-align-choices">
<input {{{ data.inputAttrs }}} type="radio" value="inherit" name="_customize-typography-text-align-radio-{{ data.id }}" id="{{ data.id }}-text-align-inherit" <# if ( data.value['text-align'] === 'inherit' ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}-text-align-inherit">
<span class="dashicons dashicons-editor-removeformatting"></span>
<span class="screen-reader-text"><?php esc_html_e( 'Inherit', 'kirki' ); ?></span>
</label>
</input>
<input {{{ data.inputAttrs }}} type="radio" value="left" name="_customize-typography-text-align-radio-{{ data.id }}" id="{{ data.id }}-text-align-left" <# if ( data.value['text-align'] === 'left' ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}-text-align-left">
<span class="dashicons dashicons-editor-alignleft"></span>
<span class="screen-reader-text"><?php esc_html_e( 'Left', 'kirki' ); ?></span>
</label>
</input>
<input {{{ data.inputAttrs }}} type="radio" value="center" name="_customize-typography-text-align-radio-{{ data.id }}" id="{{ data.id }}-text-align-center" <# if ( data.value['text-align'] === 'center' ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}-text-align-center">
<span class="dashicons dashicons-editor-aligncenter"></span>
<span class="screen-reader-text"><?php esc_html_e( 'Center', 'kirki' ); ?></span>
</label>
</input>
<input {{{ data.inputAttrs }}} type="radio" value="right" name="_customize-typography-text-align-radio-{{ data.id }}" id="{{ data.id }}-text-align-right" <# if ( data.value['text-align'] === 'right' ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}-text-align-right">
<span class="dashicons dashicons-editor-alignright"></span>
<span class="screen-reader-text"><?php esc_html_e( 'Right', 'kirki' ); ?></span>
</label>
</input>
<input {{{ data.inputAttrs }}} type="radio" value="justify" name="_customize-typography-text-align-radio-{{ data.id }}" id="{{ data.id }}-text-align-justify" <# if ( data.value['text-align'] === 'justify' ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}-text-align-justify">
<span class="dashicons dashicons-editor-justify"></span>
<span class="screen-reader-text"><?php esc_html_e( 'Justify', 'kirki' ); ?></span>
</label>
</input>
</div>
</div>
<# } #>
<# if ( ! _.isUndefined( data.default['text-transform'] ) ) { #>
<# data.value['text-transform'] = data.value['text-transform'] || data['default']['text-transform']; #>
<div class="text-transform">
<h5><?php esc_html_e( 'Text Transform', 'kirki' ); ?></h5>
<select {{{ data.inputAttrs }}} id="kirki-typography-text-transform-{{{ data.id }}}">
<option value=""<# if ( '' === data.value['text-transform'] ) { #>selected<# } #>></option>
<option value="none"<# if ( 'none' === data.value['text-transform'] ) { #>selected<# } #>><?php esc_html_e( 'None', 'kirki' ); ?></option>
<option value="capitalize"<# if ( 'capitalize' === data.value['text-transform'] ) { #>selected<# } #>><?php esc_html_e( 'Capitalize', 'kirki' ); ?></option>
<option value="uppercase"<# if ( 'uppercase' === data.value['text-transform'] ) { #>selected<# } #>><?php esc_html_e( 'Uppercase', 'kirki' ); ?></option>
<option value="lowercase"<# if ( 'lowercase' === data.value['text-transform'] ) { #>selected<# } #>><?php esc_html_e( 'Lowercase', 'kirki' ); ?></option>
<option value="initial"<# if ( 'initial' === data.value['text-transform'] ) { #>selected<# } #>><?php esc_html_e( 'Initial', 'kirki' ); ?></option>
<option value="inherit"<# if ( 'inherit' === data.value['text-transform'] ) { #>selected<# } #>><?php esc_html_e( 'Inherit', 'kirki' ); ?></option>
</select>
</div>
<# } #>
<# if ( ! _.isUndefined( data.default['text-decoration'] ) ) { #>
<# data.value['text-decoration'] = data.value['text-decoration'] || data['default']['text-decoration']; #>
<div class="text-decoration">
<h5><?php esc_html_e( 'Text Decoration', 'kirki' ); ?></h5>
<select {{{ data.inputAttrs }}} id="kirki-typography-text-decoration-{{{ data.id }}}">
<option value=""<# if ( '' === data.value['text-decoration'] ) { #>selected<# } #>></option>
<option value="none"<# if ( 'none' === data.value['text-decoration'] ) { #>selected<# } #>><?php esc_html_e( 'None', 'kirki' ); ?></option>
<option value="underline"<# if ( 'underline' === data.value['text-decoration'] ) { #>selected<# } #>><?php esc_html_e( 'Underline', 'kirki' ); ?></option>
<option value="overline"<# if ( 'overline' === data.value['text-decoration'] ) { #>selected<# } #>><?php esc_html_e( 'Overline', 'kirki' ); ?></option>
<option value="line-through"<# if ( 'line-through' === data.value['text-decoration'] ) { #>selected<# } #>><?php esc_html_e( 'Line-Through', 'kirki' ); ?></option>
<option value="initial"<# if ( 'initial' === data.value['text-decoration'] ) { #>selected<# } #>><?php esc_html_e( 'Initial', 'kirki' ); ?></option>
<option value="inherit"<# if ( 'inherit' === data.value['text-decoration'] ) { #>selected<# } #>><?php esc_html_e( 'Inherit', 'kirki' ); ?></option>
</select>
</div>
<# } #>
<# if ( ! _.isUndefined( data.default['margin-top'] ) ) { #>
<# data.value['margin-top'] = data.value['margin-top'] || data['default']['margin-top']; #>
<div class="margin-top">
<h5><?php esc_html_e( 'Margin Top', 'kirki' ); ?></h5>
<input {{{ data.inputAttrs }}} type="text" value="{{ data.value['margin-top'] }}"/>
</div>
<# } #>
<# if ( ! _.isUndefined( data.default['margin-bottom'] ) ) { #>
<# data.value['margin-bottom'] = data.value['margin-bottom'] || data['default']['margin-bottom']; #>
<div class="margin-bottom">
<h5><?php esc_html_e( 'Margin Bottom', 'kirki' ); ?></h5>
<input {{{ data.inputAttrs }}} type="text" value="{{ data.value['margin-bottom'] }}"/>
</div>
<# } #>
<# if ( ! _.isUndefined( data.default['color'] ) && false !== data.default['color'] ) { #>
<# data.value['color'] = data.value['color'] || data['default']['color']; #>
<div class="color">
<h5><?php esc_html_e( 'Color', 'kirki' ); ?></h5>
<input {{{ data.inputAttrs }}} type="text" data-palette="{{ data.palette }}" data-default-color="{{ data.default['color'] }}" value="{{ data.value['color'] }}" class="kirki-color-control"/>
</div>
<# } #>
</div>
<input class="typography-hidden-value" type="hidden" {{{ data.link }}}>
<?php
}
/**
* Formats variants.
*
* @access protected
* @since 3.0.0
* @param array $variants The variants.
* @return array
*/
protected function format_variants_array( $variants ) {
$all_variants = Kirki_Fonts::get_all_variants();
$final_variants = array();
foreach ( $variants as $variant ) {
if ( is_string( $variant ) ) {
$final_variants[] = array(
'id' => $variant,
'label' => isset( $all_variants[ $variant ] ) ? $all_variants[ $variant ] : $variant,
);
} elseif ( is_array( $variant ) && isset( $variant['id'] ) && isset( $variant['label'] ) ) {
$final_variants[] = $variant;
}
}
return $final_variants;
}
}

View file

@ -0,0 +1,37 @@
<?php
/**
* Customizer Control: image.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 3.0.23
*/
/**
* Adds the image control.
*/
class Kirki_Control_Upload extends WP_Customize_Upload_Control {
/**
* Whitelisting the "required" argument.
*
* @since 3.0.17
* @access public
* @var array
*/
public $required = array();
/**
* Refresh the parameters passed to the JavaScript via JSON.
*
* @since 3.0.23
*
* @uses WP_Customize_Media_Control::to_json()
*/
public function to_json() {
parent::to_json();
$this->json['required'] = $this->required;
}
}

View file

@ -0,0 +1,79 @@
<?php
/**
* Repeater Customizer Setting.
*
* @package Kirki
* @subpackage Controls
* @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
* @license https://opensource.org/licenses/MIT
* @since 2.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Repeater Settings.
*/
class Kirki_Settings_Repeater_Setting extends WP_Customize_Setting {
/**
* Constructor.
*
* Any supplied $args override class property defaults.
*
* @access public
* @param WP_Customize_Manager $manager The WordPress WP_Customize_Manager object.
* @param string $id A specific ID of the setting. Can be a theme mod or option name.
* @param array $args Setting arguments.
*/
public function __construct( $manager, $id, $args = array() ) {
parent::__construct( $manager, $id, $args );
// Will onvert the setting from JSON to array. Must be triggered very soon.
add_filter( "customize_sanitize_{$this->id}", array( $this, 'sanitize_repeater_setting' ), 10, 1 );
}
/**
* Fetch the value of the setting.
*
* @access public
* @return mixed The value.
*/
public function value() {
return (array) parent::value();
}
/**
* Convert the JSON encoded setting coming from Customizer to an Array.
*
* @access public
* @param string $value URL Encoded JSON Value.
* @return array
*/
public function sanitize_repeater_setting( $value ) {
if ( ! is_array( $value ) ) {
$value = json_decode( urldecode( $value ) );
}
if ( empty( $value ) || ! is_array( $value ) ) {
$value = array();
}
// Make sure that every row is an array, not an object.
foreach ( $value as $key => $val ) {
$value[ $key ] = (array) $val;
if ( empty( $val ) ) {
unset( $value[ $key ] );
}
}
// Reindex array.
if ( is_array( $value ) ) {
$value = array_values( $value );
}
return $value;
}
}