WordPress как на ладони

Customize API

Кастомайзер — это API для создания функционала предварительного просмотра любых изменений в WordPress во фронте в реальном времени без перезагрузки страницы. Это универсальный интерфейс для настройки разных опций темы: цвета, маркеры, виджеты, меню и так далее.

Кастомайзер предоставляет механизм управления возможностями, то есть одни настройки вы можете отображать, к примеру, администраторам, другие редакторам, часть настроек для одной страницы, а часть для другой.

Объекты кастомайзера

API кастомайзера использует объектно-ориентированный подход.
Четыре типа объектов кастомайзера.

Существует четыре типа объектов кастомайзера:

  • Панели (panel) — Панели объединяют секции. Секция может существовать вне панели, то есть создание панели делается по желанию и выгодно, когда секций много и их нужно собраться в панель.
  • Секции (sections) — Секции объединяют элементы управления (текстовое поле, радиокнопки, выпадающие списки и так далее).
  • Элементы управления (controls) — Элементы управления не могут существовать вне секции.
  • Настройки (settings) — Настройки кастомайзера связывают элементы пользовательского интерфейса (controls) с настройками, хранящимися в базе данных.

К примеру, структура кастомайзера темы Twenty Seventeen такова:

  • Свойства сайта (секция), внутри 6 элементов управления
    • Выбор логотипа (выбор изображения)
    • Название сайта (текстовое поле)
    • Краткое описание (текстовое поле)
    • Отображать название и описание (флажок)
    • Иконка сайта (выбор изображения)
  • Цвета (секция), внутри 2 элемента управления
    • Цветовая схема (радиокнопки и ползунок)
    • Цвет текста заголовка (выбор цвета с помощью пипетки)
  • Медиафайл заголовка (секция)
    • Видео заголовка (выбор видео и поле для ссылки)
    • Изображение заголовка (выбор изображения)
  • Меню (панель), внутри секции в виде названий ваших меню, пусть их три
    • Верхнее меню (секция), внутри пункты меню являются элементами управления
      • Пункт меню 1
      • Пункт меню 2
      • Пункт меню 3
    • Меню продавца (секция)
      • Пункт меню 1
      • Пункт меню 2
    • Нижнее меню (секция)
      • Пункт меню 1
      • Пункт меню 2
      • Пункт меню 3
      • Пункт меню 4
    • Создать меню (секция)
      • Название меню (текстовое поле)
      • Области для меню (флажки)
      • Аккордеон (выбор типа) и списки с выбором пунктов меню
  • Виджеты (панель), внутри секции в виде названий областей меню, пусть их две
    • Боковая панель блога (секция), внутри виджеты (секции), внутри элементы управления виджетом
      • Виджет 1
      • Виджет 2
    • Подвал (секция)
      • Виджет 1
      • Виджет 2
      • Виджет 3
  • Настройки главной страницы (секция)
    • На главной странице отображать (радиокнопки)
  • Дополнительные стили (секция)
    • Добавьте собственный CSS (область текста с подсветкой CSS)

Используя методы объекта WP_Customize_Manager, можно добавлять/удалять/изменять объекты кастомайзера (панели, секции, элемент управления ...).

Основная работа проводится на хуке customize_register, в функцию которого передаётся объект WP_Customize_Manager:

add_action( 'customize_register', 'my_theme_customize_register' );

function my_theme_customize_register( WP_Customize_Manager $wp_customize ) {
	// Здесь делаем что-либо с $wp_customize - объектом класса WP_Customize_Manager, например

	// Действия с панелями
	$wp_customize->add_panel();     // добавить панель
	$wp_customize->get_panel();     // получить панель
	$wp_customize->remove_panel();  // удалить панель

	// Действия с секциями
	$wp_customize->add_section();    // добавить секцию
	$wp_customize->get_section();    // получить секцию
	$wp_customize->remove_section(); // удалить секцию

	// Действия с настройками
	$wp_customize->add_setting();    // добавить настройку
	$wp_customize->get_setting();    // получить настройку
	$wp_customize->remove_setting(); // удалить настройку

	// Действия с элементами управления
	$wp_customize->add_control();    // добавить элемент управления
	$wp_customize->get_control();    // получить элемент управления
	$wp_customize->remove_control(); // удалить элемент управления
}

Настройки

Настройки обеспечивают предпросмотр внесенных изменений, их очистку и сохранение. Настройки "следят" за элементами управлениями. К примеру, внесли изменение (выбрали цвет фона сайта) - он изменился без перезагрузки страницы. Если всё устроило - публикуете изменения, чтобы все пользователи сайта их увидели. Перед сохранением данные очищаются.

При добавлении новой настройки доступны несколько параметров:

$wp_customize->add_setting( 'setting_id', array(
	'type'                 => 'theme_mod',          // Или 'option'
	'capability'           => 'edit_theme_options', // Права доступ к изменению настроек кастомайзера.
	'theme_supports'       => '',                   // Требуется редко.
	'default'              => '',                   // Значение по умолчанию.
	'transport'            => 'refresh',            // Или 'postMessage'.
	'sanitize_callback'    => '',                   // Очистка данных на стороне PHP.
	'sanitize_js_callback' => '',                   // Очистка данных на стороне JavaScript. В основном 'to_json'.
) );

Подробнее смотрите метод WP_Customize_Manager::add_setting().

Некоторые ID настроек заняты движком, это:

  • widget_*
  • sidebars_widgets[*]
  • nav_menu[*]
  • nav_menu_item[*]

Поэтому пользуйтесь суффиксами при создании имен, например: homepage_widget.

Возможно два вида настроек, параметр type: option (опции) и theme_mod (модификации темы).

Опции (option)

Хранятся в таблице wp_options. Название опции в БД будет точно таким, какое вы указали в первом параметре ('setting_id').

Получать такие опции принято функцией get_option().

Такие опции могут быть использованы независимо от активной темы. К данному типу настроек подходят такие данные, как "Название сайта", которое не завит от того, какая тема установлена и на какую сменится в будущем.

Модификации темы (theme_mod)

Используются для темы и хранятся для каждой темы отдельно. Данные хранятся в виде сериализованного массива в таблице wp_options, в опции с названием theme_mods_THEME_NAME. Получать такие опции принято функцией get_theme_mod() или get_theme_mods().

К данному типу настроек подойдут например, цвет заголовка статей или фон сайта. Пусть у вас была "Тема А", вы её настроили. Потом решили попробовать "Тему Б", переключились и также настроили. Теперь при переключении тем, у каждой будут свои (разные) опции. Однако, если тут использовать тип настроек option, то установка настроек "Тема Б" переписала бы настройки "Темы А".

Куда сохраняются промежуточные настройки?

Во время изменения опций кастомайзера, но до их публикации (применения), WordPress сохраняет текущие измененные опции в таблицу wp_posts, в виде записи типа customize_changeset со статусом auto-draft.

Идентифицировать конкретную сессию изменения опций кастомайзера можно по имени записи: в поле post_name записывается уникальный id: customize_changeset_uuid, который выглядит так: 653acb14-b389-4d19-ba98-8968c976befa.

Таким образом, получить измененный опции (еще не опубликованные), можно получив контент записи с именем customize_changeset_uuid. В контенте, в виде JSON строки хранятся текущие измененные опции:

{
	"my_show_per_page": {
		"value": "10",
		"type": "option",
		"user_id": 5,
		"date_modified_gmt": "2019-06-21 16:28:30"
	},
	"my_main_swiper_effect": {
		"value": "flip",
		"type": "option",
		"user_id": 5,
		"date_modified_gmt": "2019-06-21 16:28:30"
	}
}

Добавление настроек в Customizer

Получать значения нужно функцией get_theme_mod():

echo get_theme_mod( 'my_setting_name' );

PHP

<?php

add_action( 'customize_register', 'customizer_init' );
add_action( 'customize_preview_init', 'customizer_js_file' );
add_action( 'wp_head', 'customizer_style_tag' );

function customizer_init( WP_Customize_Manager $wp_customize ){

	// как обновлять превью сайта:
	// 'refresh'     - перезагрузкой фрейма (можно полностью отказаться от JavaScript)
	// 'postMessage' - отправкой AJAX запроса
	$transport = 'postMessage';

	// Секция
	if( 'базовая - colors' ){

		// настройка
		$setting = 'link_color';

		$wp_customize->add_setting( $setting, [
			'default'     => '#000000',
			'transport'   => $transport
		] );

		$wp_customize->add_control(
			new WP_Customize_Color_Control( $wp_customize, $setting, [
				'label'    => 'Цвет ссылок',
				'section'  => 'colors',
				'settings' => $setting
			] )
		);

	}

	// Секция
	if( $section = 'display_options' ){

		$wp_customize->add_section( $section, [
			'title'     => 'Отображение',
			'priority'  => 200,                   // приоритет расположения
			'description' => 'Внешний вид сайта', // описание не обязательное
		] );

		// настройка
		$setting = 'display_header';

		$wp_customize->add_setting( $setting, [
			'default'    =>  'true',
			'transport'  =>  $transport
		] );

		$wp_customize->add_control( $setting, [
			'section' => $section,
			'label'   => 'Отобразить заголовок?',
			'type'    => 'checkbox',
		] );

		// настройка
		$setting = 'color_scheme';

		$wp_customize->add_setting( $setting, [
			'default'   => 'normal',
			'transport' => $transport
		] );

		$wp_customize->add_control( $setting, [
			'section'  => $section,
			'label'    => 'Цветовая схема',
			'type'     => 'radio',
			'choices'  => [
				'normal'    => 'Светлая',
				'inverse'   => 'Темная',
			]
		] );

		// настройка
		$setting = 'font';

		$wp_customize->add_setting( $setting, [
			'default'   => 'arial',     // этот шрифт будет задействован по умолчанию
			'type'      => 'theme_mod', // использовать get_theme_mod() для получения настроек, если указать 'option', то нужно будет использовать функцию get_option()
			'transport' => $transport
		] );

		$wp_customize->add_control( $setting, [
			'section'  => 'display_options', // секция
			'label'    => 'Шрифт',
			'type'     => 'select', // выпадающий список select
			'choices'  => [ // список значений и лейблов выпадающего списка в виде ассоциативного массива
				'arial'     => 'Arial',
				'courier'   => 'Courier New'
			]
		] );

		// настройка
		$setting = 'footer_copyright_text';

		$wp_customize->add_setting( $setting, [
			'default'            => 'Все права защищены',
			'sanitize_callback'  => 'sanitize_text_field',
			'transport'          => $transport
		] );

		$wp_customize->add_control( $setting, [
			'section'  => 'display_options', // id секции
			'label'    => 'Копирайт',
			'type'     => 'text' // текстовое поле
		] );

	}

	// секция
	if( $section = 'advanced_options' ){

		// Добавляем ещё одну секцию - Настройки фона
		$wp_customize->add_section( $section, [
			'title'    => 'Настройки фона',
			'priority' => 201,
		] );

		// настройка
		$setting = 'bg_image';

		$wp_customize->add_setting( $setting, [
				'default'      => '', // по умолчанию - фоновое изображение не установлено
				'transport'    => $transport
			]
		);

		$wp_customize->add_control(
			new WP_Customize_Image_Control( $wp_customize, $setting, [
				'label'    => 'Фон сайта',
				'settings' => 'bg_image',
				'section'  => 'advanced_options'
			] )
		);

		// Добавим кнопку в дизайн сайта в кастомайзере для быстрого перехода к текущей настройке
		// при transport = postMessage здесь можно указать функцию,
		// которая будет заменять часть дизайна (таким образом можно не писать JS код)
		if ( isset( $wp_customize->selective_refresh ) ){

			$wp_customize->selective_refresh->add_partial( $setting, [
				'selector'            => '.site-footer .inner',
				'container_inclusive' => false,
				'render_callback'     => 'footer_inner_dh5theme',
				'fallback_refresh'    => false, // Prevents refresh loop when document does not contain .cta-wrap selector. This should be fixed in WP 4.7.
			] );

			// поправим стиль, чтобы кнопку было видно
			add_action( 'wp_head', function(){
				echo '<style>.site-footer .inner .customize-partial-edit-shortcut{ margin: 10px 0 0 38px; }</style>';
			} );

		}

	}

}

function customizer_style_tag(){

	$style = [];

	$body_styles = [];

	switch( get_theme_mod( 'font' ) ){
		case 'arial':
			$body_styles[] = 'font-family: Arial, Helvetica, sans-serif;';
			break;
		case 'courier':
			$body_styles[] = 'font-family: "Courier New", Courier;';
			break;
		default:
			$body_styles[] = 'font-family: Arial, Helvetica, sans-serif;';
			break;
	}

	if( 'inverse' === get_theme_mod( 'color_scheme' ) )
		$body_styles[] = 'background-color:#000; color:#fff;';
	else
		$body_styles[] = 'background-color:#fff; color:#000;';

	if( $bg_image = get_theme_mod( 'bg_image' ) ){
		$body_styles[] = "background-image: url( '$bg_image' );";
	}

	$style[] = 'body { '. implode( ' ', $body_styles ) .' }';

	$style[] = 'a { color: ' . get_theme_mod( 'link_color' ) . '; }';

	if( ! get_theme_mod( 'display_header' ) )
		$style[] = '#header { display: none; }';

	echo "<style>\n" . implode( "\n", $style ) . "\n</style>\n";
}

function customizer_js_file(){
	wp_enqueue_script( 'theme-customizer', get_stylesheet_directory_uri() . '/js/theme-customizer.js', [ 'jquery', 'customize-preview' ], null, true );
}

theme-customizer.js

jQuery(function( $ ) {

	// настройка
	wp.customize( 'link_color', function( value ) {
		value.bind( function( newVal ) {
			$( 'a' ).css( 'color', newVal );
		} );
	});

	// настройка
	wp.customize( 'display_header', function( value ) {
		value.bind( function( newVal ) {
			false === newVal ? $( '#header' ).hide() : $( '#header' ).show();
		} );
	});

	// настройка
	wp.customize( 'color_scheme', function( value ) {
		value.bind( function( newVal ) {
			if ( 'inverse' === newVal ) {
				$( 'body' ).css({
					'background-color': '#000',
					'color'           : '#fff' 
				});
			}
			else {
				$( 'body' ).css({
					'background-color': '#fff',
					'color'           : '#000' 
				});
			}
		});
	});

	// настройка
	var sFont;
	wp.customize( 'font', function( value ) {
		value.bind( function( newVal ) {
			switch( newVal.toString().toLowerCase() ) {
				case 'arial':
					sFont = 'Arial, Helvetica, sans-serif';
					break;
				case 'courier':
					sFont = 'Courier New, Courier';
					break;
				default:
					sFont = 'Arial, Helvetica, sans-serif';
					break;
			}
			$( 'body' ).css({
				fontFamily: sFont
			});
		});

	});

	// настройка
	wp.customize( 'footer_copyright_text', function( value ) {
		value.bind( function( newVal ) {
			$( '#copyright' ).text( newVal );
		});
	});

	// настройка
	wp.customize( 'background_image', function( value ) {
		value.bind( function( newVal ) {
			0 === $.trim( newVal ).length ? $( 'body' ).css( 'background-image', '' ) : $( 'body' ).css( 'background-image', 'url( ' + newVal + ')' );
		});
	});

});

Методы

Методы для добавления настроек/секций.

$wp_customize->add_panel( $id, $args )

Добавляет панель.

$wp_customize->add_section( $id, $args )

Добавляет секцию.

$wp_customize->add_setting( $id, $args )

Добавляет новую настройку/опцию. В основе работы метода лежит класс WP_Customize_Setting().

$id(строка) (обязательный)
Название опции.
$args(массив)

Параметры настройки. Возможные ключи массива, все свойства класса WP_Customize_Setting{}:

  • $type(строка)
    Type of the setting.
    По умолчанию: 'theme_mod'

  • $capability(строка)
    Capability required for the setting.
    По умолчанию: 'edit_theme_options'

  • $theme_supports(строка/массив)
    Theme features required to support the panel.
    По умолчанию: none

  • $default(строка)
    Default value for the setting.
    По умолчанию: ''

  • $transport(строка)
    Параметры отображения предварительного просмотра изменений в Настройщике тем. Может быть:
    refresh — применяет изменения перезагрузкой фрейма (можно полностью отказаться от JavaScript).
    postMessage — применяет изменения через JavaScript.
    По умолчанию: 'refresh'

  • $validate_callback(callable)
    Server-side validation callback for the setting's value.
    Функция получит параметры $validity, $value, $this, смотрите хук customize_validate_(id)
    По умолчанию: ''

  • $sanitize_callback(callable)
    Callback to filter a Customize setting value in un-slashed form.
    Функция получит параметры $value, $this, смотрите хук customize_sanitize_(id)
    По умолчанию: ''

  • $sanitize_js_callback(callable)
    Callback to convert a Customize PHP setting value to a value that is JSON serializable.
    Функция получит параметры $value, $this, смотрите хук customize_sanitize_js_(id)
    По умолчанию: ''

  • $dirty(true/false)
    Whether or not the setting is initially dirty when created.
    По умолчанию: false

По умолчанию: предустановки

$wp_customize->add_control( $id, $args )

Добавляет элемент управления.

$id(WP_Customize_Control/строка) (обязательный)

Объект Customize Control или ID.

Строки, которые можно использовать: text, checkbox, textarea, radio, select, dropdown-pages, и email, url, number, hidden, date.

Объекты, которые можно использовать в качестве параметра $id.

Разные:

Image:

Nav_Menu:

Widget:

$args(массив)

Массив свойств для нового объекта управления.

Параметр нужно указывать, только когда в $id указывается строка, если в $id указывается объект, то параметры передаются в создаваемый объект.

  • $settings(массив)
    All settings tied to the control. If undefined. IDs in the array correspond to the ID of a registered WP_Customize_Setting.
    По умолчанию: $setting

  • $setting(строка)
    The primary setting for the control (if there is one).
    По умолчанию: 'default'

  • $capability(строка)
    Capability required to use this control. Normally derived from $settings.

  • $priority(число)
    Order priority to load the control.
    По умолчанию: 10

  • $section(строка)
    The section this control belongs to.
    По умолчанию: ''

  • $label(строка)
    Label for the control.
    По умолчанию: ''

  • $description(строка)
    Description for the control.
    По умолчанию: ''

  • $choices(массив)
    List of choices for 'radio' or 'select' type controls, where values are the keys, and labels are the values.
    По умолчанию: array()

  • $input_attrs(массив)
    List of custom input attributes for control output, where attribute names are the keys and values are the values.
    По умолчанию: array()

  • $allow_addition(true/false)
    Show UI for adding new content, currently only used for the dropdown-pages control.
    По умолчанию: false

  • $type(строка)
    The type of the control.
    По умолчанию: 'text'

  • $active_callback(callback)
    Active callback.

По умолчанию: array()

$wp_customize->selective_refresh->add_partial( $id, $args )
Adds a partial.

-

Офф. дока: Theme Customization API

11 комментариев
Полезные 1Вопросы 3 Все
    Войти