Реальный пример разработки плагина для WordPress

Реальный пример разработки плагина для WordPress

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

Реальный пример – Список филиалов компании

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

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

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

Настройка

Давайте все настроим, перейдите в папку плагина и создайте следующие папки/файловую структуру

Самый верхний файл wp_simple_location_plugin.php будет главным. Тут мы будем загружать наши стили из папки CSS, а также дополнительные PHP файлы из папки inc.

Основной класс местоположения

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

Непрямой доступ

Рекомендуется закрывать прямой доступ к PHP файлам с помощью проверки на существование константы ABSPATH (если не существует, скрипт прекращает работу). Поместите код ниже прямо после открывающего PHP тега:

Объявление плагина

Чтобы плагин работал, его сначала необходимо объявить. Объявление выглядит, как набор комментариев для WordPress, в которых содержится информация о плагине. В плагин необходимо добавить код ниже, иначе он просто не появится в менеджере плагинов в WP.

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

Класс wp_simple_location Class

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

Подключаем файлы шорткодов и виджета

Так как мы будем использовать и виджет и шорткод, то было решено разбить функционал на два отдельных файла.
Скопируйте код ниже в самый конец класса wp_simple_location:

Код выше подключает наши файлы. О них мы поговорим чуть позже.

Свойства класса

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

Функция _construct

Функция _construct – важная часть плагина. Это мастер-функция, с помощью которой можно обрабатывать и запускать другие функции.

Функция относится к так называемым magic (магическим) функциям. Магические функции представляют собой специальные функции, добавленные в PHP5, автоматически запускающиеся при определенных условиях. Данная функция срабатывает сразу же после создания экземпляра класса (класс создан и создан его экземпляр в виде переменной).

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

Функции register_activation_hook и register_deactivation_hook используются для встраивания в другие функции при активации и отключении плагина. Мы будем использовать эти функции для проверки правильности добавленного типа контента (наши места) и обработки ссылок (мы будем использовать человекопонятные ссылки).

Настройка рабочих часов для определенного филиала

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

Рабочие дни хранятся на стороне back-end’а в свойстве $wp_location_trading_hour_days. Для настройки рабочих дней и часов необходимо вызвать функцию set_location_trading_hour_days.

После заполнения значений массива необходимо вызвать фильтр wp_location_trading_hours_days. Т.е. тема или другой плагин смогут переписать рабочие дни магазина (они могут фильтровать массив и добавить поле каникул «holidays», чтобы потом задать для этого периода свое рабочее время).

Настройка рабочих часов заданного филиала

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

После добавления этого кода в меню должна появиться новая строка.

Добавляем мета бокс к новому типу местоположений

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

Третье значение add_meta_box – функция, которая будет показывать наш бокс. Тут мы вызываем функцию location_meta_box_display, ее мы создадим следующей.

Функция location_meta_box_display

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

Что делает функция:

Сперва создается безопасное nonce поле для мета бокса (nonce используется для проверки того, что экшен отправки формы пришел из нужного места).

Поле собираем наши телефоны, почту и адреса (если они есть).

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

Показываем поля телефона, почты и адреса (если есть какие-то данные, то заполняем их).

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

Перед закрытием формы добавляем хук wp_location_admin_form_end. Это позволит другим плагинам или темам встроиться в этом место и добавить дополнительные поля или данные.

Мета бокс должен показаться на странице места. Выглядеть это будет примерно так:

Регистрация типа контента и обработка правил перезаписи во время активации

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

Мы зарегистрировали тип контента через хук init, но нам все равно нужно вызвать функцию register_location_content_type (чтобы проверить, добавился ли наш тип).

Также мы изменим правила перезаписи, чтобы можно было использовать человекопонятные ссылки (у нас будут ссылки типа example.com/location/mylocation вместо example.com/?p=144)

Сброс правил перезаписи при отключении плагина

Функция plugin_deactivate срабатывает при отключении плагина. Так как мы удаляем плагин, а в плагине использовался пользовательский тип контента, то для верности необходимо сбросить правила перезаписи.

Показываем мета данные для конкретного места

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

Функция prepend_location_meta_to_content цепляется к фильтру the_content, т.е. мы можем добавить свои данные перед главным контентом страниц.

Что делает функция:

Функция добавлена к хуку the_content, т.е. она будет запускаться при каждом обновлении страницы. Мы используем глобальные переменные $post и $post_type для проверки, что мы находимся на странице конкретного места

Собираем базовую информацию: почта, телефон и адрес.

Перед отображением мета данных вызываем хук wp_location_meta_data_output_start. С его помощью другие плагины или темы смогут встроиться в этом место и добавлять дополнительные мета данные (если кто-то добавит новое поле к месту, этот хук можно будет использовать для отображения сохраненных данных).

Показываем почту, телефон и адрес.

Пробегаемся по переменной wp_location_trading_hour_days и проверяем ее на рабочие дни. Если они есть, пробегаемся по ним в цикле, сохраняем рабочие часы и показываем их.

Почти в самом конце вызываем экшен wp_location_meta_data_output_end. С его помощью можно будет добавить дополнительные данные перед закрытием мета бокса.

Выводим список мест

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

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

В массив заносятся стандартные аргументы. Количество мест будет установлено в -1 (все места), а ID будет без значения (т.е. мы хотим показать список мест, а не конкретное место).

Проверяем переданную переменную $arguments на пустоту, и является ли она массивом. Пробегаемся по всем аргументам $arguments и сверяем их ключи на совпадение с нашим массивом $default_args. Если что-то совпало, обновляем массив $default_args.

Массив $default_args используется для создания запроса для get_posts(), который и будет искать все места (если создано всего одно место, его мы и получим).

Теперь переходим к созданию HTML. Создаем переменную $html, куда будем заносить разметку.

Собираем все данные о месте (заголовок, контент, изображение и т.д.) и подготавливаем их к выводу.

Вызываем фильтр wp_location_before_main_content на переменную $html. Так сторонние плагины и темы смогут добавлять дополнительный контент перед заголовком места. Крайне полезно, если мы заранее создали дополнительные поля в панели администратора, которые потом можно выводить.

В вывод добавляются заголовок, изображение, контент, телефон и почта (с условиями на проверку их существования).

Перед выводом кнопки Подробнее мы вызываем наш второй фильтр wp_location_after_main_content. С его помощью сторонние плагины и темы смогут добавлять дополнительный контент прямо перед кнопкой.

Добавляем кнопку Подробнее и возвращаем нашу переменную $html.

Сохранение дополнительных мета данных

При сохранении нового места необходимо запускать функцию, которая будет собирать и обновлять наши дополнительные мета поля (почта, телефон, адрес и т.д). Для этого мы создадим функцию save_location.

Что мы делаем:

Сначала ищем поле nonce и проверяем его на существование (передается через мета бокс). Также проверяем автосохранение. После всех проверок едем дальше.

Собираем телефон, почту и адрес и очищаем данные с помощью функции sanitize_text_field(). Данные заносятся в переменные и позже используются в нашей функции update_post_meta() для сохранения данных о месте.

Так как наши рабочие часы динамические, то вытягивать и сохранять их мы вынуждены слегка по-другому. Мы не знаем, сколько будет значений, поэтому мы не можем вытягивать их из массива $_POST по имени. Нам придется пройтись по всему массиву и проверять ключи на совпадение с «wp_location_trading_hours_». Если совпадения есть, мы обновляем значения и сохраняем их в качестве мета данных.

Почти в конце вызываем экшен wp_location_admin_save. Экшен сохраняет ID текущего места в $post_id, чтобы сторонние функции могли вытягивать дополнительные данные из массива $_POST и сохранять их в месте.

Загружаем админ и публичные скрипты и стили

Нам необходимо загрузить дополнительные CSS файлы как для front-end, так и для back-end стороны нашего сайта. Для этого мы создадим две функции, которые будут загружать любые скрипты или файлы стилей.

Внутри CSS файлов будут стили полей мета бокса в панели администратора, а также немного стилей front-end’а. Плагин замечательно работает без CSS стилей. Если вам эта часть не интересна, ее можно пропустить. (Если вы пропускаете эту часть, не забудьте удалить вызов экшенов в конструкторе)

Шорткод

Теперь можно перейти к классу шорткода, который будет работать в паре с нашим основным классом. Шорткоды предоставляют администратору простой интерфейс отображения различных мест. Шорткоды будут настраиваемые, администратор сможет задавать конкретный филиал (место) по ID или же показывать все филиалы сразу. Шорткод на странице будет выглядеть примерно следующим образом:

Работать мы будем в файле wp_location_shortcode.php.

Запрет на прямой доступ

Как в случае с основным файлом PHP, тут мы тоже хотим закрыть прямой доступ. Скопируйте код ниже в верхушку файла:

Класс wp_location_shortcode

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

Функция __construct

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

Функция register_location_shortcodes

С помощью этой функции мы будем добавлять шорткод. Мы вызываем функцию add_shortcode для добавления нового шорткода wp_locations. Для вывода шорткода будем использовать функцию location_shortcode_output.

Вывод шорткода

Функция вывода вызывается из функции add_shortcode и нужна для формирования кода для вывода шорткода на экран.

Что делает функция:

Функция принимает аргументы шорткода в виде переменной $atts, контент шорткода $content и назавние шорткода $tag. Эти переменные используются для формирования кода на вывод.

Создаем глобальную переменную $wp_simple_locations, чтобы получить доступ к главному классу (и всем его функциям).

Создаем дефолтный массив аргументов шорткода с помощью функции shortcode_atts().

Формируем код на вывод с помощью функции get_locations_output из объекта $wp_simple_locations. В функцию передаем наши аргументы, чтобы контент в шорткоде мог быть динамическим. К примеру, можно передать ID одного места, тогда вернется всего одно местоположение.

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

Создаем объект wp_location_shortcode

В самом конце класса необходимо создать объект wp_location_shortcode. Таким образом будет активирован весь функционал класса.

Виджет

Закончим статью классом, работающим с виджетом. Мы добавим виджет, потому что почти все темы сейчас поддерживают виджеты. Виджеты дают администраторам простой и быстрый способ демонстрации чего-либо (в нашем случае это филиалы компании). Откроем файл wp_location_widget.php и начнем.

Запрет прямого доступа

И опять мы запрещаем прямой доступ к PHP файлу с помощью следующей строки:

Класс wp_location_widget

Создадим базовую структуру класса wp_location_widget. Класс похож на предыдущие; но в этот раз мы расширим уже существующий класс WP_widget.

Функция __construct

В функции _construct мы определим наши базовые стили виджета. А сделаем мы это, перегрузив родительский конструктор и передав в него наши значения. Нам необходимо задать ID, название и описание виджета. Также мы прицепим нашу функцию register_wp_location_widgets к хуку widgets_init, чтобы зарегистрировать наш виджет.

Создаем интерфейс виджета в панели администратора

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

Функция form() унаследована от родительского класса WP_widget, она будет автоматически вызываться, когда мы будем заходить на экран виджета в панели администратора.

Что тут происходит:

Сперва мы задаем ID и количество мест. Проверяем переменную $instance на наличие этих значений (существуют ли они). Если значения есть, извлекаем их. Если их нет, просто передаем стандартные значения (устанавливаем количество мест на 5 и передаем ID по умолчанию).

Создаем лейбл и форму для показа мест в панели администратора. С помощью функции get_posts() вытягиваем все места и показываем их. Каждое место мы проверяем на совпадение с сохраненным ID (если он был задан).

Создаем список select для отображения всех наших мест. И опять проверяем все варианты на совпадение с переданным значением.

Обновление виджета и сохранение вариантов

Для сохранения значений формы необходимо вызывать функцию обновления виджета. Функция update() унаследована от класса WP_widget. Нам осталось только указать, как сохранять значения.

У нас есть две переменные $new_instance и $old_instance. В $new_instance хранятся текущие значения формы, а в $old_instance хранятся старые значения. Нам необходимо создать новый массив для хранения извлеченных значений для последующего их возврата.

Отображение виджета на стороне front-end’а

Функция widget() унаследована из класса WP_widget, с ее помощью виджет показывается на стороне front-end’а. Для формирования кода на вывод используется функция отображения из класса wp_simple_locations.

Что мы тут делаем:

Создаем глобальный объект $wp_simple_locations, нам нужна его функция вывода на экран.

Создаем пустой массив аргументов и проверяем, заданы ли аргументы для виджета (количество мест, к примеру).

Начинаем формировать код на вывод и создаем переменную $html. Вызываем функцию get_locations_output(), прописанную в объекте $wp_simple_locations, и передаем в нее аргументы (нам вернется весь HTML код).

Выводим весь код из переменной $html на экран.

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

Функция ниже нужна для регистрации виджета в WordPress. Необходимо вызвать функцию register_widget() и передать в нее название класса в качестве значения.

Надеюсь, вам понравился реальный пример разработки плагина для WordPress с нуля. Следите за моими статьями.

Автор: Simon Codrington

Источник: //www.sitepoint.com/

Редакция: Команда webformyself.

Метки:

Похожие статьи:

Комментарии Вконтакте: