Программно добавлять виджеты в боковые панели

Я хотел бы программно добавлять виджеты к моим двум боковым панелям, которые у меня есть. Я не мог найти официального способа сделать это?

Я начал искать в базе данных. Я обнаружил, что это опция «sidebars_widgets», которая помещает виджеты на боковые панели. При просмотре опций имена виджетов имеют число, добавленное в конец, например: widget_name-6. Откуда это число?

Любая идея о том, как это исправить?

59 голосов | спросил Marlun 22 PM00000030000003531 2011, 15:45:35

4 ответа


84

Когда я начал этот ответ, это должно быть всего лишь небольшая заметка. Ну, я потерпел неудачу. Сожалею! Оставайтесь со мной, есть скрытая глубина -

Как хранятся виджеты WordPress

Список виджета хранится в опции с именем 'sidebars_widgets'. A var_export () может содержать примерно следующее:

массив (
  'wp_inactive_widgets' =>
  массив (
  ),
  'top-widget' =>
  массив (
  ),
  'bottom-widget' =>
  массив (
  ),
  'array_version' => 3,
)

Игнорировать 'wp_inactive_widgets' и 'array_version'. Мы не должны заботиться о них. Другие ключи являются идентификаторами зарегистрированных боковых панелей. В этом случае боковые панели могут быть зарегистрированы с помощью этого кода:

//Зарегистрируйте две боковые панели.
$ sidebars = array ('a' => 'top-widget', 'b' => 'bottom-widget');
foreach ($ sidebars как $ sidebar)
{
    register_sidebar (
        массив (
            'name' => $ Боковой панели,
            'id' => $ Боковой панели,
            'before_widget' => '',
            'after_widget' => «»
        )
    );
}

По умолчанию боковые панели пусты после регистрации. Конечно.

Для каждого зарегистрированного класса виджетов создается отдельный параметр, содержащий все необходимые параметры. Опция имеет префикс строки widget _. Чтобы получить параметры для всех активных виджетов RSS, мы должны посмотреть в «|

get_option ('widget_rss');

Возможный выход:

массив (
  2 =>
  массив (
    '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 и прокрутите вниз, пока не увидите что-то вроде этого:

скриншот сериализованных параметров виджетов

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

Демо-виджет

Чтобы лучше иллюстрировать внутреннюю работу, я написал очень простой демонстрационный виджет:

/**
 * Супер простой виджет.
 * /
Класс T5_Demo_Widget расширяет WP_Widget
{
    публичная функция __construct ()
    {//id_base, видимое имя
        parent :: __ construct ('t5_demo_widget', 'T5 Demo Widget');
    }

    виджет публичных функций ($ args, $ instance)
    {
        echo $ args ['before_widget'], wpautop ($ instance ['text']), $ args ['after_widget'];
    }

    форма публичных функций ($ instance)
    {
        $ text = isset ($ instance ['text'])
            ? esc_textarea ($ instance ['text']): '';
        Е (
            '<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'),
            $ текст
        );
    }
}

Обратите внимание на конструктор: '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');

функция t5_default_widget_demo ()
{
    //Зарегистрируйте собственный виджет.
    register_widget ('T5_Demo_Widget');

    //Зарегистрируем две боковые панели.
    $ sidebars = array ('a' => 'top-widget', 'b' => 'bottom-widget');
    foreach ($ sidebars как $ sidebar)
    {
        register_sidebar (
            массив (
                'name' => $ Боковой панели,
                'id' => $ Боковой панели,
                'before_widget' => '',
                'after_widget' => «»
            )
        );
    }

До сих пор так просто. Наша тема в настоящее время виджет готов, известен виджет. Теперь весело.

$ active_widgets = get_option ('sidebars_widgets');

if (! empty ($ active_widgets [$ sidebars ['a']])
    или ! empty ($ active_widgets [$ sidebars ['b']])
)
{//Ладно, больше не забава. Уже есть некоторый контент.
    вернуть;
}

Вы действительно не хотите уничтожать пользовательские настройки. Если в боковых панелях уже есть некоторый контент, ваш код не должен работать над ним. Вот почему мы останавливаемся в этом случае.

Хорошо, предположим, что боковые панели пусты - нам нужен счетчик:

$ counter = 1;

Виджеты пронумерованы . Эти номера являются вторыми идентификаторами для WordPress.

Давайте получим массив, чтобы изменить его:

$ active_widgets = get_option ('sidebars_widgets');

Нам нужен счетчик (подробнее об этом позже):

$ counter = 1;

И вот как мы используем счетчик, имена боковых панелей и аргументы виджета (ну, у нас есть только один аргумент: text).

//Добавить виджет «demo» на верхнюю боковую панель â € |
$ active_widgets [$ sidebars ['a']] [0] = 't5_demo_widget-'. $ Счетчика;
//â € | и напишите в него текст:
$ demo_widget_content [$ counter] = array ('text' => "Это работает! \ n \ nAmazing!");

$ Счетчика ++;

Обратите внимание, как создается идентификатор виджета: id_base, минус - и счетчик. содержимое виджета хранится в другой переменной $ demo_widget_content. Вот счетчик и аргументы виджета хранятся в массиве.

Мы увеличиваем счетчик на единицу, когда делаем это, чтобы избежать столкновений.

Это было легко. Теперь виджет RSS. Больше полей, больше удовольствия!

$ active_widgets [$ sidebars ['a']] [] = 'rss-'. $ Счетчика;
//Последние 15 вопросов из WordPress Stack Exchange.
$ rss_content [$ counter] = массив (
    '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);

$ Счетчика ++;

Вот что-то новое: update_option (), это будет хранить аргумент виджета RSS в отдельном варианте. WordPress найдет их автоматически позже. Мы не сохранили аргументы демо-виджета, потому что теперь добавим второй экземпляр на нашу вторую боковую панель â € |

//Хорошо, теперь к нашей второй боковой панели. Мы делаем это коротко.
$ active_widgets [$ sidebars ['b']] [] = 't5_demo_widget-'. $ Счетчика;
# $ demo_widget_content = get_option ('widget_t5_demo_widget', array ());
$ demo_widget_content [$ counter] = array ('text' => 'Второй экземпляр нашего удивительного демонстрационного виджета.');
update_option ('widget_t5_demo_widget', $ demo_widget_content);

â € | и сохраните все аргументы для t5_demo_widget в один спешка. Не нужно обновлять одну и ту же опцию два раза.

Ну, достаточно виджетов на сегодняшний день, давайте сохраним sidebars_widgets тоже:

update_option ('sidebars_widgets', $ active_widgets);

Теперь WordPress будет знать, что есть некоторые зарегистрированные виджеты и где хранятся аргументы для каждого виджета. A var_export () в sidebar_widgets будет выглядеть так:

массив (
  'wp_inactive_widgets' =>
  массив (
  ),
  'top-widget' =>
  массив (
    0 => 'T5_demo_widget-1',
    1 => 'Новости-2',
  ),
  'bottom-widget' =>
  массив (
    0 => 'T5_demo_widget-3',
  ),
  'array_version' => 3,
)

завершить код :

add_action ('widgets_init', 't5_default_widget_demo');

функция t5_default_widget_demo ()
{
    //Зарегистрируйте собственный виджет.
    register_widget ('T5_Demo_Widget');

    //Зарегистрируем две боковые панели.
    $ sidebars = array ('a' => 'top-widget', 'b' => 'bottom-widget');
    foreach ($ sidebars как $ sidebar)
    {
        register_sidebar (
            массив (
                'name' => $ Боковой панели,
                'id' => $ Боковой панели,
                'before_widget' => '',
                'after_widget' => «»
            )
        );
    }

    //Хорошо, теперь смешная часть.

    //Мы не хотим отменять пользовательские изменения, поэтому сначала ищем изменения.
    $ active_widgets = get_option ('sidebars_widgets');

    if (! empty ($ active_widgets [$ sidebars ['a']])
        или ! empty ($ active_widgets [$ sidebars ['b']])
    )
    {//Ладно, больше не забава. Уже есть некоторый контент.
        вернуть;
    }

    //Боковые панели пусты,давайте вложим в них что-то.
    //Как насчет виджета RSS и двух экземпляров нашего демонстрационного виджета?

    //Обратите внимание, что виджеты нумеруются. Нам нужен счетчик:
    $ counter = 1;

    //Добавить виджет «demo» на верхнюю боковую панель â € |
    $ active_widgets [$ sidebars ['a']] [0] = 't5_demo_widget-'. $ Счетчика;
    //â € | и напишите в него текст:
    $ demo_widget_content [$ counter] = array ('text' => "Это работает! \ n \ nAmazing!");
    #update_option ('widget_t5_demo_widget', $ demo_widget_content);

    $ Счетчика ++;

    //Это было легко. Теперь виджет RSS. Больше полей, веселее!
    $ active_widgets [$ sidebars ['a']] [] = 'rss-'. $ Счетчика;
    //Последние 15 вопросов из WordPress Stack Exchange.
    $ rss_content [$ counter] = массив (
        '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);

    $ Счетчика ++;

    //Хорошо, теперь к нашей второй боковой панели. Мы делаем это коротко.
    $ active_widgets [$ sidebars ['b']] [] = 't5_demo_widget-'. $ Счетчика;
    # $ demo_widget_content = get_option ('widget_t5_demo_widget', array ());
    $ demo_widget_content [$ counter] = array ('text' => 'Второй экземпляр нашего удивительного демонстрационного виджета.');
    update_option ('widget_t5_demo_widget', $ demo_widget_content);

    //Теперь сохраним массив $ active_widgets.
    update_option ('sidebars_widgets', $ active_widgets);
}

Если вы перейдете к wp-admin /widgets.php, теперь вы увидите три предустановленных виджета:

снимок экрана активных виджетов

И все. Используйте â € |

dynamic_sidebar ('top-widget');
dynamic_sidebar («нижний виджет»);

â | |, чтобы распечатать виджеты.

Существует небольшой сбой: вы должны загрузить интерфейс перед отправкой дважды. Если кто-нибудь может помочь здесь, я буду очень благодарен.

ответил fuxia 4 Mayam12 2012, 06:23:58
3

Спасибо, что поделились своим решением. Я использовал то, что было описано в этом вопросе, чтобы создать фрагмент кода, который можно легко использовать для инициализации боковых панелей. Он очень гибкий, вы можете создать столько виджетов, сколько хотите, без необходимости изменять код вообще. Просто используйте крючки фильтра и передайте аргументы в массиве. Вот прокомментированный код:

function initialize_sidebars () {

  $ sidebars = array ();
  //Поставляем боковые панели, которые вы хотите инициализировать в фильтре
  $ sidebars = apply_filters ('alter_initialization_sidebars', $ sidebars);

  $ active_widgets = get_option ('sidebars_widgets');

  $ args = array (
    'sidebars' => $ врезки,
    'active_widgets' => $ active_widgets,
    'update_widget_content' => Массив (),
  );

  foreach ($ sidebars as $ current_sidebar_short_name => $ current_sidebar_id) {

    $ args ['current_sidebar_short_name'] = $ current_sidebar_short_name;
    //мы передаем наши аргументы в качестве ссылки, поэтому мы можем изменить их содержимое
    do_action ('your_plugin_sidebar_init', array (& $ args));

  }
  //нам нужно обновлять боковые панели, если боковые панели еще не инициализированы
  //и у нас также есть данные для инициализации боковых панелей с помощью
  if (! empty ($ args ['update_widget_content'])) {

    foreach ($ args ['update_widget_content'] как $ widget => $ widget_occurence) {

      //массив update_widget_content хранит все экземпляры виджета каждого виджета
      update_option ('widget_'. $ widget, $ args ['update_widget_content'] [$ widget]);

    }
    //после обновления всех виджетов мы обновляем массив active_widgets
    update_option ('sidebars_widgets', $ args ['active_widgets']);

  }

}

Это вспомогательная функция, которая проверяет, имеет ли на боковой панели в ней содержимое:

function check_sidebar_content ($ active_widgets, $ sidebars, $ sidebar_name) {

  $ sidebar_contents = $ active_widgets [$ sidebars [$ sidebar_name]];

  if (! empty ($ sidebar_contents)) {

    return $ sidebar_contents;

  }

  return false;

}

Теперь нам нужно создать функцию, привязанную к действию «sidebar_init».

add_action ('your_plugin_sidebar_init', 'add_widgets_to_sidebar');

function add_widgets_to_sidebar ($ args) {

  extract ($ args [0]);

  //Мы проверяем, имеет ли текущая боковая панель уже содержимое, и если она выйдет
  $ sidebar_element = check_sidebar_content ($ active_widgets, $ sidebars, $ current_sidebar_short_name);

  if ($ sidebar_element! == false) {

    вернуть;

  }

  do_action ('your_plugin_widget_init', массив (& $ args));

}

И теперь инициализация виджета:

add_action ('your_plugin_widget_init', 'your_plugin_initialize_widgets');

function your_plugin_initialize_widgets ($ args) {

  extract ($ args [0] [0]);

  $ widgets = array ();

  //Здесь виджеты, ранее определенные в функциях фильтра, инициализируются,
  //но только те, которые соответствуют текущей боковой панели
  $ widgets = apply_filters ('alter_initialization_widgets_'. $ current_sidebar_short_name, $ widgets);

  if (! empty ($ widgets)) {

    do_action ('create_widgets_for_sidebar', массив (& $ args), $ widgets);

  }

}

Последнее действие - создать виджеты в каждой боковой панели:

add_action ('create_widgets_for_sidebar', 'your_plugin_create_widgets', 10, 2);

function your_plugin_create_widgets ($ args, $ widgets) {

  extract ($ args [0] [0] [0]);

  foreach ($ widgets как $ widget => $ widget_content) {

    //Счетчик увеличивается на основе виджетов. Например, если у вас три виджета,
    //два из них являются виджетами архива, а один из них является настраиваемым виджетам, затем
    //исправленный счетчик, добавленный к каждому из них, будет иметь архив-1, архив-2 и пользовательский-1.
    //Таким образом, счетчик виджета не является глобальным счетчиком, а считается, что экземпляры (
    //widget_occurrence, как я его назвал) каждого виджета.
    $ counter = count_widget_occurence ($ widget, $ args [0] [0] [0] ['update_widget_content']);

    //Мы добавляем каждый экземпляр в активные виджеты ...
    $ args [0] [0] [0] ['active_widgets'] [$ sidebars [$ current_sidebar_short_name]] [] = $ widget. '-'. $ Счетчика;

    //..., а также сохранить содержимое в другом ассоциативном массиве.
    $ args [0] [0] [0] ['update_widget_content'] [$ widget] [$ counter] = $ widget_content;

  }

}

Эта функция используется для отслеживания того, сколько экземпляров определенного виджета уже определено:

function count_widget_occurence ($ widget, $ update_widget_content) {

  $ widget_occurrence = 0;

  //Мы смотрим на массив update_widget_content, который хранит каждый
  //экземпляр текущего виджета с текущим счетчиком в
  //ассоциативный массив. Ключ этого массива - это имя
  //текущий виджет.
      //Например, три виджета архивов выглядят так:
      //'update_widget_content' ['archives'] => [1] [2] [3]
  если (array_key_exists ($ widget, $ update_widget_content)) {

    $ widget_counters = array_keys ($ update_widget_content [$ widget]);

    $ widget_occurrence = end ($ widget_counters);

  }

  $ Widget_occurrence ++;

  return $ widget_occurrence;

}

Последнее, что нам нужно сделать, - это фактически присвоить значения. Используйте эти функции фильтра:

add_filter ('alter_initialization_sidebars', 'current_initialization_sidebars');
//Используйте этот фильтр, чтобы указать, какие боковые панели вы хотите инициализировать
функция current_initialization_sidebars ($ sidebars) {

  //Боковые панели назначаются таким образом.
  //Ключ массива очень важен, поскольку он используется как суффикс в функции инициализации
  //для каждой боковой панели. Значение - это то, что используется в атрибутах html.
  $ sidebars ['info'] = 'info-sidebar';

  return $ sidebars;

}

и

add_filter ('alter_initialization_widgets_info', 'current_info_widgets');
//Добавьте крючок фильтра для каждой боковой панели. Имя крючка происходит из
//ключи массива передаются в файле alter_initialization_sidebars.
//Каждый фильтр имеет имя 'alter_initialization_widgets_' и массив
//добавлен ключ к ней.

function current_info_widgets ($ widgets) {
  //Эта функция фильтра используется для добавления виджетов на панель сведений. Добавить каждый виджет
  //вы хотите назначить эту боковую панель массиву.

  return $ widgets = array (
    //Использовать имя виджета, как указано в вызове конструктора WP_Widget
    //как ключ массива.

    //Виджет архивов - это виджет, который по умолчанию поставляется с wordpress.
    //Аргументы, используемые этим виджетами, как и все другие виджеты по умолчанию, можно найти
    //в wp-includes /default-widgets.php.

    'archives' => массив (
      //Передать параметры массива в виде массива
      'title' => «Старое содержимое»,
      'dropdown' => 'на',
      //Значение «on» выбрано произвольно, виджет фактически проверяет только
      //непустое значение для обеих этих опций
      'count' => 'на',
    ),
 );

}

В идеале вы должны вызвать initialize_sidebars в функции настройки, которая вызывается при активации плагина или темы следующим образом: Активация темы:

add_action ('after_switch_theme', 'my_activation_function');
function my_activation_function () {
  initialize_sidebars ();
}

Активация плагина:

register_activation_hook (__FILE__, 'my_activation_function');
function my_activation_function () {
  initialize_sidebars ();
}

Подводя итог использованию этого конгломерата функций:

  1. создать функцию, которая инициализирует боковые панели, которые подключены к фильтру alter_initialization_sidebars.

  2. создайте функцию для каждой добавленной боковой панели, которая подключена к фильтру 'alter_initialization_widgets_ $ sidebarname'. Замените $ sidebarname именем каждой боковой панели, созданной на шаге 1.

Вы также можете просто скопировать этот незарегистрированный код в свой файл функций и сразу же начать создавать свои функции фильтра: Код на пасте (без функции фильтра инициализации)

ответил BdN3504 12 +04002014-10-12T16:25:38+04:00312014bEurope/MoscowSun, 12 Oct 2014 16:25:38 +0400 2014, 16:25:38
1

Прежде всего, спасибо @toscho за подробный ответ.

Это простой пример для тех, кто ищет простые решения и варианты виджета по умолчанию:

$ active_sidebars = get_option ('sidebars_widgets'); //получить все боковые панели и виджеты
$ widget_options = get_option ('widget_name-1');
$ widget_options [1] = array ('option1' => 'value', 'option2' => 'value2');

if (isset ($ active_sidebars ['sidebar-id']) & & empty ($ active_sidebars ['sidebar-id'])) {//проверить, существует ли боковая панель, и она пуста

    $ active_sidebars ['sidebar-id'] = array ('widget_name-1'); //добавление виджета в боковую панель
    update_option ('widget_name-1', $ widget_options); //обновлять параметры по умолчанию для виджета
    update_option ('sidebars_widgets', $ active_sidebars); //обновлять боковые панели
}

Примечание 1: вы можете получить sidebar-id в меню виджетов и осмотреть нужную боковую панель. Первый дочерний элемент <div id = "widgets-holder-wrap"> <div> имеет боковую панель id .

Примечание 2: вы можете получить widget_name в меню виджетов и осмотреть необходимый виджет. Вы увидите что-то вроде <div id = "widget-6_widget_name -__ i__" class = "widget ui-draggable">.

Я хочу, чтобы это помогло.

ответил Manolo 19 PM000000120000001931 2014, 12:59:19
1

Вот как вы это делаете:

(ПРЕДУПРЕЖДЕНИЕ, это может УДАЛИТЬ все предыдущие виджеты, если вы не вернули исходные виджеты в массив )

. <
$ widgets = array (
    'middle-sidebar' => массив (
        'WIDGET_NAME'
    ),
    «right-sidebar» => массив (
        'Widget2_name-1'
    )
);
update_option ('sidebars_widgets', $ widgets);

Номер -number можно использовать, если позже вы захотите добавить параметры в виджет с чем-то вроде этого:

update_option ('widget_widget_name', array (
    1 => массив (
        'title' => «Плитка»,
        'number' => 4
    ),
    '_multiwidget' => 1
));
ответил Manolo 19 PM000000120000001931 2014, 12:59:19

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132