Начало работы
Эта страница ведёт от нуля до вашего дополнения, показывающего страницу на сайте: три шага и ни одного файла, написанного вручную. Опыт с Pano не нужен, достаточно немного Kotlin и JavaScript.
Дополнение Pano добавляет сайту возможности: страницы и виджеты на теме (публичный сайт), экраны в панели (админка по адресу /panel) и API на бэкенде, всё в одном устанавливаемом JAR.
Дополнение и плагин это одно и то же
Дополнения это плагины Pano. В коде имена используют слово plugin (PanoPlugin, pluginId). В тексте сказано дополнение; ничего не переименовано.
У дополнения две работающие вместе половины: бэкенд на Kotlin, который работает внутри Pano (загружается через PF4J, вы его не трогаете), и UI на Svelte. Можно выпускать только одну половину, но каркас пишет обе. Внутреннее устройство объясняет Архитектура. Если вы хотите установить дополнения, а не писать их, см. Дополнения.
Что вам нужно
| Вам нужно | Как проверить |
|---|---|
| JDK 17 или новее | java -version |
| Bun (bun.sh) | bun --version |
| Pano на этой машине с включённым Панель → Настройки платформы → Режим разработки | откройте /panel |
Pano должен работать локально: пока вы работаете, дополнение лежит в папке plugins/ этой установки. Если его нет, см. Установку. В cmd или PowerShell вместо ./gradlew используйте gradlew.bat.
Быстрый старт
cd <ваш-pano>/plugins && bunx @panomc/plugin-kit new my-plugin # задаёт пять вопросов, затем устанавливает
cd my-plugin && bun run dev # первый запуск собирает jar (минуты); перезапустите Pano один раз, затем откройте /my-pluginТри шага: каркас, dev, перезапуск Pano. Каркас всегда создаётся в папке plugins/ Pano, потому что Pano ищет исходники разработки плагина в plugins/<pluginId>; папка называется id плагина, существующая папка отклоняется. Без id команда спросит id, имя, автора, пакет Kotlin и ставить ли сразу. new <id> [--package x.y] ничего не спрашивает.
После перезапуска откройте http://<адрес вашего Pano>/my-plugin: страница на месте и показывает ответ эндпоинта из каркаса. Панель → Дополнения тоже перечисляет дополнение.
Медленная первая сборка, зависшая установка
Первая сборка Gradle скачивает Gradle и toolchain и может несколько минут выглядеть зависшей; не отменяйте её. Если bun install застрял на «Resolving...», остановите его и запустите bun install --backend=copyfile.
Что вы получаете
| Файл | Что это |
|---|---|
src/theme/views/HelloPage.svelte | страница по адресу /my-plugin; показывает ответ GetHelloAPI |
src/main/kotlin/<пакет>/routes/GetHelloAPI.kt | GET /api/plugins/my-plugin/hello, объявлен как /hello |
src/main/kotlin/<пакет>/MyPlugin.kt | класс плагина |
src/main/resources/frontend-targets.json | ссылки, которые плагин отправляет наружу (пусто), см. Справочник API |
build.gradle.kts, gradle.properties, Gradle wrapper | сборка; copyJar кладёт jar в папку panoPluginsDir (..) |
package.json, rollup.config.js | две devDependency (@panomc/sdk, @panomc/plugin-kit) и двухстрочный rollup-файл |
Самая простая страница, которую пишет автор, и её эндпоинт:
<!-- src/theme/views/HelloPage.svelte -->
<script module>export const view = { path: '/hello' };</script>
<h1>Hello</h1>@Endpoint
class GetHelloAPI : Api() {
override val paths = listOf(Path("/hello", RouteType.GET))
override suspend fun handle(context: RoutingContext) = Successful(mapOf("message" to "hi"))
}Цикл разработки
bun run dev один раз собирает jar (без UI), если его нет, проверяет, что режим разработки включён, затем следит за UI. Что требует каждое изменение:
| Что вы изменили | Чтобы увидеть |
|---|---|
представление, помощник или контроллер в src/theme/ | bun run dev запущен, обновите страницу |
src/main/resources/locales/*.json | обновите страницу (режим разработки включён) |
| код Kotlin | ./gradlew build -Pnoui, затем перезапустите Pano |
gradle.properties | полный ./gradlew build, затем перезапуск |
Kotlin никогда не обновляется на лету
Выключение и включение дополнения в панели не загружает новый код Kotlin; сервер держит старый код, пока перезапуск не загрузит новый jar.
-Pnoui пропускает сборку UI и нужен только для итераций бэкенда; релизная сборка обязана включать UI (см. Сборка и публикация).
Что можно добавить
Новая страница: src/theme/views/X.svelte с export const view = { path: '/x' }
Помощник: любой .js рядом, импортируется как обычно (поставляется читаемым)
Закрытая логика: src/theme/controllers/x.js -> plugin('my-plugin').require('x')
Страница панели: src/main.js -> pano.ui.page.register({ path, component })
Тестовые данные: bunx pano-plugin samples X Проверка: bunx pano-plugin checkКаждый пункт разобран на странице Фронтенд.
Когда не работает
- Нет в Панель → Дополнения. Вы перезапустили Pano после первой сборки? Лежит ли jar прямо в
plugins/? Посмотрите в журнале сервера ошибку загрузки плагина. - Правка UI или локали не видна. Работает ли ещё
bun run dev, включён ли режим разработки, лежит ли папка вplugins/<pluginId>/? - Правка Kotlin не действует. Соберите
./gradlew build -Pnouiи перезапустите. - Dev-сервер зависает. Никогда не добавляйте правило прокси Vite для
/plugins: сервер UI уже отдаёт его, прокси зациклится. - «needs API level 0». Каркас пишет
apiLevel=1вgradle.properties; не удаляйте.
Куда дальше
- Фронтенд: именованные представления, помощники, контроллеры, примеры, виджеты.
- Справочник API: относительные пути эндпоинтов,
api.get, коды ошибок, страницы, цели ссылок, вебхуки. - Бэкенд: таблицы, эндпоинты, права.
- Архитектура: что происходит, когда Pano загружает ваш JAR.
- Сборка и публикация: выпустите релиз.