В этой статье подробно рассмотрим, как создать в вашей теме WordPress полноценную систему динамических отзывов. Такой функционал полезен для сайтов портфолио, корпоративных сайтов и сервисов, где важно демонстрировать обратную связь клиентов. Мы пройдем весь путь: от создания кастомного типа записей «Отзывы», добавления метаполей для рейтинга и автора, до вывода отзывов на фронтенде с использованием AJAX для динамической подгрузки.
Создание кастомного типа записей «Отзывы» в теме
Первым шагом создадим кастомный тип записей для отзывов. Это позволит удобно управлять отзывами из админки и выводить их отдельно от обычных постов.
Добавьте следующий код в файл functions.php вашей темы:
function wpthemes_register_reviews_cpt() {
$labels = array(
'name' => 'Отзывы',
'singular_name' => 'Отзыв',
'add_new' => 'Добавить отзыв',
'add_new_item' => 'Добавить новый отзыв',
'edit_item' => 'Редактировать отзыв',
'new_item' => 'Новый отзыв',
'view_item' => 'Просмотреть отзыв',
'search_items' => 'Поиск отзывов',
'not_found' => 'Отзывы не найдены',
'not_found_in_trash' => 'В корзине отзывов не найдено',
);
$args = array(
'labels' => $labels,
'public' => true,
'has_archive' => true,
'supports' => array('title', 'editor', 'thumbnail'),
'menu_icon' => 'dashicons-testimonial',
'rewrite' => array('slug' => 'otzyvy'),
);
register_post_type('wpthemes_review', $args);
}
add_action('init', 'wpthemes_register_reviews_cpt');После добавления и обновления сайта в админке появится раздел «Отзывы» с удобным интерфейсом для добавления новых записей.
Добавление метаполей для имени автора и рейтинга
Чтобы отзывы были информативными, добавим два метаполя: имя автора и рейтинг (от 1 до 5). Для этого используем стандартные метабоксы WordPress.
Добавьте в functions.php следующий код для регистрации метабокса и сохранения данных:
function wpthemes_add_review_metabox() {
add_meta_box('wpthemes_review_details', 'Детали отзыва', 'wpthemes_render_review_metabox', 'wpthemes_review', 'normal', 'default');
}
add_action('add_meta_boxes', 'wpthemes_add_review_metabox');
function wpthemes_render_review_metabox($post) {
wp_nonce_field('wpthemes_save_review_meta', 'wpthemes_review_nonce');
$author = get_post_meta($post->ID, '_wpthemes_review_author', true);
$rating = get_post_meta($post->ID, '_wpthemes_review_rating', true);
?>
<p><label for="wpthemes_review_author">Имя автора:</label><br>
<input type="text" id="wpthemes_review_author" name="wpthemes_review_author" value="<?php echo esc_attr($author); ?>" style="width:100%;"></p>
<p><label for="wpthemes_review_rating">Рейтинг (1-5):</label><br>
<select id="wpthemes_review_rating" name="wpthemes_review_rating">
<?php for ($i = 1; $i <= 5; $i++) : ?>
<option value="<?php echo $i; ?>" <?php selected($rating, $i); ?>><?php echo $i; ?></option>
<?php endfor; ?>
</select></p>
<?php
}
function wpthemes_save_review_meta($post_id) {
if (!isset($_POST['wpthemes_review_nonce']) || !wp_verify_nonce($_POST['wpthemes_review_nonce'], 'wpthemes_save_review_meta')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if (isset($_POST['wpthemes_review_author'])) {
update_post_meta($post_id, '_wpthemes_review_author', sanitize_text_field($_POST['wpthemes_review_author']));
}
if (isset($_POST['wpthemes_review_rating'])) {
$rating = intval($_POST['wpthemes_review_rating']);
if ($rating < 1) $rating = 1;
if ($rating > 5) $rating = 5;
update_post_meta($post_id, '_wpthemes_review_rating', $rating);
}
}
add_action('save_post', 'wpthemes_save_review_meta');Теперь при создании или редактировании отзыва появятся поля для заполнения имени автора и рейтинга.
Вывод отзывов в теме с пагинацией
Для фронтенда создадим шаблон вывода отзывов с пагинацией. Добавим функцию, которая будет выводить отзывы с автором и рейтингом, а также навигацию по страницам.
Пример функции для вывода отзывов:
function wpthemes_display_reviews($paged = 1, $posts_per_page = 5) {
$args = array(
'post_type' => 'wpthemes_review',
'posts_per_page' => $posts_per_page,
'paged' => $paged,
'orderby' => 'date',
'order' => 'DESC',
);
$query = new WP_Query($args);
if ($query->have_posts()) {
echo '<div class="wpthemes-reviews">';
while ($query->have_posts()) {
$query->the_post();
$author = get_post_meta(get_the_ID(), '_wpthemes_review_author', true);
$rating = intval(get_post_meta(get_the_ID(), '_wpthemes_review_rating', true));
echo '<div class="wpthemes-review-item">';
echo '<h3>' . get_the_title() . '</h3>';
echo '<div class="wpthemes-review-content">' . get_the_content() . '</div>';
echo '<div class="wpthemes-review-meta">';
echo '<span class="wpthemes-review-author">Автор: ' . esc_html($author) . '</span> | ';
echo '<span class="wpthemes-review-rating">Рейтинг: ' . str_repeat('★', $rating) . str_repeat('☆', 5 - $rating) . '</span>';
echo '</div>';
echo '</div>';
}
echo '</div>';
// Навигация
$big = 999999999; // уникальное число
$pagination = paginate_links(array(
'base' => str_replace($big, '%#%', esc_url(get_pagenum_link($big))),
'format' => '?paged=%#%',
'current' => max(1, $paged),
'total' => $query->max_num_pages,
'type' => 'list',
));
echo $pagination;
} else {
echo '<p>Отзывы не найдены.</p>';
}
wp_reset_postdata();
}В шаблоне темы можно вызвать функцию с нужной страницей, например:
if (get_query_var('paged')) {
$paged = get_query_var('paged');
} elseif (get_query_var('page')) {
$paged = get_query_var('page');
} else {
$paged = 1;
}
wpthemes_display_reviews($paged, 5);Динамическая подгрузка отзывов через AJAX
Для улучшения UX реализуем подгрузку отзывов по кнопке без перезагрузки страницы. Это особенно удобно, если отзывов много.
Добавим скрипт и обработчик AJAX в functions.php:
function wpthemes_enqueue_scripts() {
wp_enqueue_script('wpthemes-reviews-ajax', get_template_directory_uri() . '/js/reviews-ajax.js', array('jquery'), null, true);
wp_localize_script('wpthemes-reviews-ajax', 'wpthemes_ajax_obj', array(
'ajaxurl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wpthemes_ajax_nonce'),
));
}
add_action('wp_enqueue_scripts', 'wpthemes_enqueue_scripts');
function wpthemes_ajax_load_reviews() {
check_ajax_referer('wpthemes_ajax_nonce', 'nonce');
$paged = isset($_POST['paged']) ? intval($_POST['paged']) : 1;
$posts_per_page = 5;
ob_start();
wpthemes_display_reviews($paged, $posts_per_page);
$content = ob_get_clean();
wp_send_json_success(array('content' => $content));
}
add_action('wp_ajax_wpthemes_load_reviews', 'wpthemes_ajax_load_reviews');
add_action('wp_ajax_nopriv_wpthemes_load_reviews', 'wpthemes_ajax_load_reviews');Создайте файл js/reviews-ajax.js в директории темы с таким содержимым:
jQuery(document).ready(function($) {
var paged = 2;
$('#wpthemes-load-more').on('click', function(e) {
e.preventDefault();
$.ajax({
url: wpthemes_ajax_obj.ajaxurl,
type: 'POST',
data: {
action: 'wpthemes_load_reviews',
nonce: wpthemes_ajax_obj.nonce,
paged: paged
},
success: function(response) {
if (response.success) {
if($.trim(response.data.content) !== '') {
$('.wpthemes-reviews').append($(response.data.content).find('.wpthemes-review-item'));
paged++;
} else {
$('#wpthemes-load-more').hide();
}
}
}
});
});
});В шаблоне рядом с выводом отзывов добавьте кнопку:
<button id="wpthemes-load-more">Загрузить ещё отзывы</button>Рекомендации по плагинам и оптимизации
Хотя мы создали базовую систему отзывов самостоятельно, можно расширить возможности с помощью плагинов. Например, Expert Review от WPShop позволяет добавить профессиональные шаблоны отзывов с рейтингами, интеграцию с Gutenberg и кастомизацию внешнего вида.
Для оптимизации загрузки рекомендуем использовать кеширование и минимизировать вывод данных, а также применять lazy load для изображений в отзывах, если добавляете фото клиентов.
Таким образом, вы получите удобный и функциональный блок отзывов, который легко поддерживать и масштабировать под нужды проекта.