WordPress. Добавляем мета-теги. Часть 3 из 3

20.09.2019

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

Добавлять мета-теги keywords и description для рубрик и меток теперь удобно, чего нельзя сказать о добавлении мета-тегов для постов и страниц. Мало того, что для каждой новой записи надо добавлять два произвольных поля, так еще при смене темы нужно вносить изменения в шаблон header.php. Давайте добавим метабокс для страниц редактирования записей, который будет содержать два textarea для мета-тегов. И будем добавлять мета-теги для постов и страниц без необходимости правки шаблона header.php.

Плагин «Мета-теги для SEO»

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

<?php
/*
Plugin Name: Добавляет мета-теги для страниц сайта
Plugin URI: https://tokmakov.msk.ru
Description: Добавляет мета-теги keywords и description для рубрик, меток, постов и страниц.
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;
    }
});

Мы должны решить следующие задачи:

  1. Зарегистрировать произвольные поля для таксономий «Рубрики» и «Метки», в которых будем хранить содержимое мета-тегов.
  2. Добавить textarea для форм создания и редактирования рубрики и метки, для каждой формы — два textarea.
  3. При сохранении данных формы добавления или редактирования рубрики или метки — сохранить мет-теги в таблице БД wp_termmeta.
  4. Создать метабокс для страниц редактирования постов и страниц, который будет содержить два textarea для мета-тегов.
  5. При сохранении данных формы добавления или редактирования записи или страницы — сохранить мет-теги в таблице БД wp_postmeta.
  6. В публичной части сайта при показе страницы списка записей рубрики или метки — добавить мета-теги keywords и description.
  7. В публичной части сайта при показе записи блога или страницы сайта — добавить мета-теги keywords и description.
/*
 * Мы должны решить следующие задачи:
 * 1. Зарегистрировать произвольные поля для таксономий «Рубрики» и «Метки»,
 *    в которых будем хранить содержимое мета-тегов.
 * 2. Добавить textarea для форм создания и редактирования рубрики и метки,
      для каждой формы — два textarea.
 * 3. При сохранении данных формы добавления или редактирования рубрики или
 *    метки — сохранить мет-теги в таблице БД `wp_termmeta`.
 * 4. Создать метабокс для страниц редактирования постов и страниц, который
 *    будет содержать два textarea для мета-тегов.
 * 5. При сохранении данных формы добавления или редактирования записи или
 *    страницы — сохранить мет-теги в таблице БД `wp_postmeta`.
 * 6. В публичной части сайта при показе страницы списка записей рубрики или
 *    метки — добавить мета-теги keywords и description.
 * 7. В публичной части сайта при показе записи блога или страницы сайта —
 *    добавить мета-теги keywords и description.
 */
/*
 * 1. Регистрируем два метаполя для таксономии category и два метаполя для
 *    таксономии post_tag, в которых будем хранить содержимое мета-тегов
 *    keywords и description для каждой рубрики и для каждой метки
 */
add_action('init', function () {
    register_term_meta('category', 'tokmakov_meta_keywords', []);
    register_term_meta('category', 'tokmakov_meta_description', []);
    register_term_meta('post_tag', 'tokmakov_meta_keywords', []);
    register_term_meta('post_tag', 'tokmakov_meta_description', []);
});
/*
 * 2.1. Добавляем два textarea для формы добавления новой категории
 */
add_action('category_add_form_fields', function () {
    ?>
    <div id="tokmakov-meta-tags-term" style="margin-bottom: 20px;">
        <fieldset>
            <legend>Мета-теги для SEO</legend>
            <label for="tokmakov-meta-keywords">Мета-тег keywords</label>
            <textarea name="tokmakov_meta_keywords"
                      id="tokmakov-meta-keywords"></textarea>
            <label for="tokmakov-meta-description">Мета-тег description</label>
            <textarea name="tokmakov_meta_description"
                      id="tokmakov-meta-description"></textarea>
        </fieldset>
        <input type="hidden" name="tokmakov_meta_hidden" value="1" />
    </div>
    <?php
});
/*
 * 2.2. Добавляем два textarea для формы редактирования существующей категории
 */
add_action('category_edit_form_fields', function ($term) {
    $keywords = '';
    $description = '';
    $meta = get_term_meta(
        $term->term_id,
        'tokmakov_meta_tags',
        true
    );
    if (!empty($meta['keywords'])) {
        $keywords = $meta['keywords'];
    }
    if (!empty($meta['description'])) {
        $description = $meta['description'];
    }
    ?>
    <tr class="form-field">
        <td></td>
        <td>
            <div id="tokmakov-meta-tags-term">
                <fieldset>
                    <legend>Мета-теги для SEO</legend>
                    <label for="tokmakov-meta-keywords">Мета-тег keywords</label>
                    <textarea
                        name="tokmakov_meta_keywords"
                        id="tokmakov-meta-keywords"><?= esc_attr($keywords); ?></textarea>
                    <label for="tokmakov-meta-description">Мета-тег description</label>
                    <textarea
                        name="tokmakov_meta_description"
                        id="tokmakov-meta-description"><?= esc_attr($description); ?></textarea>
                </fieldset>
                <input type="hidden" name="tokmakov_meta_hidden" value="1" />
            </div>
        </td>
    </tr>
    <?php
});
/*
 * 2.3. Добавляем два textarea для формы добавления новой метки
 */
add_action('post_tag_add_form_fields', function () {
    ?>
    <div id="tokmakov-meta-tags-term" style="margin-bottom: 20px;">
        <fieldset>
            <legend>Мета-теги для SEO</legend>
            <label for="tokmakov-meta-keywords">Мета-тег keywords</label>
            <textarea name="tokmakov_meta_keywords"
                      id="tokmakov-meta-keywords"></textarea>
            <label for="tokmakov-meta-description">Мета-тег description</label>
            <textarea name="tokmakov_meta_description"
                      id="tokmakov-meta-description"></textarea>
        </fieldset>
        <input type="hidden" name="tokmakov_meta_hidden" value="1" />
    </div>
    </td>
    <?php
});
/*
 * 2.4. Добавляем два textarea для формы редактирования существующей метки
 */
add_action('post_tag_edit_form_fields', function ($term) {
    $keywords = '';
    $description = '';
    $meta = get_term_meta(
        $term->term_id,
        'tokmakov_meta_tags',
        true
    );
    if (!empty($meta['keywords'])) {
        $keywords = $meta['keywords'];
    }
    if (!empty($meta['description'])) {
        $description = $meta['description'];
    }
    ?>
    <tr class="form-field">
        <td></td>
        <td>
            <div id="tokmakov-meta-tags-term">
                <fieldset>
                    <legend>Мета-теги для SEO</legend>
                    <label for="tokmakov-meta-keywords">Мета-тег keywords</label>
                    <textarea
                        name="tokmakov_meta_keywords"
                        id="tokmakov-meta-keywords"><?= esc_attr($keywords); ?></textarea>
                    <label for="tokmakov-meta-description">Мета-тег description</label>
                    <textarea
                        name="tokmakov_meta_description"
                        id="tokmakov-meta-description"><?= esc_attr($description); ?></textarea>
                </fieldset>
                <input type="hidden" name="tokmakov_meta_hidden" value="1" />
            </div>
        </td>
    </tr>
    <?php
});
/*
 * 3.1. Назначаем обработчики событий добавления и обновления рубрики
 *      или метки
 */
add_action('create_category', 'tokmakov_save_term_meta');
add_action('edited_category', 'tokmakov_save_term_meta');
add_action('create_post_tag', 'tokmakov_save_term_meta');
add_action('edited_post_tag', 'tokmakov_save_term_meta');
/*
 * 3.2. Сохраняем в базу данных значения мета-тегов при добавлении или
 *      обновлении рубрики или метки
 */
function tokmakov_save_term_meta($term_id) {

    // проверяем права пользователя
    if (!current_user_can('edit_term', $term_id)) {
        return;
    }
    // только при отправке формы, которую мы изменили
    if (!isset($_POST['tokmakov_meta_hidden'])) {
        return;
    }

    $data = [
        'keywords' => '',
        'description' => ''
    ];
    if (isset($_POST['tokmakov_meta_keywords'])) {
        $keywords = iconv_substr(
            $_POST['tokmakov_meta_keywords'],
            0,
            200
        );
        $data['keywords'] = sanitize_text_field($keywords);
    }
    if (isset($_POST['tokmakov_meta_description'])) {
        $description = iconv_substr(
            $_POST['tokmakov_meta_description'],
            0,
            200
        );
        $data['description'] = sanitize_text_field($description);
    }

    if (empty($data['keywords']) && empty($data['description'])) {
        // нет смысла хранить пустые строки, поэтому удаляем
        delete_term_meta(
            $term_id,
            'tokmakov_meta_tags'
        );
    } else {
        update_term_meta(
            $term_id,
            'tokmakov_meta_tags',
            $data
        );
    }
}
/*
 * 4. Добавляем метабокс на страницу редактирования поста блога или страницы
 */
add_action('add_meta_boxes', function () {
    add_meta_box(
        'tokmakov-meta-tags-post',
        'Мета-теги для SEO',
        function ($post) {
            $keywords =  '';
            $description = '';
            $meta = get_post_meta($post->ID, 'tokmakov_meta_tags', true);
            if (!empty($meta)) {
                $keywords = $meta['keywords'];
                $description = $meta['description'];
            }
            ?>
                <label for="tokmakov-meta-keywords">Мета-тег keywords</label>
                <textarea
                    name="tokmakov_meta_keywords"
                    id="tokmakov-meta-keywords"><?= esc_attr($keywords); ?></textarea>
                <label for="tokmakov-meta-description">Мета-тег description</label>
                <textarea
                    name="tokmakov_meta_description"
                    id="tokmakov-meta-description"><?= esc_attr($description); ?></textarea>
                <input type="hidden" name="tokmakov_meta_hidden" value="1" />
            <?php
        },
        ['post', 'page'],
        'normal',
        'high'
    );
});
/*
 * 5. Сохраняем данные из формы добавления-редактирования поста или страницы
 */
add_action('save_post', function ($post_id) {

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

    /*
     * Все хорошо, сохраняем данные метабокса
     */
    $data = [
        'keywords' => '',
        'description' => ''
    ];
    if (isset($_POST['tokmakov_meta_keywords'])) {
        $keywords = iconv_substr(
            $_POST['tokmakov_meta_keywords'],
            0,
            200
        );
        $data['keywords'] = sanitize_text_field($keywords);
    }
    if (isset($_POST['tokmakov_meta_description'])) {
        $description = iconv_substr(
            $_POST['tokmakov_meta_description'],
            0,
            200
        );
        $data['description'] = sanitize_text_field($description);
    }

    if (empty($data['keywords']) && empty($data['description'])) {
        // нет смысла хранить пустые строки, поэтому удаляем
        delete_post_meta($post_id, 'tokmakov_meta_tags');
    } else {
        update_post_meta($post_id, 'tokmakov_meta_tags', $data);
    }
});
/*
 * Подключаем файл стилей для панели управления, чтобы оформить наши textarea
 */
add_action('admin_enqueue_scripts', function () {
    wp_enqueue_style(
        'tokmakov-meta-tags',
        plugin_dir_url(__FILE__) . 'style.css'
    );
});
/*
 * Оформление для формы редактирования постов блога и страниц
 */
#tokmakov-meta-tags-post {
    border: 1px solid #ccf;
    background: #f5f5ff;
}
    #tokmakov-meta-tags-post h2 {
        color: #99f;
        border-bottom: 1px solid #ccf;
    }
        #tokmakov-meta-tags-post label {
            color: #99f;
            display: block;
            margin: 10px 0 5px 0;
        }
        #tokmakov-meta-tags-post textarea {
            display: block;
            color: #999;
            border: 1px solid #ccf;
            width: 100%;
        }

/*
 * Оформление для формы добавления и редактирования рубрик и меток
 */
#tokmakov-meta-tags-term {
    width: 95%;
}
    #tokmakov-meta-tags-term fieldset {
        display: block;
        box-sizing: border-box;
        border: 1px solid #ccf;
        padding: 5px 10px 10px 10px;
        background: #f5f5ff;
    }
        #tokmakov-meta-tags-term fieldset legend {
            color: #99f;
            border: 1px solid #ccf;
            padding: 0 12px 2px 12px;
            border-radius: 10px;
            background: #fff;
        }
        #tokmakov-meta-tags-term fieldset label {
            color: #99f;
        }
        #tokmakov-meta-tags-term fieldset textarea {
            color: #999;
            border: 1px solid #ccf;
            width: 100%;
        }
/*
 * 6. Добавляем мета-теги keywords и description в публичной части
 *    сайта для рубрики или метки
 */
add_action(
    'wp_head',
    function () {
        if (is_category() || is_tag()) {
            $temp = 'cat';
            if (is_tag()) {
                $temp = 'tag_id';
            }
            $id = get_query_var($temp);
            $meta = get_term_meta($id, 'tokmakov_meta_tags', true);
            if (!empty($meta['keywords'])) {
                ?>
                <meta name="keywords" content="<?= esc_attr($meta['keywords']); ?>" />
                <?php
            }
            if (!empty($meta['description'])) {
                ?>
                <meta name="description" content="<?= esc_attr($meta['description']); ?>" />
                <?php
            }
        }
    },
    1
);
/*
 * 7. Добавляем мета-теги keywords и description в публичной части
 *    сайта для записи блога или страницы
 */
add_action(
    'wp_head',
    function () {
        global $post;
        if (is_page() || is_singular('post')) {
            $meta = get_post_meta($post->ID, 'tokmakov_meta_tags', true);
            if (!empty($meta['keywords'])) {
                ?>
                <meta name="keywords" content="<?= esc_attr($meta['keywords']); ?>" />
                <?php
            }
            if (!empty($meta['description'])) {
                ?>
                <meta name="description" content="<?= esc_attr($meta['description']); ?>" />
                <?php
            }
        }
    },
    1
);

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

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

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

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

Поиск: CMS • SEO • 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.