Коли я почав цю відповідь, це повинна бути лише невелика записка. Ну, я провалився. Вибачте! Залишайся зі мною, там є хороший прихований глибоко вниз…
Як зберігаються віджети 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()
на бічній панелі_віджетів виглядатиме так:
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' );
… Для друку віджетів.
Є невеликий глюк: для початкової реєстрації вам доведеться два рази перевантажувати передню частину. Якщо хтось може допомогти тут, я буду дуже вдячний.