Добавление класса к before_widget внутри пользовательского виджета

1 июн. 2011 г., 15:00:10
Просмотры: 19.7K
Голосов: 10

У меня есть простой пользовательский виджет, который запрашивает свою ширину (которая позже используется во фронтенде). Поле ширины представляет собой выпадающий список, поэтому у пользователя есть предопределенные варианты.

У меня будет много экземпляров моего виджета, каждый со своей настройкой ширины.

Сейчас в коде моего виджета есть следующая строка:

echo $before_widget;

которая выводит:

<div class="widget my" id="my-widget-1"></div>

Я хочу каким-то образом подключиться к $before_widget и добавить свой собственный класс (указанную ширину из выпадающего списка). То есть, я хочу получить следующую разметку:

<div class="widget my col480" id="my-widget-3"></div>

И если класс не указан, то я хочу добавить class="col480".

Как мне этого достичь?

Спасибо за помощь! Даша

0
Все ответы на вопрос 5
1
15

Ага, значит переменная $before_widget - это строка, представляющая элемент div: <div class="widget my" id="my-widget-1">. Я проверил $before_widget на наличие подстроки "class" и добавил к ней значение $widget_width.

Код из моего файла пользовательского виджета:

function widget( $args, $instance ) {
  extract( $args );
  ... //другой код

  $widget_width = !empty($instance['widget_width']) ? $instance['widget_width'] : "col300";
  /* Добавляем ширину из $widget_width к классу из $before_widget */
  // нет атрибута 'class' - добавляем его со значением ширины
  if( strpos($before_widget, 'class') === false ) {
    // включаем закрывающий тег в строку замены
    $before_widget = str_replace('>', 'class="'. $widget_width . '">', $before_widget);
  }
  // есть атрибут 'class' - добавляем значение ширины к нему
  else {
    $before_widget = str_replace('class="', 'class="'. $widget_width . ' ', $before_widget);
  }
  /* Выводим before_widget */
  echo $before_widget;

  ... //другой код
}

Я хотел добавить свою переменную $widget_width к элементу div виджета в коде моего собственного виджета (в то время как у меня был легкий доступ к переменной $widget_width).

Надеюсь, это понятно и поможет кому-то.

Спасибо, Даша

2 июн. 2011 г. 18:30:00
Комментарии

отличная работа - помогли мне с проблемой виджета - спасибо :)

Q Studio Q Studio
21 окт. 2012 г. 22:52:14
5
11

Вы можете использовать хук фильтра dynamic_sidebar_params для поиска вашего виджета и добавления к нему ваших классов:

add_filter('dynamic_sidebar_params', 'add_classes_to__widget'); 
function add_classes_to__widget($params){
    if ($params[0]['widget_id'] == "my-widget-1"){ // убедитесь, что это ID вашего виджета
        // это ваш виджет, поэтому добавляем ваши классы
        $classe_to_add = 'col480 whatever bla bla '; // убедитесь, что оставляете пробел в конце
        $classe_to_add = 'class=" '.$classe_to_add;
        $params[0]['before_widget'] = str_replace('class="',$classe_to_add,$params[0]['before_widget']);
    }
    return $params;
} 
1 июн. 2011 г. 16:03:38
Комментарии

спасибо за ответ. У меня будет много экземпляров моего пользовательского виджета, каждый со своей собственной шириной. Поэтому я хотел добавить дополнительный класс прямо в коде виджета, а не через фильтр. Надеюсь, это объяснение понятно?

dashaluna dashaluna
1 июн. 2011 г. 16:37:15

параметры экземпляров сохраняются в таблице опций, так что вы можете получить их оттуда, зная ID виджета, используя get_option('widget-name')

Bainternet Bainternet
1 июн. 2011 г. 19:14:42

большое спасибо за помощь! Извините, но я не совсем понимаю ваше решение :( Я хотел, чтобы весь код находился в файле моего пользовательского виджета, где я могу легко получить доступ к переменной ширины. В итоге я модифицировал строку $before_widget. Ваш ответ помог мне понять, что $before_widget - это строка. Еще раз спасибо :)

dashaluna dashaluna
2 июн. 2011 г. 18:32:29

Это будет предпочтительным вариантом, так как он использует фильтры WordPress вместо редактирования файлов темы.

rhysclay rhysclay
15 мар. 2017 г. 06:51:53

Это отлично работает - спасибо. Хотя лично я предпочитаю использовать $params[0]['id'] вместо $params[0]['widget_id'], так как это тот id, с которым вы будете регистрировать сайдбар/виджет.

Brett Brett
26 мая 2020 г. 02:25:26
0

Ещё один способ добавить класс для пользовательского виджета — использовать ключ 'classname' в функции конструктора, как показано ниже:

class My_Widget_Class extends WP_Widget {
// Для версий PHP ниже 5 используйте имя дочернего класса для конструктора…
// function My_Widget_Class()
       function __construct() {
            $widget_ops = array(
                'classname' => 'my-class-name',
                'description' => __("Виджет во имя человечества",'themedomain'),
            );
            $control_ops = array(
                'id_base' => 'my-widget-class-widget'
            );
   //дальше может быть ещё код...

   // Вызов родительского конструктора. Можно заменить первый аргумент на $control_ops['id_base'] и удалить четвёртый.
            parent::__construct(@func_get_arg(0),@func_get_arg(1),$widget_ops,$control_ops);
        }
}

Убедитесь, что в вашей теме используется стандартный 'before_widget', или, если вы используете register_sidebar() в function.php, сделайте это так:

//Это всего лишь пример.
register_sidebar(array(
          'name'=> 'Боковая панель',
            'id' => 'sidebar-default',
            'class' => '',//Я так и не нашёл, где это используется...
            'description' => 'Боковая панель для человечества',
            'before_widget' => '<aside id="%1$s" class="widget %2$s">',//Это важная строка!!
            'after_widget' => '</aside>',
            'before_title' => '<h3>',
            'after_title' => '</h3>',
        ));

Тогда для каждого экземпляра вашего виджета будет добавлен класс 'widget my-class-name', например:

<aside class="widget my-class-name" id="my-widget-class-widget-N"><!-- где N — это число -->
  <h3>ЗАГОЛОВОК ВИДЖЕТА</h3>
  <p>СОДЕРЖИМОЕ ВИДЖЕТА</p>
</aside>

Вы также можете сначала вызвать родительский конструктор, а затем добавить нужный класс:

class My_Widget_Class extends WP_Widget {
    // Лучше явно определить список аргументов родителя…
    function __construct($id_base, $name, $widget_options = array(), $control_options = array())
    {    parent::__construct($id_base, $name, $widget_options, $control_options);
         // Изменяем имя класса после вызова
         $this->widget_options['classname'].= ' some-extra';
    }
}
12 февр. 2014 г. 15:52:09
0

Сначала добавьте пользовательский класс-заполнитель в конструктор

<?php
public function __construct() {
   $widget_ops  = array(
      'classname'                   =>; 'widget_text eaa __eaa__', //__eaa__ - это мой CSS-класс-заполнитель
      'description'                 =>; __( 'Реклама AdSense, произвольный текст, HTML или JS.','eaa' ),
      'customize_selective_refresh' =>; true,
   );
   $control_ops = array( 'width' =>; 400, 'height' =>; 350 );
   parent::__construct( 'eaa', __( 'Easy AdSense Ads &amp; Scripts', 'eaa' ), $widget_ops, $control_ops );
}
?>

Затем замените его на класс/классы по вашему выбору на основе настроек виджета следующим образом

<?php
if ( $instance['no_padding'] ) {
   $args['before_widget'] = str_replace( '__eaa__', 'eaa-clean', $args['before_widget'] );
}
?>

Подробности с примером можно найти по адресу http://satishgandham.com/2017/03/adding-dynamic-classes-custom-wordpress-widgets/

12 мар. 2017 г. 20:27:27
0

Вы можете попробовать этот фильтр:

/**
 * Эта функция проходит через все виджеты в сайдбаре 
 * и добавляет значение из админ-формы в виджет как имя класса  
 *  
 * @param array $params Массив виджетов в сайдбаре
 * @return array
*/

add_filter( 'dynamic_sidebar_params', 'nen_lib_add_class_to_widget' );
function nen_lib_add_class_to_widget( $params )
{
    foreach( $params as $key => $widget )
    {
        if( !isset($widget['widget_id']) ) continue;

        // моя пользовательская функция для получения данных виджета из админ-формы (объект)
        $widget_data = nen_get_widget_data($widget['widget_id']) ;

        // проверяем, существует ли поле и имеет ли значение
        if( isset($widget_data->wm_name) && $widget_data->wm_name )
        {
            // конвертируем и помещаем значение в массив
            $classes = array( sanitize_title( $widget_data->wm_name ) );

            // добавляем фильтр, чтобы можно было добавить больше классов
            $classes = apply_filters( 'nen_lib_add_class_to_widget' , $classes , $widget['widget_id'] , $widget , $widget_data  );

            // получаем элемент 'before_widget', устанавливаем поиск и замену
            $string     = $params[$key]['before_widget'];
            $find       = '"widget ';
            $replace    = '"widget '.implode( ' ' , $classes ).' ';

            // новое значение
            $new_before = str_replace( $find , $replace , $string ) ;

            // устанавливаем новое значение
            $params[$key]['before_widget'] = $new_before;
        }
    }
    return $params;
}
3 окт. 2018 г. 20:56:55