Когда я начал этот ответ, это была просто небольшая заметка. Ну, я потерпел неудачу. Сожалею! Оставайся со мной, там в глубине души спрятано ...
Как хранятся виджеты WordPress
Список виджетов хранится в опции с именем 'sidebars_widgets'
. А var_export()
может дать что-то вроде следующего:
array (
'wp_inactive_widgets' =>
array (
),
'top-widget' =>
array (
),
'bottom-widget' =>
array (
),
'array_version' => 3,
)
Игнорировать 'wp_inactive_widgets'
и 'array_version'
. Мы не должны заботиться о них.
Другие ключи являются идентификаторами для зарегистрированных боковых панелей. В этом случае боковые панели могут быть зарегистрированы с этим кодом:
// Register two sidebars.
$sidebars = array ( 'a' => 'top-widget', 'b' => 'bottom-widget' );
foreach ( $sidebars as $sidebar )
{
register_sidebar(
array (
'name' => $sidebar,
'id' => $sidebar,
'before_widget' => '',
'after_widget' => ''
)
);
}
По умолчанию боковые панели пусты после регистрации. Конечно.
Для каждого зарегистрированного класса виджетов создается отдельная опция, содержащая все необходимые опции. Опция начинается с строки widget_
. Чтобы получить опции для всех активных виджетов RSS, мы должны изучить…
get_option( 'widget_rss' );
Возможный вывод:
array (
2 =>
array (
'title' => 'WordPress Stack Exchange',
'url' => 'http://wordpress.stackexchange.com/feeds',
'link' => 'http://wordpress.stackexchange.com/questions',
'items' => 5,
'show_summary' => 1,
'show_author' => 0,
'show_date' => 0,
),
)
Обратите внимание на номер 2 . Все аргументы для нескольких экземпляров хранятся в одной опции, отсортированной по номерам.
Чтобы увидеть, какие классы виджетов уже известны WordPress, перейдите wp-admin/options.php
и прокрутите вниз, пока не увидите что-то вроде этого:
Да, сериализованные данные. Нет, вы не можете прочитать их здесь. Не волнуйся, тебе не нужно.
Демо-виджет
Чтобы лучше проиллюстрировать внутреннюю работу, я написал очень простой демонстрационный виджет:
/**
* Super simple widget.
*/
class T5_Demo_Widget extends WP_Widget
{
public function __construct()
{ // id_base , visible name
parent::__construct( 't5_demo_widget', 'T5 Demo Widget' );
}
public function widget( $args, $instance )
{
echo $args['before_widget'], wpautop( $instance['text'] ), $args['after_widget'];
}
public function form( $instance )
{
$text = isset ( $instance['text'] )
? esc_textarea( $instance['text'] ) : '';
printf(
'<textarea class="widefat" rows="7" cols="20" id="%1$s" name="%2$s">%3$s</textarea>',
$this->get_field_id( 'text' ),
$this->get_field_name( 'text' ),
$text
);
}
}
Обратите внимание на конструктор: 't5_demo_widget'
это $id_base
идентификатор этого виджета. Как вы можете видеть на скриншоте, его аргументы сохраняются в опции widget_t5_demo_widget
. Все ваши пользовательские виджеты будут обрабатываться следующим образом. Вам не нужно угадывать имя. И поскольку вы написали свои виджеты (вероятно), вы знаете все аргументы из параметров вашего класса $instance
.
Основы темы
Сначала вы должны зарегистрировать некоторые боковые панели и пользовательский виджет. Правильное действие для этого легко запомнить 'widgets_init'
. Поместите все в контейнер - класс или функцию. Для простоты я буду использовать функцию с именем t5_default_widget_demo()
.
Весь следующий код входит в functions.php
. Класс уже T5_Demo_Widget
должен быть загружен. Я просто положил его в тот же файл ...
add_action( 'widgets_init', 't5_default_widget_demo' );
function t5_default_widget_demo()
{
// Register our own widget.
register_widget( 'T5_Demo_Widget' );
// Register two sidebars.
$sidebars = array ( 'a' => 'top-widget', 'b' => 'bottom-widget' );
foreach ( $sidebars as $sidebar )
{
register_sidebar(
array (
'name' => $sidebar,
'id' => $sidebar,
'before_widget' => '',
'after_widget' => ''
)
);
}
Пока все просто. Наша тема теперь готова к виджетам, демо-виджет известен. Теперь самое интересное.
$active_widgets = get_option( 'sidebars_widgets' );
if ( ! empty ( $active_widgets[ $sidebars['a'] ] )
or ! empty ( $active_widgets[ $sidebars['b'] ] )
)
{ // Okay, no fun anymore. There is already some content.
return;
}
Вы действительно не хотите уничтожать пользовательские настройки. Если на боковых панелях уже есть какой-то контент, ваш код не должен выполняться поверх него. Вот почему мы остановимся в этом случае.
Хорошо, предполагается, что боковые панели пусты ... нам нужен счетчик:
$counter = 1;
Виджеты пронумерованы . Эти числа являются вторыми идентификаторами для WordPress.
Давайте получим массив для его изменения:
$active_widgets = get_option( 'sidebars_widgets' );
Нам тоже нужен счетчик (об этом позже):
$counter = 1;
И вот как мы используем счетчик, имена боковой панели и аргументы виджета (ну, у нас есть только один аргумент:) text
.
// Add a 'demo' widget to the top sidebar …
$active_widgets[ $sidebars['a'] ][0] = 't5_demo_widget-' . $counter;
// … and write some text into it:
$demo_widget_content[ $counter ] = array ( 'text' => "This works!\n\nAmazing!" );
$counter++;
Обратите внимание, как создается идентификатор виджета: id_base
минус -
и счетчик. Содержание виджета хранится в другой переменной $demo_widget_content
. Здесь счетчик ключа и аргументы виджета хранятся в массиве.
Мы увеличиваем счетчик на единицу, когда закончим, чтобы избежать столкновений.
Это было просто. Теперь RSS виджет. Больше полей, больше веселья!
$active_widgets[ $sidebars['a'] ][] = 'rss-' . $counter;
// The latest 15 questions from WordPress Stack Exchange.
$rss_content[ $counter ] = array (
'title' => 'WordPress Stack Exchange',
'url' => 'http://wordpress.stackexchange.com/feeds',
'link' => 'http://wordpress.stackexchange.com/questions',
'items' => 15,
'show_summary' => 0,
'show_author' => 1,
'show_date' => 1,
);
update_option( 'widget_rss', $rss_content );
$counter++;
Вот что-то новое: update_option()
это будет хранить аргумент виджета RSS в отдельной опции. WordPress найдет их автоматически позже.
Мы не сохранили аргументы демо-виджета, потому что теперь добавляем второй экземпляр на нашу вторую боковую панель…
// Okay, now to our second sidebar. We make it short.
$active_widgets[ $sidebars['b'] ][] = 't5_demo_widget-' . $counter;
#$demo_widget_content = get_option( 'widget_t5_demo_widget', array() );
$demo_widget_content[ $counter ] = array ( 'text' => 'The second instance of our amazing demo widget.' );
update_option( 'widget_t5_demo_widget', $demo_widget_content );
... и сохранить все аргументы для t5_demo_widget
в один раз. Нет необходимости обновлять один и тот же параметр два раза.
Ну, хватит на сегодня виджетов, давайте тоже сохраним sidebars_widgets
:
update_option( 'sidebars_widgets', $active_widgets );
Теперь WordPress будет знать, что есть несколько зарегистрированных виджетов и где хранятся аргументы для каждого виджета. А var_export()
на sidebar_widgets будет выглядеть так:
array (
'wp_inactive_widgets' =>
array (
),
'top-widget' =>
array (
0 => 't5_demo_widget-1',
1 => 'rss-2',
),
'bottom-widget' =>
array (
0 => 't5_demo_widget-3',
),
'array_version' => 3,
)
Полный код еще раз:
add_action( 'widgets_init', 't5_default_widget_demo' );
function t5_default_widget_demo()
{
// Register our own widget.
register_widget( 'T5_Demo_Widget' );
// Register two sidebars.
$sidebars = array ( 'a' => 'top-widget', 'b' => 'bottom-widget' );
foreach ( $sidebars as $sidebar )
{
register_sidebar(
array (
'name' => $sidebar,
'id' => $sidebar,
'before_widget' => '',
'after_widget' => ''
)
);
}
// Okay, now the funny part.
// We don't want to undo user changes, so we look for changes first.
$active_widgets = get_option( 'sidebars_widgets' );
if ( ! empty ( $active_widgets[ $sidebars['a'] ] )
or ! empty ( $active_widgets[ $sidebars['b'] ] )
)
{ // Okay, no fun anymore. There is already some content.
return;
}
// The sidebars are empty, let's put something into them.
// How about a RSS widget and two instances of our demo widget?
// Note that widgets are numbered. We need a counter:
$counter = 1;
// Add a 'demo' widget to the top sidebar …
$active_widgets[ $sidebars['a'] ][0] = 't5_demo_widget-' . $counter;
// … and write some text into it:
$demo_widget_content[ $counter ] = array ( 'text' => "This works!\n\nAmazing!" );
#update_option( 'widget_t5_demo_widget', $demo_widget_content );
$counter++;
// That was easy. Now a RSS widget. More fields, more fun!
$active_widgets[ $sidebars['a'] ][] = 'rss-' . $counter;
// The latest 15 questions from WordPress Stack Exchange.
$rss_content[ $counter ] = array (
'title' => 'WordPress Stack Exchange',
'url' => 'http://wordpress.stackexchange.com/feeds',
'link' => 'http://wordpress.stackexchange.com/questions',
'items' => 15,
'show_summary' => 0,
'show_author' => 1,
'show_date' => 1,
);
update_option( 'widget_rss', $rss_content );
$counter++;
// Okay, now to our second sidebar. We make it short.
$active_widgets[ $sidebars['b'] ][] = 't5_demo_widget-' . $counter;
#$demo_widget_content = get_option( 'widget_t5_demo_widget', array() );
$demo_widget_content[ $counter ] = array ( 'text' => 'The second instance of our amazing demo widget.' );
update_option( 'widget_t5_demo_widget', $demo_widget_content );
// Now save the $active_widgets array.
update_option( 'sidebars_widgets', $active_widgets );
}
Если вы зайдете wp-admin/widgets.php
сейчас, вы увидите три предустановленных виджета:
Вот и все. Используйте ...
dynamic_sidebar( 'top-widget' );
dynamic_sidebar( 'bottom-widget' );
... чтобы распечатать виджеты.
Есть небольшой глюк: вы должны загрузить интерфейс два раза для первоначальной регистрации. Если кто-то может помочь здесь, я буду очень благодарен.