WordPress. Метабоксы. Часть 2 из 2

16.09.2019

Теги: CMSWeb-разработкаWordPressМетаБоксМетаДанныеПлагин

Давайте немного попрактикуемся и напишем плагин, который добавит метабокс «Настройки SEO» для формы редактирования постов и страниц. Метабокс будет содержать текстовое поле для заголовка записи и ckeckbox, который закрывает пост или страницу от индексации поисковыми системами.

Плагин «Настройки SEO» для постов и страниц

Итак, создаем директорию tokmakov-metabox-seo и внутри нее — файл tokmakov-metabox-seo.php:

<?php
/*
Plugin Name: Настройки SEO для постов и страниц
Plugin URI: https://tokmakov.msk.ru
Description: Добавляет метабокс «Настройки SEO» для постов и страниц
Version: 1.0
Author: Евгений Токмаков
Author URI: https://tokmakov.msk.ru
*/

register_activation_hook(__FILE__, function () {
    // проверяем права пользователя на активацию плагинов
    if (!current_user_can('activate_plugins')) {
        return;
    }
});

register_deactivation_hook(__FILE__, function () {
    // проверяем права пользователя на деактивацию плагинов
    if (!current_user_can('deactivate_plugins')) {
        return;
    }
});

Добавляем метабокс «Настройки SEO» для записей блога и страниц:

/*
 * Добавляем метабокс «Настройки SEO» для записей блога и страниц
 */
add_action('add_meta_boxes', function () {
    add_meta_box(
        'tokmakov-metabox-seo',
        'Настройки SEO',
        function ($post) {
            wp_nonce_field(plugin_basename(__FILE__), 'tokmakov_metabox_seo_nonce');
            $title =  '';
            $robots = 'all';
            $meta = get_post_meta($post->ID, 'tokmakov_metabox_seo', true);
            if (!empty($meta)) {
                $title = $meta['title'];
                $robots = $meta['robots'];
            }
            ?>
            <fieldset>
                <legend>Заголовок окна браузера</legend>
                <input type="text" name="tokmakov_seo_title" value="<?= esc_attr($title); ?>" />
            </fieldset>
            <fieldset>
                <legend>Мета-тег robots (all, none)</legend>
                <input type="checkbox"
                       name="tokmakov_seo_robots"
                       id="tokmakov_seo_robots"
                       value="1"
                       <?php checked($robots, 'none'); ?> />
                <label for="tokmakov_seo_robots">Скрыть запись от поисковиков?</label>
            </fieldset>
            <?php
        },
        ['post', 'page'],
        'normal',
        'high'
    );
});

Сохраняем данные из формы добавления-редактирования поста или страницы:

/*
 * Сохраняем данные из формы добавления-редактирования поста или страницы
 */
add_action('save_post', function ($post_id) {

    // проверяем наличие nonce-поля, потому что save_post может быть вызван с другого места
    if (!isset($_POST['tokmakov_metabox_seo_nonce'])) {
        return;
    }
    // проверяем корректность nonce-поля
    if (!wp_verify_nonce($_POST['tokmakov_metabox_seo_nonce'], plugin_basename(__FILE__))) {
        return;
    }
    // если это автосохранение, то ничего не делаем
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }
    // проверяем права пользователя
    if(!current_user_can('edit_post', $post_id)) {
        return;
    }
    // тип записи должен быть post или page
    $post = get_post($post_id);
    if (!in_array($post->post_type, ['post', 'page'])) {
        return;
    }

    /*
     * Все хорошо, сохраняем данные метабокса
     */
    $data = [
        'title' => '',
        'robots' => 'all'
    ];
    if (isset($_POST['tokmakov_seo_title'])) {
        $data['title'] = sanitize_text_field($_POST['tokmakov_seo_title']);
    }
    if (isset($_POST['tokmakov_seo_robots'])) {
        $data['robots'] = 'none';
    }
    update_post_meta($post_id, 'tokmakov_metabox_seo', $data);
});

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

/*
 * Подключаем файл стилей для панели управления, чтобы оформить метабокс
 */
add_action('admin_enqueue_scripts', function () {
    wp_enqueue_style(
        'tokmakov-metabox-seo-css',
        plugin_dir_url(__FILE__) . 'style.css'
    );
});
#tokmakov-metabox-seo {
    border: 1px solid #ddf;
}
    #tokmakov-metabox-seo h2 {
        color: #99f;
        border-bottom: 1px solid #ddf;
    }
    #tokmakov-metabox-seo input {
        border: 1px solid #ddf;
    }
    #tokmakov-metabox-seo fieldset {
        display: block;
        box-sizing: border-box;
        width: 100%;
        margin-top: 15px;
        border: 1px solid #ddf;
        padding: 10px;
        background: #f5f5ff;
    }
        #tokmakov-metabox-seo fieldset legend {
            color: #99f;
            border: 1px solid #ddf;
            padding: 0 7px 2px 7px;
            border-radius: 10px;
            background: #fff;
        }
        #tokmakov-metabox-seo fieldset label {
            color: #99f;
        }
            #tokmakov-metabox-seo fieldset input[type="text"] {
                width: 100%;
            }
            #tokmakov-metabox-seo fieldset input[type="checkbox"] {
                position: relative;
                top: 2px;
            }
            #tokmakov-metabox-seo fieldset input[type="checkbox"]:checked:before {
                color: #99f;
            }

Изменяем заголовок поста или страницы в публичной части сайта:

/*
 * Изменяем заголовок поста или страницы в публичной части сайта
 */
add_filter('pre_get_document_title', function() {
    global $post;
    /*
     * если это не пост и не страница, заголовок не изменяем
     */
    if (!is_singular()) {
        return '';
    }
    if (!in_array($post->post_type, ['post', 'page'])) {
        return '';
    }
    /*
     * если заголовок не установлен, то изменять его не будем
     */
    $data = get_post_meta($post->ID, 'tokmakov_metabox_seo', true);
    return empty($data['title']) ? '' : $data['title'];
});

Закрываем от индексации пост или страницу в публичной части сайта:

/*
 * Закрываем от индексации пост или страницу в публичной части сайта
 */
add_action(
    'wp_head',
    function () {
        global $post;
        /*
         * если это не пост и не страница, ничего не делаем
         */
        if (!is_singular()) {
            return;
        }
        if (!in_array($post->post_type, ['post', 'page'])) {
            return;
        }
        /*
         * мета-тег robots устанавливаем только для значения none
         */
        $data = get_post_meta($post->ID, 'tokmakov_metabox_seo', true);
        $robots = empty($data['robots']) ? 'all' : $data['robots'];
        if ($robots == 'none') {
            ?>
            <meta name="robots" content="none" />
            <?php
        }
    },
    1
);

И вот что у нас получилось в итоге:

Последее, что нам осталось сделать — создать файл uninstall.php:

<?php
if (!defined('WP_UNINSTALL_PLUGIN')) {
    exit;
}

global $wpdb;
$wpdb->delete(
    $wpdb->postmeta,
    ['meta_key' => 'tokmakov_metabox_seo']
);

Поиск: CMS • Web-разработка • WordPress • Метабокс • Мета данные • Плагин

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.