/**
* Страница настроек темы
* Автор: Kama
* v 0.1
*/
Themeopt::init();
class Themeopt{
const OPT_NAME = 'theme_options';
const PAGE_ID = 'theme_options_page';
static $i;
public $opt;
static function init(){
if( ! is_null( self::$i ) ) return self::$i;
return self::$i = new self;
}
function __construct(){
$this->opt = (object) get_option( self::OPT_NAME );
add_action('admin_init', array( &$this, 'register_settings') );
// добавим меню
add_action('admin_menu', array( &$this, 'add_menu_page') );
}
## Возвращает опцию, когда запрашивается несуществующее свойство
function __get( $name ){
return @ self::$i->opt->$name ?: false;
}
## Регистрируем настройки
function register_settings(){
register_setting( self::PAGE_ID, self::OPT_NAME, array( &$this, 'validate_settings') );
}
## Добавляем страницу в меню
function add_menu_page(){
// $hook_name = add_menu_page( 'Настройки темы', 'Настройки темы', 'manage_options', self::PAGE_ID, array( &$this, 'page_out'), 'dashicons-admin-generic', 100);
$hook_name = add_submenu_page('themes.php', 'Настройки темы', 'Настройки темы', 'manage_options', self::PAGE_ID, array( &$this, 'page_out') );
add_action("load-$hook_name", array( & $this, 'page_load') );
}
## Загрузка страницы
function page_load(){
$this->register_settings_sections();
}
## HTML вывод страницы
function page_out(){
do_action( 'before_theme_options' );
?>
<div class="wrap">
<h2>Настройки темы</h2>
<form method="POST" enctype="multipart/form-data" action="<?php echo admin_url('options.php') ?>">
<?php
settings_fields( self::PAGE_ID ); // меняем под себя только здесь (название настроек)
do_settings_sections( self::PAGE_ID );
?>
<p class="submit">
<input type="submit" class="button-primary" value="<?php _e('Сохранить') ?>" />
</p>
</form>
</div>
<?php
do_action( 'after_theme_options' );
}
## регистрирует поля настроек
function register_settings_sections(){
do_action( 'theme_register_settings_sections', $this );
// ПЕРВАЯ секция
$section = 'section_1';
add_settings_section( $section, 'Секция 1', '', self::PAGE_ID );
// текстовое поле в первой секции
$id = 'my_text_field';
add_settings_field( $id, 'Текстовое поле', array( __CLASS__, 'display_field'), self::PAGE_ID, $section, array(
'id' => $id,
'label_for' => $id,
'desc' => 'Пример обычного текстового поля.', // описание
) );
// textarea в первой секции
$id = 'my_textarea_field';
add_settings_field( $id, 'Большое текстовое поле', array( __CLASS__, 'display_field'), self::PAGE_ID, $section, array(
'id' => $id,
'type' => 'textarea',
'attr' => 'style="width:100%;"',
'desc' => 'Пример большого текстового поля.'
) );
// ВТОРАЯ секция
$section = 'section_2';
add_settings_section( $section, 'Секция 2', '', self::PAGE_ID );
// чекбокс
$id = 'my_checkbox_field';
add_settings_field( $id, 'Чекбокс', array( __CLASS__, 'display_field'), self::PAGE_ID, $section, array(
'id' => $id,
'type' => 'checkbox',
'desc' => 'Пример чекбокса.'
) );
// выпадающий список
$id = 'my_select_field';
add_settings_field( $id, 'Выпадающий список', array( __CLASS__, 'display_field'), self::PAGE_ID, $section, array(
'id' => $id,
'type' => 'select',
'desc' => 'Пример выпадающего списка.',
'options' => array( 'val1' => 'Значение 1', 'val2' => 'Значение 2', 'val3' => 'Значение 3')
) );
// радио-кнопку
$id = 'my_radio';
add_settings_field( $id, 'Радио кнопки', array( __CLASS__, 'display_field'), self::PAGE_ID, $section, array(
'id' => $id,
'type' => 'radio',
'options' => array( 'val1' => 'Значение 1', 'val2' => 'Значение 2', 'val3' => 'Значение 3')
) );
}
/**
* Выводит поля форм
* @param array $args Параметры поля
*/
static function display_field( $args ){
$def = array(
'type' => '', // по умолчанию text
'desc' => '', // описание
'val' => '', // значение по умолчанию, если нет сохраненного
'options' => '', // варианты для select и radio
'id' => '', // id атрибут
'array_key' => '', // ключ массива, когда/чтобы настройка сохранялась во вложенный массив
'attr' => '', // любая строка, будет расположена внутри тега. Для создания атрибутов. Пр: style="width:100%;"
'opt_name' => '', // название опций, чтобы метод можно было вызывать вне этого класса. По умолчанию: self::OPT_NAME
'placeholder' => '', // placeholder
// 'class'=>'', 'label_for'=>'' заняты
);
extract( array_merge( $def, $args ) );
if( ! $type )
$type = 'text';
if( ! $opt_name ) $opt_name = self::OPT_NAME; // название опций по умолчанию, чтобы метод можно было вызывать вне этого класса
$opt = get_option( $opt_name );
$name = $opt_name . ($array_key?"[$array_key]":'') ."[$id]";
$val = ($array_key ? @ $opt[ $array_key ][ $id ] : @ $opt[ $id ]) ?: $val;
$placeholder = $placeholder ? ' placeholder="'. $placeholder .'"' : '';
// textarea
if( $type == 'textarea' ){
$val = @ esc_attr( stripslashes($val) );
echo '<textarea '. $attr . $placeholder .' id="'. $id .'" name="'. $name .'">'. $val .'</textarea>'.
($desc ? '<br><span class="description">'. $desc .'</span>' : '');
}
// select
elseif( $type == 'select' ){
echo '<select '. $attr .' id="'. $id .'" name="'. $name .'">';
foreach( (array) $options as $v => $l )
echo '<option value="'. $v .'" '. selected(@ $val, $v, 0) .'>'. $l .'</option>';
echo ($desc ?: '').
'</select>';
}
// checkbox
elseif( $type == 'checkbox' ){
echo '
<label>
<input type="checkbox" id="'. $id .'" name="'. $name .'" value="1" '. checked( @ $val, 1, 0) .'>
'.($desc ?: '').'
</label>';
}
// radio
elseif( $type == 'radio' ){
echo '<fieldset>';
foreach( (array) $options as $v => $l )
echo '<label><input type="radio" name="'. $name .'" value="'. $v .'" '. checked(@ $val, $v, 0) .'>'. $l .'</label><br>';
echo '</fieldset>';
}
// text
else{
$class = ($type=='text') ? ' class="regular-text"' : '';
$val = @ esc_attr( stripslashes($val) );
echo '<input '. $attr . $class . $placeholder .' type="'. $type .'" id="'. $id .'" name="'. $name .'" value="'. $val .'">'.
($desc ? '<br><span class="description">'. $desc .'</span>' : '');
}
}
## Функция проверки/очистки сохраняемых данных
function validate_settings( $input ){
// обработка передаваемых данных
foreach( $input as $k => & $val ){
if( is_string( $val ) ) $val = trim( $val );
// foo
if( $k == 'foo' ){
$val = esc_html( $val );
}
}
return $input;
}
## Подключает скрипты опций
function __page_css_js(){
static $one; if( $one ) return $one = 1;
$tpl_url = get_template_directory_uri();
wp_enqueue_script( $this::OPT_NAME, $tpl_url .'/js/opt-page.js', array('jquery'), null, true );
wp_enqueue_script( $this::OPT_NAME, $tpl_url .'/js/example.css', array(), null );
}
}