Анатомия виджетов WordPress: основы

  • 11.05.15
  • 16:17
  • 669
  • 0

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

Размещаются виджеты в отведённых для этого областях страницы — сайдбарах, называемых также боковыми панелями. Сайдбары принадлежат теме. Размещение на них виджетов происходит на экране «Внешний вид > Виджеты» (/wp-admin/widgets.php).

Конструкция

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

Чтобы не возникало проблем с терминологией, заметим, что класс/подкласс/субкласс виджетов правильнее было бы называть «классом типа виджетов», т. к. WordPress создаёт лишь один его экземпляр и использует его методы для обработки всех виджетов данного типа. Но такое длинное название неудобно. Поэтому здесь используется термин «класс виджетов», обозначающий как PHP-класс, так и реализуемый им тип — конкретное значение понятно из контекста.

Каждый класс виджетов содержит конструктор и три метода:

  • widget — производит вывод виджета;
  • form — выдаёт форму настройки;
  • update — осуществляет контроль корректности применяемых настроек.

Метод widget обязателен.

Также в составе класса может присутствовать массив значений по умолчанию параметров плагина — $defaults — если параметров много и их исходные значения различны.

Конструктор

Конструктор __construct (рассматриваем PHP 5+) должен вызывать конструктор родителя:

Аргументы ему передаются следующие:

  • арг. 1 — 'id-base' — основа идентификаторов виджетов данного типа, по-сути является идентификатором самого типа. Должен быть уникальным. Перед использованием преобразуется в малый регистр. Если пуст, в качестве значения принимается имя класса в малом регистре и без фрагмента /^(wp_)?widget_/, если таковой имеется. Хранится в поле $id_base. Не изменяется.

    Идентификаторы виджетов формируются добавлением к $id_base их номеров:

    Номером виджета является целое число не меньше 2. Идентификаторы виджетов также являются идентификаторами содержащих их блоков при размещении в сайдбарах.

  • арг. 2 — читаемое название виджета — будет использоваться, напр., на экране управления виджетами.
  • Форма настройки с заданной шириной.

    Форма настройки с заданной шириной.

    арг. 3 (опционален) — массив параметров, связанных с отображением и описанием виджета. На данный момент поддерживаются только два ключа:

    • 'description' — описание виджета;
    • 'classname' — класс, добавляемый к блоку виджета; по умолчанию используется "widget_{$id_base}".
  • арг. 4 (опционален) — массив параметров управления. Может содержать параметр 'width' — ширина формы настройки в единицах CSS, использовать который не рекомендуется. Вариант с array('width' => '500px') представлен на рисунке.

Конструктор каждого типа виджетов вызывается только один раз — используется лишь один экземпляр класса — поэтому в него можно поместить регистрацию хуков, обработчики которых удобнее реализовать в виде методов класса. Обработчик задаётся в виде array($this, 'method'):

В качестве примера можно привести такие штатные виджеты, как «Свежие записи» (класс WP_Widget_Recent_Posts) и «Свежие комментарии» (класс WP_Widget_Recent_Comments): они кешируют свой контент и пользуются некоторыми хуками для сброса кеша, что необходимо при любых изменениях, способных повлиять на отображаемую информацию. Код виджетов расположен в /wp-includes/default-widgets.php.

Настройка виджета: методы form и update

Каждый экземпляр виджета обладает собственным экземпляром настроек. Процесс их изменения следующий:

  1. метод form отображает форму с текущими настройками;
  2. администратор редактирует поля формы;
  3. WordPress получает отредактированные данные и передаёт их методу update;
  4. данные, возвращаемые методом update, сохраняются в БД.

Методу form массив настроек передаётся в качестве аргумента. Сразу после создания виджета настройки пусты и их следует инициализировать некоторыми значениями по умолчанию. Обычно это происходит так:

Функция wp_parse_args возвращает массив, содержащий все пары «ключ-значение» из первого аргумента и те пары из второго, ключи которых в первом отсутствуют.

Такая инициализация позволяет не корректировать настройки уже существующих виджетов при добавлении новых параметров: их исходные значения будут добавлены к «устаревшему» набору $instance.

Метод form опционален, и виджеты без настроек могут его не реализовывать. Но обычно все они имеют настраиваемый заголовок, поэтому им требуется как метод form, так и метод контроля новых значений update, чистящий заголовок от потенциально опасного кода.

Метод update получает два аргумента — массив новых настроек и массив старых, и должен вернуть массив «корректных» — проверенных и поправленных. Этот результат будет сохранён в БД. Метод опционален, его реализация в WP_Widget просто возвращает первый аргумент — новые настройки — без к.-л. контроля.

Чтобы WordPress мог соотносить введённые данные с параметрами настроек, имена полей ввода должны формироваться методом get_field_name('имя_параметра'):

Метод унаследован от WP_Widget. При получении ответа формы WordPress выбирает из него значения и создаёт набор отредактированных настроек. Этот набор передаётся в update первым аргументом.

Настроечные формы виджетов одного типа одинаковы. Чтобы идентификаторы полей ввода в них всегда оставались уникальными, их формируют методом get_field_id('имя_параметра'), также унаследованным от WP_Widget:

Если параметр $instance['field'] — хеш или числовой массив, а редактируемое значение — его элемент, то аргумент этих функций имеет вид 'field[key]'.

Вот методы update и form штатного виджета WP_Widget_Calendar:

Замечание: при каждой работе с параметром из него удаляются HTML- и PHP-теги (строки 6, 15), а перед выводом на форму значение экранируется как атрибут тега (строка 24).

Вывод виджета: метод widget

Вывод виджета на страницу выполняется методом widget. В аргументах он получает два массива: с настройками виджета и с параметрами сайдбара, за которым этот виджет закреплён.

Сайдбары являются частью темы, и виджеты в каждом из них свёрстаны по-своему. Фрагменты кода этой вёрстки, необходимые для формирования виджетов, передаются в параметрах сайдбара. Всего таких фрагментов — две пары:

  • фрагменты, обрамляющие весь виджет: before_widget и after_widget;
  • фрагменты, обрамляющие непустой заголовок виджета: before_title и after_title.

Вывод метода widget должен иметь такую структуру:

Замечание: отступы добавлены только для наглядности — ни отступов, ни переносов быть не должно, т. к. в некоторых специфичных случаях они могут оказать влияние на вёрстку (когда, напр., промежуток между отступами является содержимым блока, стилизованного с использованием псевдокласса :empty).

Параметры сайдбара передаются в первом аргументе:

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

С выводом заголовка виджета связаны несколько соглашений:

  • перед выводом заголовок фильтруется хуком 'widget_title':
  • после фильтрации ни каких изменений в заголовок не вносится;
  • фрагменты before_title и after_title выводятся только с непустым заголовком:

Некоторые виджеты заменяют пустой заголовок некоторым стандартным (к таким относятся, напр., штатные виджеты «Облако меток», «Последние записи», «Последние комментарии» и др.) Подобную замену следует проводить перед фильтрацией, а вывод осуществлять по тому же условию, т. к. заголовок может быть очищен фильтром.

В ряде случаев вёрстка такова, что before_title и after_title должны выводиться и для виджетов с пустыми заголовками. В этом случае тема регистрирует фильтр 'widget_title', заменяющий пустую строку пробелом. Более подробно — в статье Темы WordPress и пустые заголовки виджетов.

Пример — метод widget класса WP_Widget_Calendar:

Замечания по примеру:

  1. виджет обладает единственным настраиваемым параметром — заголовком, поэтому настроек по умолчанию класс не имеет и коррекции $instance не проводит. Непосредственно корректируется сам параметр в строке 9.
  2. заголовок и связанные с ним фрагменты выводятся одним оператором и в рамках одного условия (строки 15-17), что удобно при внесении изменений.

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

Класс виджетов в WordPress регистрируется вызовом register_widget('Class_Name'), аргументом которого является имя этого класса. Вызов должен происходить по хуку 'widgets_init' с приоритетом не выше 99. Регистрация более поздняя будет проигнорирована.

Резюме

  • виджеты — самостоятельные фрагменты страницы, размещаемые в сайдбарах;
  • типы виджетов определяются в виде классов, производных от WP_Widget;
  • конструктор класса виджетов должен вызывать конструктор родителя, передавая ему id_base, название и массив с описанием и классом блока виджета;
  • три метода должны быть определены:
    • public function widget($args, $instance);
    • public function form($instance);
    • public function update($new_instance, $old_instance)
  • метод form должен формировать идентификаторы и имена полей ввода с помощью get_field_id('field') и get_field_name('field');
  • метод update должен возвращать корректную версию настроек;
  • в методах form и widget массив $instance следует дополнять массивом исходных значений;
  • в методе widget
    • заголовок пропускается через фильтр widget_title;
    • обрамление пустого заголовка не выводится;
    • информация выдаётся в таком порядке:
  • регистрируется класс виджетов вызовом register_widget('Class_Name') по хуку 'widgets_init' с приоритетом не выше 99.
Оставить комментарий

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