Как сделать свой виджет в Вордпресс с помощью плагина ACF

4 марта 2020

Не самый тривиальный способ применения плагина Advanced Custom Fields (ACF) для создания сложных виджетов в Вордпресс.

Кворк 2

Плагин ACF — мой любимчик! ACF один из немногих плагинов, который просто перевернул мои взгляды на Вордпресс разработку. Без него не обходится уже ни один проект. Практически 100% задач, связанных с произвольными полями Вордпресс, решаются с помощью ACF. Я сейчас уже не вспомню, когда писал для полей какой-то код. Причем, для решения повседневных задач вполне хватает стандартной бесплатной версии ACF.

Сегодня я покажу, как с помощью ACF сделать свой кастомный виджет. Конечно, для решения задачи можно обойтись и без плагинов: дописать пару сотен кода, а потом копаться в нем при каждом внесении изменений. Так было раньше, но сейчас почти на всех моих сайтах есть ACF, и я не ищу сложных путей.

Итак, поехали.

Регистрация виджета

Открываем functions.php активной темы или функциональный плагин и регистрируем новый виджет.

Назову его для примера danilin_testwidget.

/* Регистрация виджета */
 
function wpb_load_widget() {
  register_widget( 'danilin_testwidget' );
}
add_action( 'widgets_init', 'wpb_load_widget' );

Теперь переходим непосредственно к виджету и создаем его с помощью стандартного класса WP_Widget.

Называться наш виджет будет «Тестовый виджет», в качестве описания напишем «Advanced Custom Fields Example». Виджет будет содержать одно единственное поле «Заголовок» и стандартные для активной темы элементы: before_widget, after_widget, before_title, after_title. Заголовком по умолчанию будет «Тестовый виджет».

<?php

class danilin_testwidget extends WP_Widget {

  function __construct() {
    parent::__construct('danilin_testwidget', 'Тестовый виджет', array( 'description' => 'Advanced Custom Fields Example', ));
  }

  public function widget( $args, $instance ) {
    $title = apply_filters( 'widget_title', $instance['title'] ); 
    $widget_id = $args['widget_id'];

    echo $args['before_widget'];
    if ( ! empty( $title ) )
      echo $args['before_title'] . $title . $args['after_title'];

    /* Здесь будем выводить метаданные */ 

    echo $args['after_widget'];
  }

  public function form( $instance ) {
    if ( isset( $instance[ 'title' ] ) ) {
      $title = $instance[ 'title' ];
    } else {
      $title = 'Тестовый виджет';
    }
    ?>
    <p>
      <label for="<?php echo $this->get_field_id( 'title' ); ?>">Заголовок</label>
      <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
    </p>
    <?php 
  }
 
  public function update( $new_instance, $old_instance ) {
    $instance = array();
    $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
    return $instance;
  }
 
}
 
?>

Открываем админку, идем в раздел «Внешний вид» ⟶ «Виджеты» и добавляем в нужную область наш новый виджет.

Выглядит это так

«Тестовый виджет»

Я использую тему «Twenty Twenty», мой виджет выводится в подвале и выглядит так

«Тестовый виджет» в подвале

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

Регистрация произвольных полей виджета

Устанавливаем плагин ACF, если он еще вдруг не установлен, и переходим в «Группы полей» ⟶ «Добавить»

В качестве примера возьмет три поля: текст, изображение и цвет, которым зальем фон виджета.

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

Условия отображения

Дальше как обычно добавляем поля:

  1. Текстовое поле — danilin_testwidget_text
  2. Изображение — danilin_testwidget_image
  3. Цвет — danilin_testwidget_color

В итоге должна получиться вот такая группа полей:

Группа полей тестового виджета

Настройка вывода произвольных полей виджета

Теперь снова идем в раздел «Виджеты» и видим, что наш «Тестовый виджет» заметно преобразился — подцепились произвольные поля, которые мы создали на предыдущем шаге.

Тестовый виджет с произвольными полями

Теперь нам нужно заполнить эти поля и вывести их на фронте.

Заполняем текстовое поле, загружаем изображение и задаем цвет:

Выводить можно в коде выше, после пометки «Здесь будем выводить метаданные»

Текстовое поле можно вывести так:

if ( get_field('danilin_testwidget_text', 'widget_' . $widget_id) ) {
  echo get_field('danilin_testwidget_text', 'widget_' . $widget_id);
}

Изображение так:

if ( get_field('danilin_testwidget_image', 'widget_' . $widget_id) ) {
  echo wp_get_attachment_image( get_field('danilin_testwidget_image', 'widget_' . $widget_id), 'large' );
}

Цвет можно получить, как текст, сохранить в переменную $color и задействовать ее в качестве фона блока.

if ( get_field('danilin_testwidget_color', 'widget_' . $widget_id) ) {
  $color = get_field('danilin_testwidget_color', 'widget_' . $widget_id);
}

Окончательный код

В итоге должен получиться примерно такой код:

<?php

/* Регистрация виджета */
 
function wpb_load_widget() {
  register_widget( 'danilin_testwidget' );
}
add_action( 'widgets_init', 'wpb_load_widget' );

class danilin_testwidget extends WP_Widget {

  function __construct() {
    parent::__construct('danilin_testwidget', 'Тестовый виджет', array( 'description' => 'Advanced Custom Fields Example', ));
  }

  public function widget( $args, $instance ) {
    $title = apply_filters( 'widget_title', $instance['title'] ); 
    $widget_id = $args['widget_id'];

    echo $args['before_widget'];

    /* Цвет */

    if ( get_field('danilin_testwidget_color', 'widget_' . $widget_id) ) {
      $color = get_field('danilin_testwidget_color', 'widget_' . $widget_id);
    } else {
      $color = 'transparent';
    }
    echo '<div style="background-color:' . $color . '">';

    if ( ! empty( $title ) )
      echo $args['before_title'] . $title . $args['after_title'];

    /* Текст */

    if ( get_field('danilin_testwidget_text', 'widget_' . $widget_id) ) {
      echo get_field('danilin_testwidget_text', 'widget_' . $widget_id);
    }

    /* Изображение */

    if ( get_field('danilin_testwidget_image', 'widget_' . $widget_id) ) {
      echo wp_get_attachment_image( get_field('danilin_testwidget_image', 'widget_' . $widget_id), 'large' );
    }
    
    echo '</div>';
    echo $args['after_widget'];
  }

  public function form( $instance ) {
    if ( isset( $instance[ 'title' ] ) ) {
      $title = $instance[ 'title' ];
    } else {
      $title = 'Тестовый виджет';
    }
    ?>
    <p>
      <label for="<?php echo $this->get_field_id( 'title' ); ?>">Заголовок</label>
      <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
    </p>
    <?php 
  }
 
  public function update( $new_instance, $old_instance ) {
    $instance = array();
    $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
    return $instance;
  }
 
}

На фронте должна получиться вот такая красота:

Виджет

Отступы, размеры можно скорректировать с помощью CSS.

В заключение

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

Подпишитесь на мой телеграм и первыми получайте новые материалы, в том числе которых нет на сайте.

INNERSTAT
Иван Данилин

Практикующий веб-разработчик, специализируюсь на платформе Вордпресс.

Добавить комментарий