Как создать общее произвольное поле для записей

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

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

Возможно где-то похожее уже реализовано, но я ничего подобного не видел. И ничего не найдя пришлось делать самому.

За основу взят код с сайта wp-kama.ru.

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

I. Создаём 3 дополнительных произвольных поля

В первом поле (mainPostId) будет содержаться ID записи, в котором будем хранить общие данные. Для этой цели (для общих данных) можно использовать ID первой записи.

Второе поле (fieldBelongOtherPost) будет показываться в том случае, когда заполнено первое поле – mainPostId. Это необходимо, чтобы случайно не перезаписать данные основного поста, когда содержимое на страницу ещё не передаётся. Если этого не сделать, можно перезаписать основной пост пустыми данными.

Третье поле (fieldCurrentPost) будет показывать содержимое текущего поста. На тот случай, если это главная запись. Или мы захотим сделать её главной.

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

Код для создания произвольных полей:

function my_extra_fields() {

add_meta_box(
    'mainPostId',
    'Id главной записи',
    'mainPostId', 'post', 'normal', 'low'
);

global $post;
$mainPostId = get_post_meta($post->ID, 'main_post_id', true);

if ($mainPostId) {
    add_meta_box(
        'fieldBelongOtherPost',
        'Содержимое из полей главной записи',
        'fieldBelongOtherPost', 'post', 'normal', 'low'
    );
} else {
    add_meta_box(
        'fieldCurrentPost',
        'Содержимое текущей записи',
        'fieldCurrentPost', 'post', 'normal', 'low'
    );
}

}
add_action('add_meta_boxes', 'my_extra_fields', 1);

II. Подключение произвольных полей

Далее, в этом же файле ниже, подключаем стили. Это можно сделать как через php файл, так и вынести отдельно в css. У меня это сделано через php, потому что изначально все было в одном файле, пока серьёзно не разрослось. И некогда было всё это переносить в отдельный css файл.

include('custom-fields/styles.php');

Теперь подключаем основной файл с произвольным полем:

include('custom-fields/similar.php');

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

Ну и собственно сам код:

<?php
function mainPostId($post) {
    global $post;
    $mainPostId = get_post_meta($post->ID, 'main_post_id', true);
    ?>

    <div class="box-row">
        <div class="row-1">
            <label for="main_post_id">ID главной записи
                <?php if ($mainPostId) { ?>
                    – <a target="_blank"
                         href="<?php echo esc_url(home_url()); ?>/wp-admin/post.php?post=<?php
                         echo $mainPostId ?>&action=edit">
                        <?php echo get_the_title($mainPostId); ?>
                    </a>
                <?php } ?>
            </label>
        </div>
        <div class="row-2">
            <input type="text" id="main_post_id" name="extra[main_post_id]"
                   value="<?php echo get_post_meta($post->ID, 'main_post_id', 1); ?>"
            >
        </div>
    </div>

    <input type="hidden" name="extra_fields_nonce" value="<?php echo wp_create_nonce('mcf'); ?>" />
    <?php
}


/* = Данные из главной записи
--------------------------------------- */

function fieldBelongOtherPost($post){
    global $post;
    $mainPostId = get_post_meta($post->ID, 'main_post_id', true);
    ?>

    <div class="box-textarea">
        <div class="textarea-1"><label for="commonData2">Основная линия</label></div>
        <?php

        // Выводим содержимое этого поста
        wp_editor(get_post_meta($mainPostId, 'common_data', 1), 'commonData2',
            [
                'textarea_name' => 'for_main_post[common_data]',
                'media_buttons' => 0,
                'textarea_rows' => 5,
                'editor_class'  => 'editor-class',
                'drag_drop_upload' => false,
                'quicktags'     => [
                    'buttons' => 'link'
                ],
            ]);
        ?>
    </div>

    <input type="hidden" name="for_main_post_fields_nonce" value="<?php echo wp_create_nonce('mcf'); ?>" />
    <?php
}


/* = Данные текущей записи
--------------------------------------- */

function fieldCurrentPost($post) {
    ?>

    <div class="box-textarea">
        <div class="textarea-1"><label for="commonData">Основная информация</label></div>
        <?php
        wp_editor(get_post_meta($post->ID, 'common_data', 1), 'commonData',
            [
                'textarea_name' => 'extra[common_data]',
                'media_buttons' => 0,
                'textarea_rows' => 5,
                'editor_class'  => 'editor-class',
                'drag_drop_upload' => false,
                'quicktags'     => [
                    'buttons' => 'link'
                ],
            ]);
        ?>
    </div>

    <input type="hidden" name="extra_fields_nonce" value="<?php echo wp_create_nonce('mcf'); ?>" />
    <?php
}

Вот как общие поля выглядят в админке:

III. Функционал для сохранения данных их произвольных полей

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

/* = Сохранение полей для текущей записи
--------------------------------------- */

function my_extra_fields_update($currentPostId){

    // Проверяем есть ли nonce
    if (!isset($_POST['extra_fields_nonce'])) return false;

    // Выключил. Не работает при include файла.
    // if (!wp_verify_nonce($_POST['my_extra_fields'], 'mcf')) return false;

    // Отменяем для автосохранения
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return false;

    // Проверяем имеет ли юзер право редактировать ГЛАВНУЮ запись
    if (!current_user_can('edit_post', $currentPostId)) return false;

    // Проверяем есть ли отправляемые значения
    if (!isset($_POST['extra'])) return false;

    // Все ОК! Теперь, нужно сохранить/удалить данные
    $_POST['extra'] = array_map('trim', $_POST['extra']);

    foreach($_POST['extra'] as $k => $v){

        // Удаляем поле если значение пустое
        if(empty($v)){
            delete_post_meta($currentPostId, $k);
            continue;
        }
        update_post_meta($currentPostId, $k, $v); // add_post_meta() работает автоматически
    }
    return $currentPostId;
}
add_action('save_post', 'my_extra_fields_update', 0);


/* = Сохранении полей для ВНЕШНЕЙ (другой) записи
--------------------------------------- */

function update_post_meta_for_main_post($currentPostId){

    // Получаем ID главного поста (если оно заполнено на странице)
    global $post;
    $mainPostId = get_post_meta($post->ID, 'movie_series_id', true);

    // Проверяем есть ли nonce
    if (!isset($_POST['for_main_post_fields_nonce'])) return false;

    // Выключил. Не работает при include файла.
    // if (!wp_verify_nonce($_POST['for_main_post_fields_nonce'], 'mcf')) return false;

    // Отменяем для автосохранения
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return false;

    // Проверяем имеет ли юзер право редактировать ГЛАВНУЮ запись
    if (!current_user_can('edit_post', $mainPostId)) return false;

    // Проверяем есть ли отправляемые значения
    if (!isset($_POST['for_main_post'])) return false;

    // Все ОК! Теперь, нужно сохранить/удалить данные
    $_POST['for_main_post'] = array_map('trim', $_POST['for_main_post']);

    foreach($_POST['for_main_post'] as $k => $v){

        // Удаляем поле если значение пустое
        if (empty($v)){
            delete_post_meta($mainPostId, $k);
            continue;
        }
        update_post_meta($mainPostId, $k, $v); // add_post_meta() работает автоматически
    }
    return $currentPostId;
}
add_action('save_post', 'update_post_meta_for_main_post', 0);

IV. Выводим общее содержимое на странице single

Теперь всё готово. Осталось вывести данные на странице записей:

<?php

// Получаем в переменную ID главной записи
$mainPostId = get_post_meta($post->ID, 'main_post_id_id', true);

// Вывод содержимого главной записи
if ($mainPostId) {
    ?>

    <section class="signle-section">
        <h3 class="title-section"><?php echo __( 'Общие данные', 'ploshadka' ); ?></h3>
       
        <?php if (get_post_meta($mainPostId, 'main_post_id', true) ) : ?>
            <div class="ploshadka.net">
                <?php echo get_post_meta($mainPostId, 'main_post_id', true); ?>
            </div>
        <?php endif; ?>
    </section>


<?php
    // Вывод содержимого текущей записи
    } elseif (get_post_meta($post->ID, 'main_post_id', true) ) { ?>

    <section class="signle-section">
        <h3 class="title-section"><?php echo __( 'Общие данные', 'ploshadka' ); ?></h3>

        <?php if (get_post_meta($post->ID, 'main_post_id', true) ) : ?>
            <div class="ploshadka.net">
                <?php echo get_post_meta($post->ID, 'main_post_id', true); ?>
            </div>
        <?php endif; ?>
    </section>
<?php } ?>

Привет. Ты находишься на моём сайте. Я разработчик. Здесь я делюсь своими наработками и знаниями. Спрашивай в комментариях, если тебе что-то не понятно или пиши, если есть что добавить.

Если вам пригодилась информация, вы можете поблагодарить автора сайта символическим пожертвованием:

Добавить комментарий

Напишите свой комментарий, если вам есть что добавить/поправить/спросить по теме текущей статьи: "Как создать общее произвольное поле для записей"
Если вам нужно добавить участок кода ставьте его между тегами <code></code>