/ Wordpress / Поле Иконка + подпись

Поле Иконка + подпись

07.02.2026

46

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

Реализация в виде функций

// Регистрируем метабокс
function register_custom_pairs_meta_box() {
    add_meta_box(
        'custom_pairs_meta_box',
        'Пары (иконка + текст)',
        'custom_pairs_metabox_callback',
        array('post', 'page'),
        'normal',
        'high'
    );
}
add_action('add_meta_boxes', 'register_custom_pairs_meta_box');

// Вывод метабокса
function custom_pairs_metabox_callback( $post ) {
    wp_nonce_field( basename( __FILE__ ), 'custom_pairs_nonce' );
    
    // Получаем сохранённые данные
    $custom_pairs = get_post_meta( $post->ID, '_custom_pairs', true );
    if ( ! is_array( $custom_pairs ) ) {
        $custom_pairs = array(); // Пусть пока массив пуст
    }
    ?>
    <table id="custom-pairs-table" style="width:100%; border-collapse: collapse;">
        <thead>
            <tr>
                <th>Наименование (русское)</th>
                <th>Наименование (латинское)</th>
                <th></th>
            </tr>
        </thead>
        <tbody>
        <?php
        // Если есть сохранённые пары, выводим их
        if ( ! empty( $custom_pairs ) ) {
            foreach ( $custom_pairs as $index => $pair ) {
                $name = isset( $pair['name'] ) ? esc_attr( $pair['name'] ) : '';
                $latin_name = isset( $pair['latin_name'] ) ? esc_attr( $pair['latin_name'] ) : '';
                ?>
                <tr>
                    <td><input type="text" name="custom_pairs[<?php echo $index; ?>][name]" value="<?php echo $name; ?>" style="width:100%;"></td>
                    <td><input type="text" name="custom_pairs[<?php echo $index; ?>][latin_name]" value="<?php echo $latin_name; ?>" style="width:100%;"></td>
                    <td class="actions">
						<!-- <button type="button" class="move-up">↑</button> -->
						<!-- <button type="button" class="move-down">↓</button> -->
						<!-- <button type="button" class="delete-btn">Удалить</button> -->
					</td>
                </tr>
                <?php
            }
        }
        ?>
        </tbody>
    </table>
    <button type="button" id="add-row">Добавить пару</button>

	<script>
	(function($) {
		$(document).ready(function() {

			// Функция обновления стрелок у всех строк
			function updateArrowButtons() {
				$('#custom-pairs-table tbody tr').each(function() {
					var $tr = $(this);
					// Удаляем старые стрелки, чтобы не дублировать
					$tr.find('.move-up, .move-down, .delete-btn').remove();

					// Вставляем кнопки "вверх" и "вниз"
					$('<button type="button" class="move-up">↑</button>').prependTo($tr.find('td.actions'));
					$('<button type="button" class="move-down">↓</button>').appendTo($tr.find('td.actions'));

					// добавляем кнопку Удалить, если её ещё нет
					$('<button type="button" class="delete-btn">Удалить</button>').appendTo($tr.find('td.actions'));
				});
			}

			// Изначально установим стрелки и кнопки
			updateArrowButtons();

			// Обработчик добавления новой строки
			$('#add-row').on('click', function() {
				var index = $('#custom-pairs-table tbody tr').length;
				var newRow = '<tr>' +
					'<td><input type="text" name="custom_pairs[' + index + '][name]" style="width:100%;"></td>' +
					'<td><input type="text" name="custom_pairs[' + index + '][latin_name]" style="width:100%;"></td>' +
					'<td class="actions"></td>' +
					'</tr>';
				$('#custom-pairs-table tbody').append(newRow);
				updateArrowButtons();
			});

			// Обработка удаления
			$('#custom-pairs-table').on('click', '.delete-btn', function() {
				$(this).closest('tr').remove();
				renumberInputs();
				updateArrowButtons();
			});

			// Обработка перемещения вверх
			$('#custom-pairs-table').on('click', '.move-up', function() {
				var row = $(this).closest('tr');
				var prev = row.prev();
				if (prev.length) {
					row.insertBefore(prev);
					renumberInputs();
					updateArrowButtons();
				}
			});

			// Обработка перемещения вниз
			$('#custom-pairs-table').on('click', '.move-down', function() {
				var row = $(this).closest('tr');
				var next = row.next();
				if (next.length) {
					row.insertAfter(next);
					renumberInputs();
					updateArrowButtons();
				}
			});

			// Переименовываем поля при перестановке
			function renumberInputs() {
				$('#custom-pairs-table tbody tr').each(function(index) {
					$(this).find('input[name^="custom_pairs"]').each(function() {
						var nameAttr = $(this).attr('name');
						nameAttr = nameAttr.replace(/custom_pairs$$\d+$$/, 'custom_pairs[' + index + ']');
						$(this).attr('name', nameAttr);
					});
				});
			}

		});
	})(jQuery);
	</script>
    <?php
}

// Сохраняем данные
function save_custom_pairs_meta( $post_id ) {
    if ( ! isset( $_POST['custom_pairs_nonce'] ) || ! wp_verify_nonce( $_POST['custom_pairs_nonce'], basename( __FILE__ ) ) ) {
        return;
    }
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
        return;
    }
    if ( ! current_user_can( 'edit_post', $post_id ) ) {
        return;
    }

    if ( isset( $_POST['custom_pairs'] ) && is_array( $_POST['custom_pairs'] ) ) {
        $custom_pairs = $_POST['custom_pairs'];
        $filtered_pairs = array();

        foreach ( $custom_pairs as $pair ) {
            $name = isset( $pair['name'] ) ? trim( $pair['name'] ) : '';
            $latin_name = isset( $pair['latin_name'] ) ? trim( $pair['latin_name'] ) : '';

            if ( empty( $name ) && empty( $latin_name ) ) {
                continue; // пропускаем пустые
            }

            $filtered_pairs[] = array(
                'name' => $name,
                'latin_name' => $latin_name,
            );
        }

        if ( ! empty( $filtered_pairs ) ) {
            update_post_meta( $post_id, '_custom_pairs', $filtered_pairs );
        } else {
            delete_post_meta( $post_id, '_custom_pairs' );
        }
    } else {
        delete_post_meta( $post_id, '_custom_pairs' );
    }
}
add_action( 'save_post', 'save_custom_pairs_meta' );

Пример, как это выглядит в админке

Вывод данного поля

<?php $pairs = get_post_meta( $post->ID, '_custom_pairs', true );

foreach ($pairs as $index => $pair): ?>

	<div class="item feat" title="<?php echo $pair['name']; ?>"><div>
		<svg xmlns="http://www.w3.org/2000/svg"><use xlink:href="#<?php echo $pair['latin_name']; ?>"></use></svg>
		<p><?php echo $pair['name']; ?></p>
	</div></div>

<?php endforeach; ?>

Иконки подключается в подвале в виде отдельного файла.

[site-socialshare]
  • Комментарии
  • Вложения

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

Notice: Функция WP_Styles::add вызвана неправильно. Стиль с дескриптором "editor-buttons" был поставлен в очередь с незарегистрированными зависимостями: dashicons. Дополнительную информацию можно найти на странице «Отладка в WordPress». (Это сообщение было добавлено в версии 6.9.1.) in /home/t/tiberi6w/opttour.ru/public_html/wp-includes/functions.php on line 6131

Пока нет комментариев. Будь первым!

Поле Иконка + подпись Поле Иконка + подпись
Создаем анимацию Scroll Down
Рекомендации для васСоздаем анимацию Scroll DownOpttour.ru
Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.