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

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

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

Есть идеи, как это исправить?

Понравился вопрос? Нужен ответ? Поддержите проект
WPAsk
Ответов: 4
  1. fuxia

    Демо виджет

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

    /**
     * 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
            );
        }
    }
    

    Основы темы

    Сначала вы должны зарегистрировать некоторые боковые панели и пользовательский виджет. Правильное действие для этого легко запомнить: '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_widget( 'T5_Demo_Widget' );
    
        // Зарегистрируйте две боковые панели.
        $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'] ] )
    )
    {   
        return;
    }
    
    1. fuxia♦

      Виджеты не добавляются, когда боковые панели не пусты.

  2. BdN3504

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

    function initialize_sidebars(){
    
      $sidebars = array();
      // Укажите боковые панели, которые вы хотите инициализировать, в фильтре.
      $sidebars = apply_filters( 'alter_initialization_sidebars', $sidebars );
    
      $active_widgets = get_option('sidebars_widgets');
    
      $args = array(
        'sidebars' => $sidebars,
        'active_widgets' => $active_widgets,
        'update_widget_content' => array(),
      );
    
      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'] as $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  ) {
    
        return;
    
      }
    
      do_action( 'your_plugin_widget_init', array( &$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', array( &$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 as $widget => $widget_content ) {
    
         // Счетчик увеличивается на основе виджета. Например, если у вас было три виджета,
         // два из них - это виджет архива, а один - пользовательский виджет, затем
         // к каждому из них добавлен правильный счетчик: archive-1, archive-2 и custom-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 . '-' . $counter;
    
        // ... а также сохраняем содержимое в другом ассоциативном массиве.
        $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'] = & gt; [1][2][3]
      if ( 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' ) ;
    // Используйте этот фильтр, чтобы указать, какие боковые панели вы хотите инициализировать
    function current_initialization_sidebars( $sidebars ) {
    
       // Боковые панели назначаются таким образом.
       // Ключ массива очень важен, потому что он используется как суффикс в функции инициализации
       // для каждой боковой панели. Значение - это то, что используется в атрибутах html.
      $sidebars['info'] = 'info-sidebar';
    
      return $sidebars;
    
    }
    

    And:

    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' => array(
         // Передаем параметры массива как массив
          'title' => 'Old Content',
          'dropdown' => 'on',
         // Произвольно выбрано значение 'on', виджет фактически проверяет только
           // непустое значение в обеих этих опциях
          'count' => 'on',
        ),
     );
    
    }
    

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

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

    Plugin activation:

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

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

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

        $widgets = array(
        'middle-sidebar' => array(
            'widget_name'
        ),
        'right-sidebar' => array(
            'widget2_name-1'
        )
    );
    update_option('sidebars_widgets', $widgets);
    

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

        update_option('widget_widget_name', array(
        1 => array(
            'title' => 'The tile',
            'number' => 4
        ),
        '_multiwidget' => 1
    ));
    

Добавить ответ

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: