WordPress: создаем виджет для показа картинок с Flickr

Владимир | | HTML, PHP, Web разработка, WordPress.

wordpress flickr widget

Сегодня я расскажу о создании виджета для одной из самых популярных на сегодняшний день CMS – WordPress.

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

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

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

Единственное условие – тема должна быть «widget ready», т.е. поддерживать виджеты. Но добавить эту поддержку несложно. Подробная инструкция находится здесь. Чтобы не усложнять пример, я буду считать, что используется дефолтная тема.

Сформулируем задачу.

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

Сразу приведу ссылку на архив с плагином

Source

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

Условно создание виджета можно разбить на 3 этапа.

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

2) Создание панели управления.

3) Создание самого виджета.

Рассмотрим их подробнее.

Наш виджет достаточно простой, поэтому он будет состоять всего из одного файла flickr-widget.php, который мы разместим в папке wp-content/plugins/flickr_widget. Учтите, что имя файла виджета должно совпадать с названием папки, иначе WordPress не сможет его найти.

В начале файла размещаем комментарий.

/*
Plugin Name: Flickr Widget
Plugin URI: http://localhost
Description: Этот виджет ищет по заданным тегам фотографии на сервисе flickr и показывает их.
Version: 1.0
Author: Statsenko Vladimir
Author URI: http://www.simplecoding.org
*/

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

На данном этапе мы получили обычный плагин WP, который можно активировать и деактивировать, правда, он ничего не умеет делать.

Но, прежде чем переходить к написанию функционала, разберемся с сервисом Flickr. Я его выбрал главным образом потому, что он предоставляет удобный API, из которого нам потребуется всего одна функция flickr.photos.search.

Как несложно догадаться из названия, она используется для поиска фотографий. Правда перед использованием Flickr API нужно зарегистрировать свое приложение на этом сервисе и получить для него уникальный ключ (Application Key), но эта операция бесплатная и сложности не представляет.

Запрос на Flickr можно отправить несколькими способами, кстати, существуют готовые библиотеки для различных языков. Но этот пример очень простой, поэтому мы просто отправим XML-RPC запрос (библиотека для работы с XML-RPC есть в дистрибутиве WP).

По описанию функции на официальном сайте я составил минимальный перечень параметров, которые мы должны передать в XML-RPC запросе.

1) api_key – ключ нашего приложения;
2) tags – список тегов через запятую;
3) per_page – количество фотографий.

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

Возвращаемся к нашему виджету.

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

Следующий шаг — инициализация виджета.

Выполняется с помощью одной строчки кода.

add_action("widgets_init", array('Flickr_Widget', 'register'));

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

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

Сам метод инициализации выглядит следующим образом

class Flickr_Widget {
…
    public function register() {
        register_sidebar_widget('Flickr Widget', array('Flickr_Widget', 'widget'));
        register_widget_control('Flickr Widget', array('Flickr_Widget', 'control'));
    }
…
}

Как видите, в этом методе мы регистрируем виджет и его панель управления. Проще говоря, рассказываем WordPress какие методы формируют виджет и панель управления.

Кроме того, нам нужно назначить два хука (для активации и деактивации виджета).

register_activation_hook( __FILE__, array('Flickr_Widget', 'activate'));
register_deactivation_hook( __FILE__, array('Flickr_Widget', 'deactivate'));

Здесь, также как и при инициализации, мы просто указываем имена соответствующих методов.

Рассмотрим, как они работают.

  1. class Flickr_Widget {
  2.     private static $APP_NAME = 'Flickr_Widget';
  3.     private static $APP_KEY = '17e73e544f0f6fff4d06822668e76e01';
  4.     function activate() {
  5.         //устанавливаем начальные значения
  6.         $data['fw_app_name'] = Flickr_Widget::$APP_NAME;
  7.         $data['fw_app_key'] = Flickr_Widget::$APP_KEY;
  8.         $data['wf_images'] = '2'; //две картинки
  9.         $data['fw_size'] = '2'; //размер не более 100px по большей стороне
  10.         $data['wf_tags'] = 'nature, природа';
  11.         //и создаем опцию
  12.         add_option('fw_data', $data);
  13.     }
  14.     
  15.     function deactivate() {
  16.         //удаляем опцию
  17.         delete_option('fw_data');
  18.     }
  19. }

* This source code was highlighted with Source Code Highlighter.

При активации виджета мы формируем массив с настройками по-умолчанию и сохраняем его в опции fw_data (с помощью метода add_option).

Обратите внимание на использовании атрибутов класса ($APP_NAME и $APP_KEY). При вызове методов WordPress не создает экземпляр класса, поэтому для обращения к свойствам нужно указывать имя класса.

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

Теперь напишем метод создания панели управления виджетом.

  1. class Flickr_Widget {
  2.     private static $IMG_SIZES = array(
  3.                             '1'=>array('s','75 x 75 px')
  4.                             , '2'=>array('t','max 100 px')
  5.                             , '3'=>array('m','max 240 px')
  6.                             , '4'=>array('','max 500 px')
  7.                         );
  8.     function control() {
  9.         
  10.         //если пришли данные в массиве $_POST, обновляем опцию
  11.         if (isset($_POST['wf_images'])){
  12.             $data['fw_app_name'] = Flickr_Widget::$APP_NAME;
  13.             $data['fw_app_key'] = Flickr_Widget::$APP_KEY;
  14.             $data['wf_images'] = esc_attr($_POST['wf_images']);
  15.             $data['fw_size'] = esc_attr($_POST['fw_size']);
  16.             $data['wf_tags'] = esc_attr($_POST['wf_tags']);
  17.             update_option('fw_data', $data);
  18.         }
  19.         
  20.         //читаем данные, сохраненные в опции
  21.         $data = get_option('fw_data');
  22.         if ( FALSE === $data ) {
  23.             //заполняем массив $data значениями по-умолчанию
  24.             $data = array();
  25.             $data['wf_images'] = '';
  26.             $data['fw_size'] = '';
  27.             $data['wf_tags'] = '';
  28.         }
  29.         //создаем поля формы, которая будет показана в панели управления
  30. ?>
  31.         <p><label>Количество картинок <input name="wf_images"
  32.         type="text" value="<?php echo $data['wf_images']; ?>" /></label></p>
  33.         <p><label>Размер картинок <select size="1" name="fw_size">
  34. <?php
  35.         foreach ( Flickr_Widget::$IMG_SIZES as $i => $size ) {
  36.             $selected = '';
  37.             if ( $i == $data['fw_size'] ) {
  38.                 $selected = 'selected="selected"';
  39.             }
  40. ?>
  41.             <option value="<?php echo $i; ?>" <?php echo $selected; ?>><?php echo $size['1']; ?></option>
  42. <?php
  43.         }
  44. ?>
  45.         </select></label></p>
  46.         <p><label>Теги (через запятую) <input name="wf_tags"
  47.         type="text" value="<?php echo $data['wf_tags']; ?>" /></label></p>
  48. <?php
  49.     }
  50. }

* This source code was highlighted with Source Code Highlighter.

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

После этого мы создаем форму и заполняем её значениями из опции. Точнее часть формы создает движок. Нам нужно только добавить поля ввода.

Их у нас три.
1) Поле «Количество картинок».
2) Выпадающий список с размерами картинок.
3) Поле для ввода тегов.

Примечание. При загрузке пользователем фотографий, Flickr создает несколько превьюшек разных размеров. Именно эти превьюшки мы и будем показывать в сайдбаре.

Переходим к методу, формирующему сам виджет.

  1. class Flickr_Widget {
  2.     public function widget($args) {
  3.         echo $args['before_widget'];
  4.         //показываем заголовок виджета
  5.         echo $args['before_title'] . 'Images from Flickr' . $args['after_title'];
  6.         //читаем массив с опциями
  7.         if ( $data = get_option('fw_data') ) {
  8.             //подключаем библиотеку для работы с XML-RPC
  9.             include_once ('wp-includes/class-IXR.php');
  10.             
  11.             $client = new IXR_Client(Flickr_Widget::$flickr_url);
  12.             $params = array('api_key'=>$data['fw_app_key']
  13.                             ,'tags'=>$data['wf_tags']
  14.                             ,'per_page'=>$data['wf_images']
  15.                             );
  16.             if ( !$client->query('flickr.photos.search', $params) ) {
  17.                 echo 'Error: '.$client->getErrorCode().':'.$client->getErrorMessage();
  18.             }
  19.             else {
  20.                 $photos = $client->getResponse();
  21.                 $xml = new SimpleXMLElement($photos);
  22.                 foreach ($xml->photo as $photo) {
  23.                     $url = 'http://farm'.$photo['farm']
  24.                             .'.static.flickr.com/'
  25.                             .$photo['server'].'/'
  26.                             .$photo['id'].'_'
  27.                             .$photo['secret'];
  28.                     $oUrl = 'http://www.flickr.com/photos/'
  29.                             .$photo['owner']
  30.                             .'/'.$photo['id'];
  31.                     if ('' !== $data['fw_size']) {
  32.                         $url .= '_'.Flickr_Widget::$IMG_SIZES[$data['fw_size']][0].'.jpg';
  33.                     }
  34.                     else {
  35.                         $url .= '.jpg';
  36.                     }
  37.                     echo '<div class="flickr_image"><a href="'.$oUrl.'" target="_blank"><img src="'.$url.'" alt="'.$photo['title'].'" /></a></div>';
  38.                 }
  39.             }
  40.         }
  41.         else {
  42.             echo 'No settings';
  43.         }
  44.         echo $args['after_widget'];
  45.     }
  46. }

* This source code was highlighted with Source Code Highlighter.

Принцип работы следующий.

1) Выводим заголовок виджета.

2) Читаем опцию (с помощью функции get_option). Если опция найдена:

2.1) Загружаем класс для работы с XML-RPC.

2.2) Формируем и отправляем запрос на Flickr.

2.3) Если ответ получен, формируем ссылки для тегов img. Ответ от Flickr приходит в XML формате, и для его анализа мы используем библиотеку SimpleXML. Расписывать, как формируются ссылки я не буду, на этой странице вы найдете достаточное количество примеров.

2.4) В цикле выводим теги img (я дополнительно вставил их в div’ы).

Вот и все 🙂 Мы получили работающий виджет.

Я не буду утверждать, что работать с виджетами в WordPress одно удовольствие 🙂 Но, с другой стороны, каких-то сверхсложных действий не требуется, и основная часть времени все равно уйдет на написание вашего кода.

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

В общем, надеюсь, эта статья вам поможет 😉 Если есть вопросы или замечания, пишите, постараюсь ответить!

Постовой

Даем бесплатные консультации по вопросам налогообложения. Заходите!

  • Вам не кажется странным, что мы с вами практически синхронно, написали практически об одном и том же? 😉
    Хочу заметить, что виджеты не всегда являются плагинами. Их можно встроить в тему (подключая файлы виджета в functions.php), если нужна привязка к теме.
    К тому же все виджеты являются потомками класса WP_Widget. Посмотрите этот класс, с ним намного легче писать виджеты, поскольку он сам регистрирует и настраивает виджет. Нужно переопределить как минимум один метод.

    • Действительно, в один и тот же день и на одну тему 🙂 Наверное, тема хорошая 😉

      Честно говоря, я как-то пропустил обновление API виджетов в WP, а для статьи использовал предыдущие наработки.
      Согласен, новый API удобнее.
      В общем, с удовольствием прочитал вашу статью.

    • О, крутяк, уже две статьи о плагинах +подписываюсь на ваш блог тоже )

  • Вам не кажется странным, что мы с вами практически синхронно, написали практически об одном и том же? 😉
    Хочу заметить, что виджеты не всегда являются плагинами. Их можно встроить в тему (подключая файлы виджета в functions.php), если нужна привязка к теме.
    К тому же все виджеты являются потомками класса WP_Widget. Посмотрите этот класс, с ним намного легче писать виджеты, поскольку он сам регистрирует и настраивает виджет. Нужно переопределить как минимум один метод.

    • Действительно, в один и тот же день и на одну тему 🙂 Наверное, тема хорошая 😉

      Честно говоря, я как-то пропустил обновление API виджетов в WP, а для статьи использовал предыдущие наработки.
      Согласен, новый API удобнее.
      В общем, с удовольствием прочитал вашу статью.

    • О, крутяк, уже две статьи о плагинах +подписываюсь на ваш блог тоже )

  • Спасибо! Давно хотел поиграться с плагинами к словодавильне, а тут и статья подходящая )

  • Спасибо! Давно хотел поиграться с плагинами к словодавильне, а тут и статья подходящая )