Перейти к содержанию

Справочный центр и портал

Клиентский портал — место, где люди, которым вы помогаете, следят за своими обращениями на вашем сайте: список их обращений, каждая переписка, поле ответа и кнопки, чтобы отметить обращение решённым или открыть его снова. Справочный центр — его входная дверь. Эта страница описывает настройку обоих, то, что видят клиенты, и то, как вписать их в вашу тему.

Клиенты видят заявку под названием «request» («обращение») и статус своими словами, никогда ваши внутренние названия статусов. Ниже {mount} — маршрут справочного центра, обычно /help.

Настройка справочного центра

  1. В Admin Next добавьте страницу и выберите тип Help Center (шаблон helpdesk).
  2. Дайте ей заголовок (например, «Help») и короткий приветственный текст. Текст показывается вверху справочного центра.
  3. Опубликуйте её.

Маршрут страницы становится адресом справочного центра, и каждая страница портала живёт под ним.

Helpdesk Pro находит страницу по шаблону, а не по маршруту. Сначала он смотрит на маршрут в portal.route, затем, если там ничто не использует шаблон helpdesk, один раз сканирует сайт и запоминает первую найденную страницу Help Center (кэшируется до изменения страниц). Без страницы Help Center портал всё равно работает по portal.route (по умолчанию /help) внутри страницы-заглушки, где нечего редактировать, кроме приветственного текста.

Адрес, на котором он остановился, также хранится в базе данных, поэтому ссылки в письмах, отправляемых фоновым процессом, ведут куда нужно.

Статьи базы знаний могут быть дочерними страницами справочного центра (/help/getting-started/reset-password). Портал занимает только свои пути, перечисленные в разделе Маршруты; любой другой путь под справочным центром — обычная страница Grav.

Добавление Help в меню сайта

Портал живёт по маршруту, поэтому меню темы (которое перечисляет страницы) не показывает его само по себе. Дайте справочному центру настоящую страницу:

  1. Добавьте страницу верхнего уровня, например user/pages/04.help/helpdesk.md (шаблон helpdesk), с title: Help или выберите Help Center в Admin Next.
  2. Нумерованная папка видна в меню, поэтому тема перечисляет Help как любую другую страницу.

Каждая страница портала под ней считается дочерней страницей этой страницы, поэтому темы, подсвечивающие текущий раздел, оставляют Help подсвеченным. Ссылки в меню в других местах могут указывать на любую страницу портала через helpdesk_url(), например {{ helpdesk_url('list') }} для My requests.

Главная справочного центра

{mount}/ устроена так, как люди ищут помощь: сначала проверяют статьи, затем спрашивают. Сверху вниз под строкой навигации:

  • широкий блок с «How can we help?», вашим приветственным текстом одной строкой и большим полем поиска;
  • для вошедшего человека — Your requests: три его последних активных обращения и See all;
  • Browse by topic: карточка на каждую категорию базы знаний с её значком, описанием и числом статей, и Browse all articles (см. Базу знаний);
  • Popular articles;
  • блок «Still need help?» с Contact us, который открывает форму нового обращения, и ссылкой для входа для посетителей без входа.

Строка навигации

Каждая страница портала и каждая справочная статья начинается с одной тихой строки ссылок под шапкой вашей темы: Help center, Articles, My requests (и My organization для участников организации, которая делится обращениями) и Contact us, а справа — имя вошедшего человека с Sign out или Sign in. Когда некоторые из его открытых обращений ждут его ответа, My requests показывает сколько. На телефоне ссылки остаются в одну строку и прокручиваются вбок.

Sign out — ссылка выхода плагина Login. Куда попадает человек, зависит от route_after_logout плагина Login (по умолчанию главная сайта) или от главной справочного центра, когда его redirect_after_logout выключен. Sign in несёт страницу, на которой нажали ссылку, поэтому после входа человек возвращается на неё.

Чтобы разместить строку самостоятельно, например внутри шапки темы, установите portal.nav в false (Help Center → Nav Row на странице настроек) и вызовите {{ helpdesk_nav() }} там, где нужно.

Вход

Каждая страница портала, кроме главной справочного центра и формы нового обращения, требует вошедшую учётную запись Grav. Посетитель без входа получает форму входа вместо страницы («Sign in to continue»): одно поле электронной почты и Email me a link, которая отправляет ссылку для входа и не требует пароля, а также «Have a password? Sign in with it» для тех, у кого он есть. В любом случае человек возвращается на страницу, которую запрашивал. Страница одинакова, существует обращение или нет, поэтому ничего не выдаёт.

Собственная страница входа портала — {mount}/login. Клиентам нужна включённая учётная запись с доступом к входу на сайт (access.site.login: true); им не нужно право администратора или helpdesk-pro.*. При выключенном portal.magic_links страница вместо этого указывает на страницу входа плагина Login.

Клиентов добавляют в группы Grav, перечисленные в portal.client_groups (Client Groups на вкладке Portal & Access страницы настроек, где вы выбираете из групп сайта; по умолчанию пусто). Клиента добавляют при входе или открытии справочного центра, создал ли Helpdesk Pro его учётную запись из присланной ссылки для входа или она у него уже была. Группы только добавляются. Helpdesk Pro помнит, какие настроенные группы он уже выдал учётной записи, поэтому клиент, которого вы убрали из группы, остаётся вне её, а группа, добавленная в настройку позже, доходит до существующих клиентов при следующем визите. Группа, которой нет, или группа, дающая доступ к админке или рабочей области (admin.*, api.access, любая helpdesk-pro.*), пропускается для клиентов, и в журнал пишется предупреждение, поэтому группа клиентов никогда не сделает клиента сотрудником. Сотрудников, отключённые учётные записи и покупателей магазина KahunaCart (у них свои группы покупателей, см. ниже) не трогают. Создавайте группы в Accounts → Groups в Admin Next.

Покупатели магазина. Если ваш магазин работает на KahunaCart, покупателя магазина, который также является клиентом службы поддержки, можно добавить в группы покупателей KahunaCart через portal.client_store_groups (Client Store Groups на той же вкладке, где вы выбираете из групп покупателей KahunaCart; по умолчанию пусто, и настройка появляется, только когда KahunaCart установлен и включён). Это работает не так, как Client Groups: в учётной записи ничего не сохраняется. Когда KahunaCart спрашивает, в каких группах покупателей состоит покупатель, Helpdesk Pro добавляет выбранные вами, если этот покупатель — активный клиент службы поддержки, с причиной «Helpdesk Pro client» везде, где KahunaCart перечисляет выданные им группы. Группа следует за человеком: она исчезает, когда человека отвязывают от учётной записи, блокируют или удаляют, а удаление группы из настройки убирает её у всех при следующем запросе. Сотрудники её никогда не получают. Группа покупателей в KahunaCart — больше, чем метка. Она даёт покупателю право на страницу site.customer_group.<code>, поэтому страницы, требующие эту группу, открываются для него, и может принести групповые цены, скидки и любые правила купонов, доставки или товаров, которые ваш магазин построил на этой группе. Выбирайте группы с этим в виду. Покупатель магазина считается клиентом, когда его учётная запись связана с человеком-клиентом, включая покупателя, чью запись забрала обычная учётная запись Grav. Код группы, которого KahunaCart не знает, игнорируется. Сайт с пустой настройкой ничего за неё не платит.

Ссылка прямо на обращение ({mount}/tickets/12) работает для того, кто ещё не вошёл. Форма входа несёт адрес как return, и после входа человек попадает именно на эту страницу. С присланной ссылкой адрес несёт сама ссылка; с паролем портал оставляет его в сессии как redirect_after_login плагина Login.

Адрес возврата проверяется на каждом шаге и отбрасывается при сомнении. Это должен быть путь на вашем сайте под справочным центром, не страница входа, без процентного кодирования, обратной косой черты, пробела, управляющих символов, сегмента . или .., двойной косой черты и ничего необычного в строке запроса. Всё остальное, например //evil.test или /help/%2e%2e/admin, игнорируется, и человек попадает на свои обращения. Ссылка на файл, {mount}/_file/{id}/{name}, разрешена, чтобы ссылка на файл из письма могла вернуться к нему.

Маршруты

Метод Путь Что делает
GET {mount}/ Главная справочного центра. Открыта всем.
GET {mount}/new Форма нового обращения (см. Форму запроса и гостей).
POST {mount}/new Отправляет форму и открывает новое обращение.
GET {mount}/new/thanks Куда попадает гость после отправки формы.
GET {mount}/tickets Ваши обращения. ?state=waiting показывает вкладку Waiting on you, а ?state=closed — Closed, ?q= ищет, ?page= листает (20 на страницу).
GET {mount}/organization Обращения вашей организации для участников организации, которая ими делится; «not found» для всех остальных. Принимает те же state, q и page.
GET {mount}/tickets/{id} Одно обращение: переписка, поле ответа и действия.
POST {mount}/tickets/{id}/reply Добавляет ответ.
POST {mount}/tickets/{id}/resolve «This is solved»: отмечает обращение решённым.
POST {mount}/tickets/{id}/reopen Открывает решённое обращение снова.
POST {mount}/tickets/{id}/mute Останавливает письма об обращении (muted=1) или запускает их снова (muted=0).
POST {mount}/tickets/{id}/rate «How did we do?» для решённого обращения (см. Оценки клиентов).
GET, POST {mount}/rate/{token} Страница, которую открывает ссылка на оценку в письме о решении, и ответ, который она отправляет.
GET, POST {mount}/login, {mount}/login/verify Ссылки для входа (см. Ссылки для входа).
POST {mount}/login/verify-email Вошедший клиент просит ссылку, подтверждающую его адрес.
GET, POST {mount}/unsubscribe Ссылка отписки в письме (см. Исходящую почту).
GET {mount}/search, {mount}/articles, {mount}/articles/{category} Поиск и просмотр базы знаний (см. Базу знаний).
GET {mount}/_file/{id}/{name} Файл после проверки доступа (см. Вложения).
POST {mount}/_upload, {mount}/_upload/{id}/remove Черновые загрузки из поля ответа и формы.
GET, POST {mount}/_live/config, {mount}/_live/presence Обновления в реальном времени для вошедших клиентов (см. Обновления в реальном времени).

Каждый POST, кроме ссылок оценки и отписки, несёт nonce формы Grav для действия helpdesk-portal. POST с устаревшим nonce (страница, оставленная открытой на ночь) ничего не меняет и показывает страницу снова с введённым текстом и просьбой повторить.

Ваши обращения

{mount}/tickets перечисляет обращения, которые вошедший человек отправил или в копии которых был, начиная с последней активности, под одним полем поиска и тремя вкладками, у каждой свой счётчик:

  • Open: получено, в работе или ждёт его ответа.
  • Waiting on you: открытые, ждущие его ответа.
  • Closed: решённые или закрытые.

Каждая строка показывает сводку, статус, номер (#1042) и когда он последний раз менялся. Обращение, ждущее его ответа, выделяется тёплой полосой, а обращение с непрочитанным ответом помечено New reply.

Вошедшие люди могут ввести номер обращения (1042 или #1042) в поле поиска справочного центра или списка и перейти прямо к нему, когда это обращение, которое они могут читать. Любой другой номер ищется как обычные слова, и оба ответа выглядят одинаково, поэтому поле никогда не говорит, используется ли номер.

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

Обращения вашей организации

Клиент в организации, которая делится обращениями, получает My organization в строке навигации и переключатель Mine | Acme над своим списком. {mount}/organization перечисляет каждое обращение организации с теми же вкладками, поиском и страницами, и каждая строка говорит, кто спросил («Asked by Ada» или «Asked by you»).

Открытие показывает публичную переписку, никогда заметки сотрудников. Он может её читать, но не может ответить, отметить решённым или отключить уведомления, если не участвует в обращении; страница говорит об этом там, где было бы поле ответа. Ему не приходят письма об этих обращениях.

Одно обращение

{mount}/tickets/{id} показывает сводку, статус, Request #{id} и когда оно было открыто, затем баннер о том, что будет дальше («We need something from you. Please reply below.»), затем переписку, начиная со старого. Собственные сообщения человека читаются как You; ответы поддержки несут имя агента, метку Support и акцентную полосу. Внутренние заметки, внутренняя активность и ваши названия статусов никогда не появляются: страница построена только из публичной переписки и публичной активности.

Пользовательские поля обращения, которые клиент может видеть и у которых есть значение, перечислены под заголовком. Клиент не может изменить их здесь.

Обращение, открытое сотрудником для клиента (в рабочей области «Anna on behalf of Maria Lopez»), показывает первое сообщение как сообщение заявителя: You для него, с тихим «added by our team».

Статус показывается словами клиента:

Категория статуса Что видит клиент
new Received
open, waiting_us In progress
waiting_client Waiting for your reply
resolved Solved
closed Closed

Что человек может сделать, зависит от обращения:

  • Reply. Ответ на решённое обращение открывает его снова, а ответ на обращение, которое ждёт его, возвращает его на вашу сторону. Ответы — обычный текст: пустая строка начинает абзац, вставленная ссылка становится ссылкой, а блок кода в тройных обратных кавычках остаётся блоком кода.
  • This is solved отмечает открытое обращение решённым. Это видят только заявитель и копии.
  • Reopen возвращает решённое обращение.
  • Закрытое обращение больше не принимает ответы. Оно предлагает Start a new request с заполненной сводкой и показывает набранный ответ, чтобы его можно было скопировать.
  • Stop emails about this request отключает уведомления для этого человека; затем ссылка читается Email me about this request again.

«You can also reply to any of our emails about this request» показывается, только когда входящая почта включена (inbound.enabled).

Обращение, которое человек не может читать, отвечает 404 и страницей «We couldn't find that request», точно как несуществующее.

Сотрудников, работающих с проектом обращения, отправляют в рабочую область (/admin/plugin/helpdesk-pro#/t/{id}, следуя маршруту вашего Admin Next). Портал никогда не показывает сторону сотрудников, и сотрудники никогда не отвечают через него. Любой другой сотрудник, открывший страницу обращения (отправленного им самим, в проекте, где он не работает), видит клиентский вид со ссылкой Open in the desk.

Время

У каждого времени в портале один формат, Sep 23, 2026, 2:22 PM, в часовом поясе читателя: часовой пояс его профиля Helpdesk, иначе timezone его учётной записи Grav, иначе system.timezone, иначе значение PHP по умолчанию. Время за последние 24 часа читается «just now», «12 min ago» или «3 h ago» с полным временем во всплывающей подсказке. С JavaScript портал перерисовывает их в часовом поясе браузера.

Файлы

Когда вложения включены, в поле ответа и форме нового обращения есть кнопка Attach files, а файлы также можно перетащить в форму или вставить в текстовое поле. С JavaScript каждый файл загружается сразу при выборе; без него файлы отправляются вместе с формой. Файлы всегда открываются через собственную ссылку портала с проверкой доступа, никогда по адресу хранилища. См. Вложения.

С JavaScript и без него

Всё работает с выключенным JavaScript: каждая кнопка — обычная форма, которая отправляется и возвращается к обращению с коротким подтверждением сверху («Your reply has been sent.»).

С включённым JavaScript скрипт портала (assets/dist/portal.js) загружает htmx на страницах, где он нужен, и те же формы обновляют обращение на месте: ответ появляется без загрузки страницы, подтверждение объявляется скринридерам, а поля ответа растут по мере ввода. Ctrl+Enter (Cmd+Enter на Mac) отправляет. Если ваша тема уже поставляет htmx, портал использует его. Тема, которая ускоряет каждую ссылку через htmx, тоже обрабатывается: ускоренная ссылка в портал становится полной загрузкой страницы, поэтому её стили и скрипт приходят с ней.

Страницы портала личные, поэтому отправляются с Cache-Control: private, no-cache, no-store, must-revalidate, какими бы ни были настройки кэша страниц.

Оформление портала

Портал наследует шрифты и цвета вашей темы. Вся разметка портала использует классы с префиксом helpdesk- внутри оболочки .helpdesk, а каждый цвет, радиус и отступ берётся из одного набора CSS-переменных. В теме на основе Pico (Quark2 и другие) они следуют переменным Pico; в любой другой теме они откатываются к нейтральным значениям, смешанным с цветом текста. Светлый и тёмный режимы работают без изменений.

Переоформите портал, задав любое из этого на :root или .helpdesk, не копируя шаблон:

Свойство Что задаёт
--helpdesk-accent Ссылки, основные кнопки, кольцо фокуса, полосу ответов поддержки, значки тем
--helpdesk-accent-contrast Текст на акцентном цвете
--helpdesk-text Основной текст
--helpdesk-muted Вторичный текст (строки метаданных, подсказки)
--helpdesk-border Тонкие линии
--helpdesk-surface Фон карточек
--helpdesk-subtle Оттенённые блоки («Still need help?», строка оценки статьи)
--helpdesk-team Оттенок за ответами поддержки
--helpdesk-radius Радиус углов (карточки используют его в полтора раза больше)
--helpdesk-gap Базовый отступ; каждый отступ в портале кратен ему
--helpdesk-width Наибольшая ширина портала (по умолчанию 68rem)
--helpdesk-success, --helpdesk-warning, --helpdesk-danger Цвета статусов и уведомлений

Например, в CSS вашей темы:

:root { --helpdesk-accent: #8428df; }

Внутри портала украшения заголовков темы и автоматические переносы выключены, а списки не несут маркеров темы.

Переопределение шаблонов

Каждый шаблон портала находится в templates/ плагина, и ваша тема побеждает, когда поставляет файл с тем же путём в собственной templates/. Текст берётся из languages/en.yaml под ICU.PLUGIN_HELPDESK_PRO.PORTAL_*, поэтому перевод портала означает перевод этих строк.

Шаблон Что отрисовывает
helpdesk.html.twig Тип страницы Help Center; размещает каждую страницу портала внутри макета вашей темы
helpdesk/home.html.twig Главную справочного центра
helpdesk/form.html.twig Страницу нового обращения
helpdesk/list.html.twig Ваши обращения
helpdesk/ticket.html.twig Одно обращение
helpdesk/not-found.html.twig «We couldn't find that request» (или «that topic»), отправляется с 404
helpdesk/articles.html.twig, helpdesk/category.html.twig Индекс статей и одну категорию
helpdesk/sign-in.html.twig Форму входа, показываемую вместо страницы, которой нужна учётная запись
helpdesk/unsubscribe.html.twig Страницу подтверждения отписки
helpdesk/rate.html.twig Страницу оценки
helpdesk/partials/*.html.twig Части: portal-nav, search-box, ticket-form, form-extra, ticket-body, thread, message, attachments, reply-form, attach-field, status-pill, ticket-row, my-requests, notice, sign-in-form, time, icon, topic-card, link-list

Шаблоны читают всё из одной переменной portal (portal.urls, portal.ticket, portal.timeline и так далее) и никогда не видят сырые строки базы данных. Шаблоны базы знаний перечислены в разделе База знаний.

Функции Twig

Используйте их в любом шаблоне или на странице с включённой обработкой Twig, чтобы ввести портал в остальной сайт.

Функция Возвращает
helpdesk_url(name, params = {}) URL страницы портала. Имена: home, form (или new), list (или tickets), ticket (передайте {id: 12}), login, search (передайте {q: '…'}), articles. Остальные параметры становятся строкой запроса, поэтому helpdesk_url('form', {q: 'Refund'}) открывает форму с заполненной сводкой.
helpdesk_nav(options = {}) Строку навигации портала для темы, которая установила portal.nav в false. Параметры: current (home, articles, list или new; по умолчанию тот, под который попадает адрес страницы) и wrap (false опускает оболочку .helpdesk).
helpdesk_ticket_form(options = {}) Форму нового обращения. Параметры: project (id или слаг для предварительного выбора) и compact (меньшая форма для боковой панели). Посетитель без входа видит вместо неё ссылку для входа.
helpdesk_my_requests(limit = 5) Последние активные обращения вошедшего человека со ссылкой на все. Для посетителей пусто.
<a href="{{ helpdesk_url('list') }}">My support requests</a>

{{ helpdesk_ticket_form({project: 'billing', compact: true}) }}

{{ helpdesk_my_requests(3) }}

{# В теме, где задано portal.nav: false #}
{{ helpdesk_nav() }}

Функции сами добавляют таблицу стилей и скрипт портала на страницу и оборачивают вывод в .helpdesk, чтобы стили работали и вне справочного центра. База знаний добавляет собственные функции.

Доступность

У каждого поля видимая метка, ошибки связаны с полем и объявляются, текущая вкладка и ссылка навигации помечены aria-current, переписка — размеченный список, времена — настоящие элементы <time>, а фокус виден на каждом элементе управления. Цвет статуса никогда не единственный сигнал: у каждого статуса есть и слова. Каждая страница работает без JavaScript, в светлом и тёмном режимах темы и на ширине телефона без боковой прокрутки.