Отзывы покупателей на сайте: оценки и модерация
5.0 1 оценка
Отзыв здесь — это заявка отдельной формы, поэтому ему бесплатно достаётся всё, что приложение уже умеет: конструктор полей, защита от спама, капча, вложения и уведомления. Плагин добавляет то, чего у заявки нет: оценку, модерацию, ответ магазина и ленту на витрине.
Поле «Оценка» со звёздами, средний балл и число отзывов над лентой. Пять сортировок: по дате (в обе стороны), по отметкам «Полезно» и по оценке (в обе стороны).
На витрину попадают только опубликованные отзывы. Отклонённый исчезает из ленты, но остаётся в приложении.
Ответ пишется прямо в карточке отзыва и показывается под ним на витрине. Автору уходит письмо о публикации и об ответе.
При редактировании сохранённый текст возвращается в поле, а кнопка «Сохранить ответ» неактивна, пока его не изменят — повторных писем не бывает. К ответу можно приложить файлы (сертификат, фото замены) — они показываются на витрине вместе с ответом. Отзывы с ответом помечены зелёным бэджем «Ответ» прямо в списке заявок.
Микроразметка Schema.org (Review и AggregateRating) — Яндекс и Google показывают рейтинг прямо в выдаче.
Отзывы привязаны к форме, поэтому лент может быть сколько угодно: «Отзывы о магазине», «Отзывы о доставке», «Отзывы о сервисном центре». Каждая — своя форма со своими полями и настройками.
Кроме самих отзывов лента показывает три вещи, которые обычно приходится собирать вручную.
Состояние, оценка, число отметок «Полезно» и поле ответа — всё в одном месте, рядом с самим отзывом.
Карточки отзывов проявляются при прокрутке, кнопка «Полезно» откликается на клик, а фотографии открываются в окне с плавным появлением, аккуратной сменой кадра по стрелкам и свайпом на телефоне — всё это делает сам плагин, без единой строчки в теме. Анимации уважают системную настройку «Уменьшить анимацию» браузера и отключаются целиком одним переключателем в форме, если владельцу сайта они не нужны.
Лента выводится одной строкой в любом месте шаблона или прямо в содержимом страницы — число в скобках это номер формы с отзывами. Проверка {if !empty(...)} ничего не ломает, даже если плагин когда-нибудь выключат или удалят: вызов на несуществующем плагине просто вернёт пустую строку, а не уронит страницу.
{if !empty($wa->requests->sitereviewsPlugin->version())}
{$wa->requests->sitereviewsPlugin->render(3)}
{/if}
{* пять последних, плитками в несколько колонок *}
{$wa->requests->sitereviewsPlugin->render(3, ['limit' => 5, 'layout' => 'cards'])}
{* только средний балл, например в шапке страницы *}
{$wa->requests->sitereviewsPlugin->summary(3)}
Так вызов работает в любой теме — и в витрине магазина, и на страницах сайта: приложение поднимается само, а хелпер находится по тому же принципу, что и хелперы других наших плагинов. Стили и скрипт подключаются автоматически и только один раз, даже если лент на странице несколько.
Если в теме уже стоит прежняя запись {$wa->requests->plugin('sitereviews', 'render', 3)} — она продолжает работать, переписывать её не обязательно. Для новых вставок удобнее хелпер выше: у него есть проверка version() и все методы из примеров ниже.
685 отзывов на одной странице — это долгая загрузка и для посетителя, и для поисковика. Опция paging у render() разбивает ленту на страницы тремя способами — вычисления и запросы плагин берёт на себя, в теме их считать не нужно.
{* Нумерованная навигация: 1 2 3 … 35 *}
{$wa->requests->sitereviewsPlugin->render(3, ['per_page' => 20, 'paging' => 'pages'])}
{* Кнопка «Показать ещё» — обычная ссылка ?page=N+1,
рабочая и без JavaScript *}
{$wa->requests->sitereviewsPlugin->render(3, ['per_page' => 20, 'paging' => 'more'])}
{* То же самое, но следующая страница подгружается
сама при прокрутке к кнопке *}
{$wa->requests->sitereviewsPlugin->render(3, ['per_page' => 20, 'paging' => 'scroll'])}
Без опции paging лента работает как и раньше — короткий список без навигации, для тех случаев, где это и нужно (например, три последних отзыва на главной странице).
Опция filters добавляет над лентой одну кнопку-меню вместо ряда чипсов: подпись показывает текущий выбор — «Все отзывы · Сначала новые», при активном фильтре — «С фото · Сначала высокие». Клик раскрывает список из двух групп: «Показать» (Все отзывы; С фото; С ответом магазина; Положительные 4–5; Отрицательные 1–2; и оценки «5★»…«1★» отдельно — с числом отзывов по каждому пункту) и «Сортировка» (пять значений). Выбор в одной группе не сбрасывает выбор в другой — сменили сортировку, фильтр остался, и наоборот. По каждой оценке отдельно фильтрует и клик по строке гистограммы в шапке — она сочетается с уже выбранными «С фото»/«С ответом», а не заменяет их, в отличие от пункта меню. Меню можно включить и без правки шаблона — настройкой формы на вкладке «Отзывы».
{$wa->requests->sitereviewsPlugin->render(3, ['per_page' => 20, 'paging' => 'more', 'filters' => true])}
Меню — нативные <details>/<summary>: открывается кликом без единой строки JavaScript, пункты — обычные ссылки вида ?with_photos=1, поэтому меню работает и без скрипта, и его видит поисковик. Со скриптом клик закрывает меню, подгружает страницу без перезагрузки, обновляет подпись кнопки и поддерживает стрелки ↑/↓ и Escape. На узком экране меню становится нижним листом на весь экран. Комбинация без единого совпадения показывает «Нет отзывов с такими условиями» и ссылку «Сбросить фильтры» вместо пустоты.
Своя вёрстка — те же фильтры опциями items()/paging(), например «только отзывы с фото, лучшие сначала»:
{foreach $wa->requests->sitereviewsPlugin->items(3, ['with_photos' => true, 'sort' => 'rating_desc']) as $review}
{$review.author} — {$review.rating} из 5
{$review.text}
{/foreach}
{* только оценка 5, только с ответом магазина *}
{$wa->requests->sitereviewsPlugin->render(3, ['rating' => 5, 'with_answer' => true])}
Если стандартный блок не вписывается в макет, плагин отдаст готовые массивы, а разметку напишете сами — например, чтобы показать три отзыва на главной странице.
{assign var=reviews value=$wa->requests->sitereviewsPlugin->items(3, ['limit' => 3])}
{foreach $reviews as $review}
{$review.author} — {$review.rating} из 5
{$review.text}
{/foreach}
{* текст отзыва может лежать в нескольких полях формы —
«Достоинства», «Недостатки», «Комментарий»; $review.text — все они
одной строкой (как в примере выше), $review.text_parts — те же
части по отдельности, с подписью поля *}
{foreach $review.text_parts as $part}
{$part.label}: {$part.text}
{/foreach}
{assign var=stats value=$wa->requests->sitereviewsPlugin->stats(3)}
{$stats.average_human} из 5, отзывов: {$stats.count}
{* items() тоже принимает постраничный вывод — page и per_page.
paging() отдаёт номера страниц отдельно, без повторного
вывода отзывов — удобно поверх собственной вёрстки *}
{assign var=reviews value=$wa->requests->sitereviewsPlugin->items(3, ['page' => 2, 'per_page' => 20])}
{assign var=paging value=$wa->requests->sitereviewsPlugin->paging(3, ['page' => 2, 'per_page' => 20])}
Страница {$paging.page} из {$paging.pages}
В отзыве уже подготовлены инициалы для аватара, человеческая дата, признак покупателя, число отметок «полезно», ответ магазина и ссылки на фотографии. В сводке — средний балл и распределение оценок по звёздам для гистограммы.
Просмотр фотографий в окне — часть плагина, а не стандартного блока: подключите стили и скрипт методом assets() и оставьте на ссылке класс requests-reviews__file — дальше плагин всё делает сам, свой JavaScript в теме не нужен. Без JS ссылка ведёт прямо на файл.
{$wa->requests->sitereviewsPlugin->assets()}
{foreach $wa->requests->sitereviewsPlugin->items(3, ['limit' => 6]) as $review}
<div class="my-review" data-requests-reviews-gallery>
{$review.author} — {$review.rating} из 5
{$review.text}
{foreach $review.files as $file}
<a class="requests-reviews__file" href="{$file.url|escape}">
<img src="{$file.url|escape}" alt="{$file.name|escape}" loading="lazy">
</a>
{/foreach}
</div>
{/foreach}
Атрибут data-requests-reviews-gallery на обёртке одного отзыва — чтобы стрелки «предыдущая / следующая» листали фото именно этого отзыва, а не всех фото на странице разом. Без обёртки окно всё равно открывается, просто без стрелок.
Стандартный шаблон лежит в плагине, но тема важнее: положите в её корень файл sitereviews_plugin.reviews.html — и ленту отзывов (шапку со сводкой и список) будет рисовать он. Внутри обычный Smarty и подготовленные переменные, список которых есть в шапке исходного шаблона.
Разметка одного отзыва вынесена отдельно — файл sitereviews_plugin.reviews_items.html. Переопределите его, если нужна только своя карточка отзыва: тот же файл используется и для страницы, дозагружаемой кнопкой «Показать ещё», поэтому новые отзывы получат ту же карточку, без лишней правки.
Откат — просто удалите файл из темы: плагин снова возьмёт свой шаблон. Обновление плагина вашу вёрстку не затирает, потому что она лежит в теме, а не в его файлах.
Раздел «Мои отзывы» — покупатель видит все свои отзывы: опубликованные, на проверке и (по настройке) отклонённые нейтральным «Не опубликован», с ответом магазина и фотографиями, — и может оставить новый через всплывающую форму, без перехода на отдельную страницу. «Свои» — все отзывы с привязкой к контакту покупателя, включая перенесённые и подобранные по email или телефону в редакторе заявки, а не только оставленные лично на этой витрине.
Раздел выключен по умолчанию — без поддержки темы ссылка вела бы в никуда. Включается на общей странице настроек плагина:
В теме Seller 2 раздел работает сразу после включения настройки: пункт «Мои отзывы» появляется в меню личного кабинета, страница — по адресу /my/profile/?view=reviews.
Для любой другой темы дизайна нужен один вызов на странице личного кабинета покупателя — тем же способом, каким выводится лента:
{if !empty($wa->requests->sitereviewsPlugin->version())}
{$wa->requests->sitereviewsPlugin->myReviews()}
{/if}
Пункт меню в тему добавляется автоматически, если она поддерживает стандартное событие Webasyst frontend_my_nav (как темы Shop-Script по умолчанию). Гость, открывший страницу, увидит не пустоту, а приглашение войти со ссылкой на вход.
Как и у ленты — готовые массивы вместо готового HTML, а также адрес и число отзывов для своей плитки или пункта меню:
{assign var=reviews value=$wa->requests->sitereviewsPlugin->myItems(['limit' => 10])}
{foreach $reviews as $review}
{$review.form_name}: {$review.author} — {$review.state_label}
{$review.text}
{/foreach}
{* адрес страницы и число отзывов — для своей плитки на главной ЛК *}
{$wa->requests->sitereviewsPlugin->myUrl()}
{$wa->requests->sitereviewsPlugin->myCount()}
state_label — «Опубликован», «На проверке» или «Не опубликован»: формулировка для покупателя, а не служебные термины модерации из карточки заявки. У опубликованного отзыва в стандартной странице плашки нет вовсе — только у тех, что ещё проверяются или не прошли проверку.
Как и вывод ленты — файлом в корне активной темы. sitereviews_plugin.my_reviews.html переопределяет страницу целиком, sitereviews_plugin.my_nav.html — только пункт меню (обычная ссылка, без обёртки списка — подставляется в готовую разметку темы).
Если на сайте стоит приложение MCP, плагин добавляет в него три инструмента — с ними Claude, Cursor или свой скрипт ведут модерацию так же, как вы в карточке заявки:
Чтение и запись выдаются токену MCP отдельными правами. Без приложения MCP плагин работает как обычно — инструменты просто не появляются.
Узнавайте первыми о наших новых решениях и акциях.
Добавляйте и выводите изображения без ограничений
7 дней бесплатно
Кампании, статистика и бюджеты VK Рекламы для ИИ
7 дней бесплатно
Позиции сайта, конкуренты и выдача для ИИ-агента
7 дней бесплатно
Поля в оформлении заказа: условия, маски, проверка
7 дней бесплатно
Чекбоксы в корзине, заказ из выбранных товаров
7 дней бесплатно
Позволяет загружать видео в настройках товара
7 дней бесплатно
Добавляйте и выводите изображения без ограничений
7 дней бесплатно
Добавляет в массив товаров дополнительные данные
7 дней бесплатно
Вывод последних постов из сообществ ВКонтакте
7 дней бесплатно
Синхронизация заказов, контактов, товаров и другое
7 дней бесплатно