Как создать свой плагин для WordPress: от простого плагина в одном файле до профессионального

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

Оглавление:

Создание плагина для WordPress общая информация

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

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

Почему нужно создавать собственный плагин?

  • Потребности и функционал: Иногда доступные плагины не соответствуют специфическим требованиям вашего проекта или недостаточный функционал.
  • Контроль над кодом: Собственный плагин дает полный контроль над функциональностью и безопасностью.
  • Обучение и развитие: Процесс создания плагина улучшает навыки программирования и понимание архитектуры WordPress.
  • Плагин можно отключить: Еще одна причина создания плагина это гибкость. Плагин можно включать и отключать если его функционал не нужен постоянно а только лишь в некоторых случаях.

Далее перейдем непосредственно к структуре и созданию собственного плагина.

Структура плагина и его расположение

Все плагины WordPress находятся в папке сайта wp-content/plugins/. Здесь вы можете создавать папки для своих плагинов или размещать одиночные файлы плагинов. Лучше использовать папки и дальше вы поймете почему.

Базовая структура простого плагина в одном файле

wp-content/
└── plugins/
    └── scroll-to-top-button/
        └── scroll-to-top-button.php

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

Далее переходим в папке wp-content и дальше открываем папку plugins и создадим здесь папку под названием нашего будущего плагина scroll-to-top-button

  • scroll-to-top-button/ — папка плагина.
  • scroll-to-top-button.php — главный файл плагина с расширением .php

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

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

Шаг 1: Создание заголовка плагина

Заголовок необходим, чтобы WordPress распознал ваш файл как плагин. Имя которое вы напишете в поле Plugin Name — так и будет называться ваш плагин в админке сайта.

Откройте файл scroll-to-top-button.php и добавьте следующий код:

<?php
/*
Plugin Name: Scroll To Top Button
Description: Добавляет кнопку "Вверх" внизу страницы.
Version: 1.0
Author: Ваше Имя
*/

Шаг 2: Добавление кнопки на сайт через плагин

Напишем простую функцию, которая создаст кнопку в параметрами внизу страницы сайта.

function sttb_add_button() {
    echo '<a href="#" id="sttb-button" style="display:none;position:fixed;bottom:20px;right:20px;padding:10px;background:#000;color:#fff;text-decoration:none;border-radius:5px;">Вверх</a>';
}
add_action('wp_footer', 'sttb_add_button');

Мы используем хук wp_footer, чтобы добавить HTML и CSS код кнопки перед закрывающим тегом </body>.

Шаг 3: Добавление JavaScript для прокрутки и отображения кнопки

Мы добавим JavaScript-код, который будет показывать кнопку после прокрутки страницы вниз и осуществлять плавную прокрутку вверх при нажатии.

function sttb_add_scripts() {
    ?>
    <script>
    document.addEventListener('DOMContentLoaded', function() {
        var sttbButton = document.getElementById('sttb-button');
        window.addEventListener('scroll', function() {
            if (window.pageYOffset > 300) {
                sttbButton.style.display = 'block';
            } else {
                sttbButton.style.display = 'none';
            }
        });
        sttbButton.addEventListener('click', function(e) {
            e.preventDefault();
            window.scrollTo({ top: 0, behavior: 'smooth' });
        });
    });
    </script>
    <?php
}
add_action('wp_footer', 'sttb_add_scripts');

Шаг 4: Полный код простого плагина и его активация

Объединим весь код в одно целое и добавим его в наш созданный файл scroll-to-top-button.php после чего зайдем в админку и активируем плагин.

Полный код плагина:

<?php
/*
Plugin Name: Scroll To Top Button
Description: Добавляет кнопку "Вверх" внизу страницы.
Version: 1.0
Author: Ваше Имя
*/
function sttb_add_button() {
    echo '<a href="#" id="sttb-button" style="display:none;position:fixed;bottom:20px;right:20px;padding:10px;background:#000;color:#fff;text-decoration:none;border-radius:5px;">Вверх</a>';
}
add_action('wp_footer', 'sttb_add_button');

function sttb_add_scripts() {
    ?>
    <script>
    document.addEventListener('DOMContentLoaded', function() {
        var sttbButton = document.getElementById('sttb-button');
        window.addEventListener('scroll', function() {
            if (window.pageYOffset > 300) {
                sttbButton.style.display = 'block';
            } else {
                sttbButton.style.display = 'none';
            }
        });
        sttbButton.addEventListener('click', function(e) {
            e.preventDefault();
            window.scrollTo({ top: 0, behavior: 'smooth' });
        });
    });
    </script>
    <?php
}
add_action('wp_footer', 'sttb_add_scripts');

Активация:

Перейдите в админку в раздел плагины и активируйте созданный нами плагин.

Как создать свой плагин для WordPress: от простого плагина в одном файле до профессионального

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

Расширяем возможности плагина и добавляем функционал редактирования плагина через админку

Расширяем возможности плагина и добавляем функционал редактирования плагина через админку

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

Шаг 1: Создание страницы настроек в админке

Добавим меню в админке для доступа к настройкам плагина.

// Добавление меню настроек в админке
function sttb_add_admin_menu() {
    add_options_page(
        'Настройки Scroll To Top Button', // Заголовок страницы
        'Scroll To Top Button',           // Название меню
        'manage_options',                 // Возможность доступа
        'sttb',                           // Уникальный идентификатор страницы
        'sttb_settings_page'              // Функция вывода страницы настроек
    );
}
add_action('admin_menu', 'sttb_add_admin_menu');

Шаг 2: Создание функции вывода страницы настроек

Теперь создадим функцию sttb_settings_page, которая будет отображать форму настроек.

// Функция вывода страницы настроек
function sttb_settings_page() {
    ?>
    <div class="wrap">
        <h1>Настройки Scroll To Top Button</h1>
        <form method="post" action="options.php">
            <?php
            // Вывод настроек
            settings_fields('sttb_settings_group');
            do_settings_sections('sttb');
            submit_button();
            ?>
        </form>
    </div>
    <?php
}

Шаг 3: Регистрация настроек и полей

Далее зарегистрируем настройки и добавим необходимые поля для редактирования.

// Регистрация настроек
function sttb_register_settings() {
    // Регистрация настроек
    register_setting('sttb_settings_group', 'sttb_icon');
    register_setting('sttb_settings_group', 'sttb_color');
    register_setting('sttb_settings_group', 'sttb_position');

    // Добавление секции настроек
    add_settings_section('sttb_main_section', 'Основные настройки', null, 'sttb');

    // Добавление полей настроек
    add_settings_field('sttb_icon', 'Иконка кнопки', 'sttb_icon_callback', 'sttb', 'sttb_main_section');
    add_settings_field('sttb_color', 'Цвет кнопки', 'sttb_color_callback', 'sttb', 'sttb_main_section');
    add_settings_field('sttb_position', 'Положение кнопки', 'sttb_position_callback', 'sttb', 'sttb_main_section');
}
add_action('admin_init', 'sttb_register_settings');

Шаг 4: Создание функций обратного вызова для полей

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

// Поле для ввода иконки
function sttb_icon_callback() {
    $sttb_icon = esc_attr(get_option('sttb_icon', '▲'));
    echo '<input type="text" name="sttb_icon" value="' . $sttb_icon . '" />';
}

// Поле для выбора цвета
function sttb_color_callback() {
    $sttb_color = esc_attr(get_option('sttb_color', '#000000'));
    echo '<input type="color" name="sttb_color" value="' . $sttb_color . '" />';
}

// Поле для выбора положения кнопки
function sttb_position_callback() {
    $sttb_position = esc_attr(get_option('sttb_position', 'right'));
    ?>
    <select name="sttb_position">
        <option value="right" <?php selected($sttb_position, 'right'); ?>>Справа</option>
        <option value="left" <?php selected($sttb_position, 'left'); ?>>Слева</option>
    </select>
    <?php
}

Шаг 5: Обновление функции вывода кнопки

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

// Новая функция для вывода кнопки с учетом настроек
function sttb_render_button() {
    $icon = esc_attr(get_option('sttb_icon', '▲'));
    $color = esc_attr(get_option('sttb_color', '#000000'));
    $position = esc_attr(get_option('sttb_position', 'right'));
    $position_style = $position === 'right' ? 'right:20px;' : 'left:20px;';

    echo '<a href="#" id="sttb-button" style="display:none;position:fixed;bottom:20px;' . $position_style . 'padding:10px;background:' . $color . ';color:#fff;text-decoration:none;border-radius:5px;">' . $icon . '</a>';
}
add_action('wp_footer', 'sttb_render_button');

Обратите внимание, что мы создали новую функцию sttb_render_button, а не изменили старую sttb_add_button.

Шаг 6: Итоговый код плагина в одном файле

Теперь соберем весь код плагина в одном файле scroll-to-top-button.php.

<?php
/*
Plugin Name: Scroll To Top Button
Description: Добавляет настраиваемую кнопку "Вверх" внизу страницы.
Version: 1.1
Author: Ваше Имя
*/

// Запрет прямого доступа
if (!defined('ABSPATH')) exit;

// Добавление кнопки в футер
function sttb_add_button() {
    echo '<a href="#" id="sttb-button" style="display:none;position:fixed;bottom:20px;right:20px;padding:10px;background:#000;color:#fff;text-decoration:none;border-radius:5px;">▲</a>';
}
add_action('wp_footer', 'sttb_add_button');

// Добавление скриптов в футер
function sttb_add_scripts() {
    ?>
    <script>
    document.addEventListener('DOMContentLoaded', function() {
        var sttbButton = document.getElementById('sttb-button');
        window.addEventListener('scroll', function() {
            if (window.pageYOffset > 300) {
                sttbButton.style.display = 'block';
            } else {
                sttbButton.style.display = 'none';
            }
        });
        sttbButton.addEventListener('click', function(e) {
            e.preventDefault();
            window.scrollTo({ top: 0, behavior: 'smooth' });
        });
    });
    </script>
    <?php
}
add_action('wp_footer', 'sttb_add_scripts');

// Добавление меню настроек в админке
function sttb_add_admin_menu() {
    add_options_page(
        'Настройки Scroll To Top Button',
        'Scroll To Top Button',
        'manage_options',
        'sttb',
        'sttb_settings_page'
    );
}
add_action('admin_menu', 'sttb_add_admin_menu');

// Функция вывода страницы настроек
function sttb_settings_page() {
    ?>
    <div class="wrap">
        <h1>Настройки Scroll To Top Button</h1>
        <form method="post" action="options.php">
            <?php
            settings_fields('sttb_settings_group');
            do_settings_sections('sttb');
            submit_button();
            ?>
        </form>
    </div>
    <?php
}

// Регистрация настроек
function sttb_register_settings() {
    register_setting('sttb_settings_group', 'sttb_icon');
    register_setting('sttb_settings_group', 'sttb_color');
    register_setting('sttb_settings_group', 'sttb_position');

    add_settings_section('sttb_main_section', 'Основные настройки', null, 'sttb');

    add_settings_field('sttb_icon', 'Иконка кнопки', 'sttb_icon_callback', 'sttb', 'sttb_main_section');
    add_settings_field('sttb_color', 'Цвет кнопки', 'sttb_color_callback', 'sttb', 'sttb_main_section');
    add_settings_field('sttb_position', 'Положение кнопки', 'sttb_position_callback', 'sttb', 'sttb_main_section');
}
add_action('admin_init', 'sttb_register_settings');

// Поле для ввода иконки
function sttb_icon_callback() {
    $sttb_icon = esc_attr(get_option('sttb_icon', '▲'));
    echo '<input type="text" name="sttb_icon" value="' . $sttb_icon . '" />';
}

// Поле для выбора цвета
function sttb_color_callback() {
    $sttb_color = esc_attr(get_option('sttb_color', '#000000'));
    echo '<input type="color" name="sttb_color" value="' . $sttb_color . '" />';
}

// Поле для выбора положения кнопки
function sttb_position_callback() {
    $sttb_position = esc_attr(get_option('sttb_position', 'right'));
    ?>
    <select name="sttb_position">
        <option value="right" <?php selected($sttb_position, 'right'); ?>>Справа</option>
        <option value="left" <?php selected($sttb_position, 'left'); ?>>Слева</option>
    </select>
    <?php
}

// Новая функция для вывода кнопки с учетом настроек
function sttb_render_button() {
    $icon = esc_attr(get_option('sttb_icon', '▲'));
    $color = esc_attr(get_option('sttb_color', '#000000'));
    $position = esc_attr(get_option('sttb_position', 'right'));
    $position_style = $position === 'right' ? 'right:20px;' : 'left:20px;';

    echo '<a href="#" id="sttb-button" style="display:none;position:fixed;bottom:20px;' . $position_style . 'padding:10px;background:' . $color . ';color:#fff;text-decoration:none;border-radius:5px;">' . $icon . '</a>';
}
add_action('wp_footer', 'sttb_render_button');

Шаг 7: Редактируем плагин через админку

Заходим в админку в раздел настройки и заходим на страницу настроек нашего плагина и видим там следующее:

Шаг 7: Редактируем плагин через админку

На данной странице мы можем изменить иконку для кнопки ее цвет и позиционирование кнопки.

А на самом сайте мы увидим такие изменения:

Оптимизация структуры плагина и добавление расширенных функций

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

Оптимизация структуры плагина и добавление расширенных функций

Разделение кода на несколько файлов помогает организовать проект, облегчает разработку, поддержку и дальнейшее развитие плагина. Перейдем к новой структуре файлов.

Шаг 1: Создание структуры папок

Мы создадим следующую структуру папок внутри папки нашего плагина scroll-to-top-button:

scroll-to-top-button/
├── assets/
│   ├── css/
│   │   └── sttb-style.css
│   └── js/
│       └── sttb-script.js
├── includes/
│   ├── admin.php
│   └── frontend.php
└── scroll-to-top-button.php
  • assets/ — содержит файлы CSS и JavaScript.
  • includes/ — содержит PHP-файлы с функциональностью для админки и фронтенда.
  • scroll-to-top-button.php — главный файл плагина.

Шаг 2: Обновление главного файла плагина

<?php
/*
Plugin Name: Scroll To Top Button
Description: Добавляет настраиваемую кнопку "Вверх" внизу страницы.
Version: 2.0
Author: Ваше Имя
*/

if (!defined('ABSPATH')) exit;

// Подключение файлов
require_once plugin_dir_path(__FILE__) . 'includes/admin.php';
require_once plugin_dir_path(__FILE__) . 'includes/frontend.php';

Шаг 3: Перенос кода в файлы admin.php и frontend.php

Файл includes/admin.php:

<?php
// Запрет прямого доступа
if (!defined('ABSPATH')) exit;

// Добавление меню настроек в админке
function sttb_add_admin_menu() {
    add_options_page(
        'Настройки Scroll To Top Button',
        'Scroll To Top Button',
        'manage_options',
        'sttb',
        'sttb_settings_page'
    );
}
add_action('admin_menu', 'sttb_add_admin_menu');

// Функция вывода страницы настроек
function sttb_settings_page() {
    ?>
    <div class="wrap">
        <h1>Настройки Scroll To Top Button</h1>
        <form method="post" action="options.php">
            <?php
            settings_fields('sttb_settings_group');
            do_settings_sections('sttb');
            submit_button();
            ?>
        </form>
    </div>
    <?php
}

// Регистрация настроек
function sttb_register_settings() {
    register_setting('sttb_settings_group', 'sttb_icon');
    register_setting('sttb_settings_group', 'sttb_color');
    register_setting('sttb_settings_group', 'sttb_position');
    register_setting('sttb_settings_group', 'sttb_scroll_distance');

    add_settings_section('sttb_main_section', 'Основные настройки', null, 'sttb');

    add_settings_field('sttb_icon', 'Иконка кнопки', 'sttb_icon_callback', 'sttb', 'sttb_main_section');
    add_settings_field('sttb_color', 'Цвет кнопки', 'sttb_color_callback', 'sttb', 'sttb_main_section');
    add_settings_field('sttb_position', 'Положение кнопки', 'sttb_position_callback', 'sttb', 'sttb_main_section');
    add_settings_field('sttb_scroll_distance', 'Расстояние прокрутки (px)', 'sttb_scroll_distance_callback', 'sttb', 'sttb_main_section');
}
add_action('admin_init', 'sttb_register_settings');

// Поле для ввода иконки
function sttb_icon_callback() {
    $sttb_icon = esc_attr(get_option('sttb_icon', '▲'));
    echo '<input type="text" name="sttb_icon" value="' . $sttb_icon . '" />';
}

// Поле для выбора цвета
function sttb_color_callback() {
    $sttb_color = esc_attr(get_option('sttb_color', '#000000'));
    echo '<input type="color" name="sttb_color" value="' . $sttb_color . '" />';
}

// Поле для выбора положения кнопки
function sttb_position_callback() {
    $sttb_position = esc_attr(get_option('sttb_position', 'right'));
    ?>
    <select name="sttb_position">
        <option value="right" <?php selected($sttb_position, 'right'); ?>>Справа</option>
        <option value="left" <?php selected($sttb_position, 'left'); ?>>Слева</option>
    </select>
    <?php
}

// Поле для ввода расстояния прокрутки
function sttb_scroll_distance_callback() {
    $sttb_scroll_distance = esc_attr(get_option('sttb_scroll_distance', 300));
    echo '<input type="number" name="sttb_scroll_distance" value="' . $sttb_scroll_distance . '" />';
}

Файл includes/frontend.php:

<?php
// Запрет прямого доступа
if (!defined('ABSPATH')) exit;

// Добавление кнопки в футер
function sttb_render_button() {
    $icon = esc_attr(get_option('sttb_icon', '▲'));
    $color = esc_attr(get_option('sttb_color', '#000000'));
    $position = esc_attr(get_option('sttb_position', 'right'));
    $position_style = $position === 'right' ? 'right:20px;' : 'left:20px;';

    echo '<a href="#" id="sttb-button" style="display:none;position:fixed;bottom:20px;' . $position_style . 'padding:10px;background:' . $color . ';color:#fff;text-decoration:none;border-radius:5px;">' . $icon . '</a>';
}
add_action('wp_footer', 'sttb_render_button');

// Подключение стилей и скриптов
function sttb_enqueue_assets() {
    wp_enqueue_style('sttb-style', plugin_dir_url(__FILE__) . '../assets/css/sttb-style.css');
    wp_enqueue_script('sttb-script', plugin_dir_url(__FILE__) . '../assets/js/sttb-script.js', array('jquery'), '1.0', true);

    $sttb_scroll_distance = esc_attr(get_option('sttb_scroll_distance', 300));

    wp_localize_script('sttb-script', 'sttbSettings', array(
        'scrollDistance' => $sttb_scroll_distance
    ));
}
add_action('wp_enqueue_scripts', 'sttb_enqueue_assets');

Шаг 4: Создание файлов стилей и скриптов

Файл assets/css/sttb-style.css:

#sttb-button {
    /* Стили кнопки могут быть перенесены сюда, если необходимо */
}

Файл assets/js/sttb-script.js:

jQuery(document).ready(function($) {
    var sttbButton = $('#sttb-button');
    var scrollDistance = parseInt(sttbSettings.scrollDistance, 10);

    $(window).scroll(function() {
        if ($(window).scrollTop() > scrollDistance) {
            sttbButton.fadeIn();
        } else {
            sttbButton.fadeOut();
        }
    });

    sttbButton.click(function(e) {
        e.preventDefault();
        $('html, body').animate({scrollTop: 0}, 'slow');
    });
});

 Финальная структура плагина и добавление расширенных настроек

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

Финальная структура плагина

Создадим оптимизированную и логически организованную структуру плагина:

scroll-to-top-button/
├── assets/
│   ├── css/
│   │   └── sttb-style.css
│   └── js/
│       └── sttb-script.js
├── includes/
│   ├── admin.php
│   └── frontend.php
├── languages/
│   └── scroll-to-top-button.pot
└── scroll-to-top-button.php
  • assets/ — содержит файлы стилей и скриптов.
  • includes/ — содержит PHP-файлы с функциональностью для админки и фронтенда.
  • languages/ — содержит файл для локализации плагина.
  • scroll-to-top-button.php — главный файл плагина.

Добавление расширенных настроек в административной панели

Добавим настройку, позволяющую загружать собственное изображение для кнопки через медиабиблиотеку WordPress.

Шаг 1: Возможность загрузки собственного изображения для кнопки

В файле includes/admin.php:

// Регистрация настройки для изображения кнопки
register_setting('sttb_settings_group', 'sttb_button_image', 'esc_url_raw');

// Добавление поля для загрузки изображения
add_settings_field('sttb_button_image', 'Изображение кнопки', 'sttb_button_image_callback', 'sttb', 'sttb_main_section');

// Функция обратного вызова для поля загрузки изображения
function sttb_button_image_callback() {
    $sttb_button_image = esc_url(get_option('sttb_button_image'));
    echo '<input type="text" id="sttb_button_image" name="sttb_button_image" value="' . $sttb_button_image . '" />';
    echo '<button class="upload_image_button button">Загрузить изображение</button>';
    ?>
    <script>
    jQuery(document).ready(function($){
        var mediaUploader;
        $('.upload_image_button').click(function(e) {
            e.preventDefault();
            if (mediaUploader) {
                mediaUploader.open();
                return;
            }
            mediaUploader = wp.media.frames.file_frame = wp.media({
                title: 'Выберите изображение кнопки',
                button: {
                    text: 'Выбрать изображение'
                }, multiple: false });
            mediaUploader.on('select', function() {
                var attachment = mediaUploader.state().get('selection').first().toJSON();
                $('#sttb_button_image').val(attachment.url);
            });
            mediaUploader.open();
        });
    });
    </script>
    <?php
}

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

function sttb_admin_enqueue_scripts($hook) {
    if ('settings_page_sttb' !== $hook) {
        return;
    }
    wp_enqueue_media();
}
add_action('admin_enqueue_scripts', 'sttb_admin_enqueue_scripts');

Шаг 2: Возможность позиционирования кнопки с точностью до пикселя

Добавим настройки для установки отступов сверху, снизу, слева и справа.

В файле includes/admin.php:

// Регистрация настроек для отступов
register_setting('sttb_settings_group', 'sttb_position_top', 'absint');
register_setting('sttb_settings_group', 'sttb_position_bottom', 'absint');
register_setting('sttb_settings_group', 'sttb_position_left', 'absint');
register_setting('sttb_settings_group', 'sttb_position_right', 'absint');

// Добавление полей для отступов
add_settings_field('sttb_position_top', 'Отступ сверху (px)', 'sttb_position_top_callback', 'sttb', 'sttb_main_section');
add_settings_field('sttb_position_bottom', 'Отступ снизу (px)', 'sttb_position_bottom_callback', 'sttb', 'sttb_main_section');
add_settings_field('sttb_position_left', 'Отступ слева (px)', 'sttb_position_left_callback', 'sttb', 'sttb_main_section');
add_settings_field('sttb_position_right', 'Отступ справа (px)', 'sttb_position_right_callback', 'sttb', 'sttb_main_section');

// Функции обратного вызова для отступов
function sttb_position_top_callback() {
    $value = esc_attr(get_option('sttb_position_top', 0));
    echo '<input type="number" name="sttb_position_top" value="' . $value . '" min="0" />';
}

function sttb_position_bottom_callback() {
    $value = esc_attr(get_option('sttb_position_bottom', 20));
    echo '<input type="number" name="sttb_position_bottom" value="' . $value . '" min="0" />';
}

function sttb_position_left_callback() {
    $value = esc_attr(get_option('sttb_position_left', 0));
    echo '<input type="number" name="sttb_position_left" value="' . $value . '" min="0" />';
}

function sttb_position_right_callback() {
    $value = esc_attr(get_option('sttb_position_right', 20));
    echo '<input type="number" name="sttb_position_right" value="' . $value . '" min="0" />';
}

Шаг 3: Обновление функции вывода кнопки с учетом новых настроек

В файле includes/frontend.php:

function sttb_render_button() {
    if (!sttb_should_display()) {
        return;
    }

    $icon = esc_attr(get_option('sttb_icon', '▲'));
    $color = esc_attr(get_option('sttb_color', '#000000'));
    $button_image = esc_url(get_option('sttb_button_image'));
    $top = esc_attr(get_option('sttb_position_top', 0));
    $bottom = esc_attr(get_option('sttb_position_bottom', 20));
    $left = esc_attr(get_option('sttb_position_left', 0));
    $right = esc_attr(get_option('sttb_position_right', 20));

    // Формирование стилей позиции
    $position_style = '';
    if ($top > 0) {
        $position_style .= 'top:' . $top . 'px;';
    } else {
        $position_style .= 'bottom:' . $bottom . 'px;';
    }
    if ($left > 0) {
        $position_style .= 'left:' . $left . 'px;';
    } else {
        $position_style .= 'right:' . $right . 'px;';
    }

    // Определение содержимого кнопки
    if ($button_image) {
        $button_content = '<img src="' . $button_image . '" alt="Scroll to Top" />';
    } else {
        $button_content = $icon;
    }

    echo '<a href="#" id="sttb-button" style="display:none;position:fixed;' . $position_style . 'background:' . $color . ';color:#fff;text-decoration:none;">' . $button_content . '</a>';
}
add_action('wp_footer', 'sttb_render_button');

Шаг 4: Обновление стилей кнопки

В файле assets/css/sttb-style.css:

#sttb-button {
    padding: 10px 15px;
    border-radius: 5px;
    transition: opacity 0.3s ease;
}

#sttb-button img {
    max-width: 50px;
    max-height: 50px;
}

Шаг 5: Оптимизация JavaScript-кода

В файле assets/js/sttb-script.js:

(function($){
    $(document).ready(function(){
        var sttbButton = $('#sttb-button');
        var scrollDistance = parseInt(sttbSettings.scrollDistance, 10) || 300;

        $(window).on('scroll', function() {
            if ($(window).scrollTop() > scrollDistance) {
                sttbButton.fadeIn();
            } else {
                sttbButton.fadeOut();
            }
        });

        sttbButton.on('click', function(e) {
            e.preventDefault();
            $('html, body').animate({scrollTop: 0}, 'slow');
        });
    });
})(jQuery);

Шаг 6: Подытог об улучшении безопасности и производительности

Что конкретно было сделано:

  • Валидация и очистка данных: Мы использовали функции esc_attr, esc_url, absint для очистки данных из настроек.
  • Загрузка файлов безопасным способом: Используем функции WordPress для загрузки и выбора изображений.
  • Оптимизация подключений: Скрипты и стили подключаются только там, где необходимо.

Финальная часть и полный код каждого файла

1. Файл scroll-to-top-button.php

<?php
/*
Plugin Name: Scroll To Top Button
Description: Добавляет настраиваемую кнопку "Вверх" с расширенными настройками.
Version: 3.0
Author: Ваше Имя
Text Domain: scroll-to-top-button
Domain Path: /languages
*/

if (!defined('ABSPATH')) exit;

// Подключение файлов
require_once plugin_dir_path(__FILE__) . 'includes/admin.php';
require_once plugin_dir_path(__FILE__) . 'includes/frontend.php';

// Загрузка текстового домена для локализации
function sttb_load_textdomain() {
    load_plugin_textdomain('scroll-to-top-button', false, dirname(plugin_basename(__FILE__)) . '/languages');
}
add_action('plugins_loaded', 'sttb_load_textdomain');

2. Файл includes/admin.php

<?php
if (!defined('ABSPATH')) exit;

// Добавление меню настроек в админке
function sttb_add_admin_menu() {
    add_options_page(
        __('Scroll To Top Button Settings', 'scroll-to-top-button'),
        __('Scroll To Top Button', 'scroll-to-top-button'),
        'manage_options',
        'sttb',
        'sttb_settings_page'
    );
}
add_action('admin_menu', 'sttb_add_admin_menu');

// Функция вывода страницы настроек
function sttb_settings_page() {
    ?>
    <div class="wrap">
        <h1><?php _e('Scroll To Top Button Settings', 'scroll-to-top-button'); ?></h1>
        <form method="post" action="options.php">
            <?php
            settings_fields('sttb_settings_group');
            do_settings_sections('sttb');
            submit_button();
            ?>
        </form>
    </div>
    <?php
}

// Регистрация настроек
function sttb_register_settings() {
    // Регистрация настроек
    register_setting('sttb_settings_group', 'sttb_icon', 'sanitize_text_field');
    register_setting('sttb_settings_group', 'sttb_color', 'sanitize_hex_color');
    register_setting('sttb_settings_group', 'sttb_button_image', 'esc_url_raw');
    register_setting('sttb_settings_group', 'sttb_position_top', 'absint');
    register_setting('sttb_settings_group', 'sttb_position_bottom', 'absint');
    register_setting('sttb_settings_group', 'sttb_position_left', 'absint');
    register_setting('sttb_settings_group', 'sttb_position_right', 'absint');
    register_setting('sttb_settings_group', 'sttb_scroll_distance', 'absint');

    // Добавление секции настроек
    add_settings_section('sttb_main_section', __('Main Settings', 'scroll-to-top-button'), null, 'sttb');

    // Добавление полей настроек
    add_settings_field('sttb_icon', __('Button Icon', 'scroll-to-top-button'), 'sttb_icon_callback', 'sttb', 'sttb_main_section');
    add_settings_field('sttb_color', __('Button Color', 'scroll-to-top-button'), 'sttb_color_callback', 'sttb', 'sttb_main_section');
    add_settings_field('sttb_button_image', __('Button Image', 'scroll-to-top-button'), 'sttb_button_image_callback', 'sttb', 'sttb_main_section');
    add_settings_field('sttb_position_top', __('Top Offset (px)', 'scroll-to-top-button'), 'sttb_position_top_callback', 'sttb', 'sttb_main_section');
    add_settings_field('sttb_position_bottom', __('Bottom Offset (px)', 'scroll-to-top-button'), 'sttb_position_bottom_callback', 'sttb', 'sttb_main_section');
    add_settings_field('sttb_position_left', __('Left Offset (px)', 'scroll-to-top-button'), 'sttb_position_left_callback', 'sttb', 'sttb_main_section');
    add_settings_field('sttb_position_right', __('Right Offset (px)', 'scroll-to-top-button'), 'sttb_position_right_callback', 'sttb', 'sttb_main_section');
    add_settings_field('sttb_scroll_distance', __('Scroll Distance (px)', 'scroll-to-top-button'), 'sttb_scroll_distance_callback', 'sttb', 'sttb_main_section');
}
add_action('admin_init', 'sttb_register_settings');

// Функции обратного вызова для полей настроек
function sttb_icon_callback() {
    $sttb_icon = esc_attr(get_option('sttb_icon', '▲'));
    echo '<input type="text" name="sttb_icon" value="' . $sttb_icon . '" />';
}

function sttb_color_callback() {
    $sttb_color = esc_attr(get_option('sttb_color', '#000000'));
    echo '<input type="color" name="sttb_color" value="' . $sttb_color . '" />';
}

function sttb_button_image_callback() {
    $sttb_button_image = esc_url(get_option('sttb_button_image'));
    echo '<input type="text" id="sttb_button_image" name="sttb_button_image" value="' . $sttb_button_image . '" />';
    echo ' <button class="upload_image_button button">' . __('Upload Image', 'scroll-to-top-button') . '</button>';
    ?>
    <script>
    jQuery(document).ready(function($){
        var mediaUploader;
        $('.upload_image_button').click(function(e) {
            e.preventDefault();
            if (mediaUploader) {
                mediaUploader.open();
                return;
            }
            mediaUploader = wp.media.frames.file_frame = wp.media({
                title: '<?php _e('Select Button Image', 'scroll-to-top-button'); ?>',
                button: {
                    text: '<?php _e('Use Image', 'scroll-to-top-button'); ?>'
                }, multiple: false });
            mediaUploader.on('select', function() {
                var attachment = mediaUploader.state().get('selection').first().toJSON();
                $('#sttb_button_image').val(attachment.url);
            });
            mediaUploader.open();
        });
    });
    </script>
    <?php
}

function sttb_position_top_callback() {
    $value = esc_attr(get_option('sttb_position_top', 0));
    echo '<input type="number" name="sttb_position_top" value="' . $value . '" min="0" />';
}

function sttb_position_bottom_callback() {
    $value = esc_attr(get_option('sttb_position_bottom', 20));
    echo '<input type="number" name="sttb_position_bottom" value="' . $value . '" min="0" />';
}

function sttb_position_left_callback() {
    $value = esc_attr(get_option('sttb_position_left', 0));
    echo '<input type="number" name="sttb_position_left" value="' . $value . '" min="0" />';
}

function sttb_position_right_callback() {
    $value = esc_attr(get_option('sttb_position_right', 20));
    echo '<input type="number" name="sttb_position_right" value="' . $value . '" min="0" />';
}

function sttb_scroll_distance_callback() {
    $value = esc_attr(get_option('sttb_scroll_distance', 300));
    echo '<input type="number" name="sttb_scroll_distance" value="' . $value . '" min="0" />';
}

// Подключение скриптов в админке
function sttb_admin_enqueue_scripts($hook) {
    if ('settings_page_sttb' !== $hook) {
        return;
    }
    wp_enqueue_media();
}
add_action('admin_enqueue_scripts', 'sttb_admin_enqueue_scripts');

3. Файл includes/frontend.php

<?php
if (!defined('ABSPATH')) exit;

// Функция для отображения кнопки
function sttb_render_button() {
    if (!sttb_should_display()) {
        return;
    }

    $icon = esc_attr(get_option('sttb_icon', '▲'));
    $color = esc_attr(get_option('sttb_color', '#000000'));
    $button_image = esc_url(get_option('sttb_button_image'));
    $top = esc_attr(get_option('sttb_position_top', 0));
    $bottom = esc_attr(get_option('sttb_position_bottom', 20));
    $left = esc_attr(get_option('sttb_position_left', 0));
    $right = esc_attr(get_option('sttb_position_right', 20));

    $position_style = '';
    if ($top > 0) {
        $position_style .= 'top:' . $top . 'px;';
    } else {
        $position_style .= 'bottom:' . $bottom . 'px;';
    }
    if ($left > 0) {
        $position_style .= 'left:' . $left . 'px;';
    } else {
        $position_style .= 'right:' . $right . 'px;';
    }

    if ($button_image) {
        $button_content = '<img src="' . $button_image . '" alt="Scroll to Top" />';
    } else {
        $button_content = $icon;
    }

    echo '<a href="#" id="sttb-button" style="display:none;position:fixed;' . $position_style . 'background:' . $color . ';color:#fff;text-decoration:none;">' . $button_content . '</a>';
}
add_action('wp_footer', 'sttb_render_button');

// Функция для определения отображения кнопки
function sttb_should_display() {
    return apply_filters('sttb_should_display', true);
}

// Подключение стилей и скриптов
function sttb_enqueue_assets() {
    wp_enqueue_style('sttb-style', plugin_dir_url(__FILE__) . '../assets/css/sttb-style.css');
    wp_enqueue_script('sttb-script', plugin_dir_url(__FILE__) . '../assets/js/sttb-script.js', array('jquery'), '1.0', true);

    $sttb_scroll_distance = esc_attr(get_option('sttb_scroll_distance', 300));

    wp_localize_script('sttb-script', 'sttbSettings', array(
        'scrollDistance' => $sttb_scroll_distance
    ));
}
add_action('wp_enqueue_scripts', 'sttb_enqueue_assets');

4. Файл assets/css/sttb-style.css

#sttb-button {
    padding: 10px 15px;
    border-radius: 5px;
    transition: opacity 0.3s ease;
    z-index: 9999;
}

#sttb-button img {
    max-width: 50px;
    max-height: 50px;
}

5. Файл assets/js/sttb-script.js

(function($){
    $(document).ready(function(){
        var sttbButton = $('#sttb-button');
        var scrollDistance = parseInt(sttbSettings.scrollDistance, 10) || 300;

        $(window).on('scroll', function() {
            if ($(window).scrollTop() > scrollDistance) {
                sttbButton.fadeIn();
            } else {
                sttbButton.fadeOut();
            }
        });

        sttbButton.on('click', function(e) {
            e.preventDefault();
            $('html, body').animate({scrollTop: 0}, 'slow');
        });
    });
})(jQuery);

Финалочка

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

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

Для отправки комментария вам необходимо авторизоваться.

Популярные статьи: