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

Панель управления

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

Статистика панели управления

GET /dashboard/stats

Возвращает сводку статистики сайта для панели управления, включая доступные обновления GPM. Требуется api.system.read.

Ответ

{"data": {"pages": {"total": 42, "published": 40}, "users": {"total": 5}, "plugins": {"total": 12, "active": 10, "updatable": 2}, "themes": {"total": 2, "updatable": 0, "active_updatable": false}, "grav": {"updatable": false}, "media": {"total": 120}, "theme": "quark", "grav_version": "2.1.0", "php_version": "8.3.14", "last_backup": "2026-03-26T03:00:00+00:00"}}

Коды ответов

Код Описание
200 Успех
401 Не авторизован
403 Нет разрешения api.system.read

Возвращает снимок статистики сайта: число страниц, пользователей, плагинов и тем с доступными обновлениями, наличие обновления Grav, число медиафайлов, активную тему, версии Grav и PHP, а также дату последней резервной копии. Счётчики обновлений становятся нулевыми, когда GPM недоступен. last_backup учитывает только архивы, созданные инструментом резервного копирования Grav (<name>--<timestamp>.zip в backup://), и равен null, когда их нет.


Статистика просмотров страниц

GET /dashboard/popularity

Возвращает статистику просмотров страниц от трекера популярности API. Требуется api.system.read.

Ответ

{"data": {"summary": {"today": 34, "week": 212, "month": 804}, "chart": [{"date": "Sep 8", "views": 25}, {"date": "Sep 9", "views": 31}], "top_pages": [{"route": "/blog", "views": 1204}, {"route": "/", "views": 980}]}}

Коды ответов

Код Описание
200 Успех
401 Не авторизован
403 Нет разрешения api.system.read

Возвращает статистику просмотров страниц: данные графика по дням за последние 14 дней (сначала старые, с метками дат вида M j), сводные счётчики (сегодня, последние 7 дней, текущий календарный месяц) и 10 самых популярных страниц по общему числу просмотров. Данные берутся из собственного хранилища популярности плагина API (plugins.api.popularity); при первом чтении после обновления с классической админки его старые файлы популярности импортируются автоматически.


Уведомления панели управления

GET /dashboard/notifications

Возвращает системные уведомления, сгруппированные по месту отображения (top, dashboard, feed), с меткой времени last_checked. Требуется api.system.read.

Параметры

Имя Тип Обязательный Описание
location string Нет Вернуть только одну группу: top, dashboard или feed.
force boolean Нет Обойти кэшированные уведомления getgrav.org и запросить их заново. Иначе кэш живёт system.session.timeout секунд на пользователя, а неудачный запрос молча возвращает кэшированную копию.

Ответ

{"data": {"notifications": {"feed": [{"id": 214, "date": "2026-07-31 12:00", "type": "info", "location": ["feed"], "message": "Run a real community on your own site with **Forum Pro** for Grav 2, now available.", "link": "https://getgrav.org/premium/forum-pro"}]}, "last_checked": "2026-09-21T08:00:00+00:00"}}

Коды ответов

Код Описание
200 Успех
401 Не авторизован
403 Нет разрешения api.system.read

Возвращает системные уведомления, сгруппированные по месту (feed, dashboard, top), плюс метку времени last_checked. Ответ объединяет ленту getgrav.org с уведомлениями, которые добавляют плагины через событие onApiDashboardNotifications, а затем отбрасывает всё, что текущий пользователь скрыл, — с учётом необязательного интервала reappear_after каждого уведомления.

Каждый элемент уведомления содержит id, message и date, а также необязательные icon (имя Lucide или эмодзи), title, action ({label, url}), link, type (info, notice, warning или promo) и reappear_after. Группа top отображается как вращающийся баннер над панелью управления; dashboard и feed — в виджете уведомлений. Скрыть уведомление можно через POST /dashboard/notifications/{id}/hide.

Пример для плагинов — как поднять постоянный скрываемый баннер и чем уведомления отличаются от временных всплывающих сообщений — см. в разделе Уведомления и всплывающие сообщения руководства разработчика.


Лента новостей

GET /dashboard/feed

Возвращает последнюю ленту новостей с getgrav.org. Требуется api.system.read.

Параметры

Имя Тип Обязательный Описание
force boolean Нет Обойти кэшированную ленту и запросить её заново.

Ответ

{"data": {"feed": [{"title": "Grav 2.1 Released", "url": "https://getgrav.org/blog/grav-2-1-released", "date": "2026-09-11T12:00:00+00:00", "summary": ""}], "last_checked": "2026-09-21T08:00:00+00:00"}}

Коды ответов

Код Описание
200 Успех
401 Не авторизован
403 Нет разрешения api.system.read

Возвращает последние записи блога из Atom-ленты getgrav.org: до 10 самых свежих статей, каждая с title, url, date и summary, плюс метку времени last_checked. Лента кэшируется на пользователя на system.session.timeout секунд, а неудачный запрос молча возвращает кэшированную копию.


Скрытие уведомления

POST /dashboard/notifications/{id}/hide

Скрывает уведомление панели управления для текущего пользователя. Записывает метку времени в user://data/notifications/{username}.yaml, чтобы это уведомление отфильтровывалось из будущих ответов GET /dashboard/notifications.

Параметры

Имя Тип Обязательный Описание
id string Да Идентификатор уведомления (из ответа GET /dashboard/notifications). Он не проверяется по известным уведомлениям, но должен состоять из 1–64 букв, цифр, ., _ или -, начинаясь с буквы или цифры. getgrav.org использует числа; плагины используют slug'и вроде login-lockout.

Коды ответов

Код Описание
204 Уведомление скрыто.
401 Не авторизован.
403 Нет разрешения api.system.write.
422 Идентификатор не является действительным идентификатором уведомления.

Проверка доступности хранилища

GET /dashboard/security/exposure-probe

Возвращает URL проверки, которые Admin2 использует, чтобы выяснить, доступны ли приватные папки хранилища по HTTP. Требуется api.system.read.

Ответ

{"data": {"url": "https://example.com/user/data/grav-security-probe.dat", "token": "3f9c2a7e5b1d4c8a9e0f6b2d7c4a1e8f", "available": true, "probes": [{"location": "user/data", "extension": "dat", "url": "https://example.com/user/data/grav-security-probe.dat", "token": "3f9c2a7e5b1d4c8a9e0f6b2d7c4a1e8f", "available": true}, {"location": "tmp", "extension": "txt", "url": "https://example.com/tmp/grav-security-probe.txt", "token": "8b1e4d7a2c9f0e3b6a5d8c1f4e7b0a2d", "available": true}]}}

Коды ответов

Код Описание
200 Список проверок возвращён.
401 Не авторизован
403 Нет разрешения api.system.read

Для каждой из папок user://data, backup:// и tmp://, находящихся внутри корня веб-сервера, сервер убеждается, что существует сигнальный файл grav-security-probe.{dat,txt,zip,json}, создавая его со случайным hex-токеном, если его нет (он никогда не перезаписывает существующий файл и не следует по символической ссылке), и возвращает его публичный URL и токен. Затем Admin2 запрашивает каждый URL через настоящий веб-сервер сайта: если тело ответа совпадает с токеном, эта папка и тип файла публично доступны, что обычно означает, что веб-сервер не применяет правила запрета Grav. Проверяются несколько типов файлов, так как фронтенд-прокси может сам отдавать некоторые расширения.

Папки, перенесённые за пределы корня веб-сервера, не имеют публичного URL и пропускаются. Поля верхнего уровня url, token и available повторяют первую проверку user://data для старых сборок Admin2. Учтите, что этот GET создаёт файлы при первом вызове.


Виджеты панели управления

GET /dashboard/widgets

Возвращает разрешённый список виджетов панели управления и макеты для текущего пользователя. Требуется api.access.

Ответ

{"data": {"widgets": [{"id": "core.stats", "source": "core", "label": "ADMIN_NEXT.DASHBOARD.WIDGETS.STATS", "icon": "BarChart3", "sizes": ["md", "lg", "xl"], "defaultSize": "xl", "priority": 100, "visible": true, "size": "xl", "order": 9000}], "user_layout": {}, "site_layout": {}, "can_edit_site": true}}

Коды ответов

Код Описание
200 Список виджетов и макеты возвращены.
401 Не авторизован
403 Нет разрешения api.access

Список объединяет встроенные виджеты ядра, виджеты, которые плагины добавляют через событие onApiDashboardWidgets, макет сайта по умолчанию и макет текущего пользователя. Виджеты, на которые у пользователя нет разрешения authorize, не включаются (суперпользователь в пределах области действия своего ключа API видит все виджеты), а authorize удаляется из ответа. Виджет, скрытый макетом сайта, удаляется полностью, поэтому пользователь не может включить его обратно.

Каждый виджет аннотируется действующими visible, size и order, а список сортируется по order. Виджет без сохранённого order размещается по своему priority. Виджет плагина, не объявивший sizes, получает sm, md и lg, а виджет без действительного defaultSize получает md (или свой первый размер), поэтому виджет, который их не указывает, всё равно отображается. Виджеты плагинов содержат source: plugin; can_edit_site сообщает клиенту, может ли вызывающая сторона сохранять макет сайта.


Сохранение макета панели управления

PATCH /dashboard/layout

Сохраняет макет панели управления текущего пользователя в admin_next.dashboard в YAML-файле его учётной записи и возвращает разрешённый список виджетов (тот же, что в GET /dashboard/widgets). Требуется api.access. Демо-учётные записи отклоняются.

Параметры

Имя Тип Обязательный Описание
preset string Нет Одно из значений: default, minimal, compact, custom. Всё остальное сохраняется как custom.
widgets array Нет Записи виджетов: id (string, обязательно), visible (boolean, по умолчанию true), size (от xs до xl) и order (число).

Запрос

{"preset": "custom", "widgets": [{"id": "core.stats", "visible": true, "size": "lg", "order": 10}, {"id": "core.news-feed", "visible": false, "order": 20}]}

Ответ

{"data": {"widgets": [{"id": "core.stats", "source": "core", "label": "ADMIN_NEXT.DASHBOARD.WIDGETS.STATS", "icon": "BarChart3", "sizes": ["md", "lg", "xl"], "defaultSize": "xl", "priority": 100, "visible": true, "size": "lg", "order": 10}], "user_layout": {"preset": "custom", "widgets": [{"id": "core.stats", "visible": true, "size": "lg", "order": 10}, {"id": "core.news-feed", "visible": false, "size": null, "order": 20}]}, "site_layout": {}, "can_edit_site": true}}

Коды ответов

Код Описание
200 Макет сохранён; разрешённый список виджетов возвращён.
401 Не авторизован
403 Нет разрешения api.access или это демо-учётная запись
422 Тело не является JSON-объектом.

Несмотря на глагол PATCH, сохранённый макет заменяется целиком, поэтому отправляйте каждую запись виджета, которую хотите сохранить. Записи без строкового id отбрасываются, а size вне диапазона от xs до xl сохраняется как null. Запись, отправленная без числового order, сохраняется без него, поэтому виджет сохраняет позицию по приоритету, а не перемещается в начало.


Сохранение макета панели управления сайта

PATCH /dashboard/site-layout

Сохраняет макет панели управления по умолчанию для всех пользователей в dashboard.site_layout в user/config/admin-next.yaml и возвращает разрешённый список виджетов для вызывающей стороны. Требуется суперпользователь (с учётом ограничения области действия ключа API). Демо-учётные записи отклоняются.

Параметры

Имя Тип Обязательный Описание
preset string Нет Одно из значений: default, minimal, compact, custom. Всё остальное сохраняется как custom.
widgets array Нет Записи виджетов: id (string, обязательно), visible (boolean, по умолчанию true), size (от xs до xl) и order (число).

Запрос

{"preset": "custom", "widgets": [{"id": "core.news-feed", "visible": false}, {"id": "core.stats", "size": "xl", "order": 10}]}

Ответ

{"data": {"widgets": [{"id": "core.stats", "source": "core", "label": "ADMIN_NEXT.DASHBOARD.WIDGETS.STATS", "icon": "BarChart3", "sizes": ["md", "lg", "xl"], "defaultSize": "xl", "priority": 100, "visible": true, "size": "xl", "order": 10}], "user_layout": {}, "site_layout": {"preset": "custom", "widgets": [{"id": "core.news-feed", "visible": false, "size": null}, {"id": "core.stats", "visible": true, "size": "xl", "order": 10}]}, "can_edit_site": true}}

Коды ответов

Код Описание
200 Макет сайта сохранён; разрешённый список виджетов возвращён.
401 Не авторизован
403 Не суперпользователь или это демо-учётная запись
422 Тело не является JSON-объектом.

Сохранённый макет заменяется целиком с той же нормализацией, что и в PATCH /dashboard/layout. Виджет, помеченный здесь как visible: false, скрыт для всех пользователей, и его нельзя включить обратно в собственном макете пользователя. Размеры и порядок действуют как значения по умолчанию, которые может переопределить макет каждого пользователя.