monoeq / kirby-inertia
Kirby Inertia 适配器
Requires
This package is auto-updated.
Last update: 2024-09-11 03:34:57 UTC
README
Inertia.js 是 Kirby 3 的适配器。
Inertia 允许您使用 JavaScript (React、Vue 和 Svelte) 构建前端,同时让服务器(在本例中为 Kirby)处理路由和数据处理。将其视为构建一个普通的 Kirby 网站,但前端使用 JavaScript 渲染。
工作原理
基本思想是当在浏览器中加载您的网站时,Kirby 提供一个包含内联 JSON 页面数据的 HTML 页面,以便您的 JavaScript 应用程序可以渲染页面。当您导航到不同的页面时,将带有 X-Inertia
标头的请求发送到 Kirby,通知 Kirby 只返回页面 JSON,而不是完整的 HTML 响应。您的 JavaScript 应用程序会接收到这些数据并渲染每个新页面。您可以在 Inertia 网站上阅读更多关于其工作原理的内容。
📌 本 README 不会介绍 Inertia 的工作原理或如何构建前端。它只是概述了实现以将 Kirby 用作 Inertia 后端的核心功能。
设置
在 安装 之后,您需要做的最基本的事情是定义一个 default.php
模板
<!DOCTYPE html> <html> <head> <title><?= $site->title() ?></title> <?= css('assets/css/site.css'); /* Your site’s css */ ?> </head> <body> <?php snippet('inertia') ?> <?= js('assets/js/site.js'); /* Your site’s js */ ?> </body> </html>
包含的 inertia
片段 仅渲染一个带有当前页面数据编码为 JSON 的应用程序外壳
<div id="app" data-page="{}"></div>
在此阶段,您可以继续构建您的 Inertia 前端。如果您在浏览器中访问您的网站(并查看源代码),您将看到包含页面数据的应用程序外壳。如果您使用带有 X-Inertia
标头的相同 URL 请求(使用 wget/curl 或 Postman 测试),将返回一个 JSON 响应。
创建响应
在 Kirby 中创建 Inertia 响应,使用 Kirby 控制器。与典型 Kirby 控制器唯一的区别是您返回一个 Inertia::render
函数,而不是数组。此插件为您分配了一个 default.php
控制器
return function ($page, $site, $kirby) { return Inertia::render( $page->intendedTemplate(), $page->toArray() ); };
第一个参数指定了您的 JavaScript 应用程序应渲染的视图名称,第二个参数是页面数据。在本例中,我们使用 $page->intendedTemplate()
作为视图名称,并使用 $page->toArray()
方法传递页面数据。
以下是一个具有更具体控制的示例 Controller
return function ($page, $site, $kirby) { return Inertia::render('TemplateName', [ 'title' => $page->title()->value(), 'date' => $page->date()->value(), 'thumbnail' => $page->thumbnail()->toFile()->url(), 'content' => $page->text()->kirbytext() ]); };
Inertia 功能
以下部分概述了如何在 Kirby 中使用一些 Inertia 功能,因为它们与 Laravel 适配器略有不同。
延迟评估
延迟评估 和部分数据按预期工作,只需将数据包裹在闭包中即可
return function ($page, $site, $kirby) { return Inertia::render('TemplateName', [ 'title' => $page->title()->value(), 'lazyProp' => function () use ($page) { return $page->children()->toArray(); } ]); };
共享数据
与 Laravel 适配器不同,Kirby 中的共享数据是在您的config.php
中定义的。您可以将共享数据定义为数组(值可以是闭包)或定义为返回数组的闭包。
'monoeq.inertia.shared' => [ "prop" => "value", "beep" => function () { return "boop"; } ]
'monoeq.inertia.shared' => function () { return [ "prop" => "value" ]; }
表单处理
在 Kirby 控制器中处理表单,就像您通常做的那样。只需确保您按照 Inertia 文档中的说明重定向到视图。
return function ($page, $site, $kirby) { // Form Handling if (kirby()->request()->method() === 'POST') { $kirby->impersonate('kirby'); $page->changeTitle(get('title', '')); go($page); // <- Redirect back to GET request for Inertia } return Inertia::render( $page->intendedTemplate(), $page->toArray() ); };
错误处理
您还希望在控制器中处理错误。包含了一个InertiaSession
辅助器,用于将数据传递到 Kirby 会话,然后您可以在共享数据中获取这些数据。请在此处查看示例。
根模板数据
您可以通过$inertia
变量访问 Kirby 模板中的数据。例如:$inertia['prop']
使用视图数据
Kirby Inertia 没有提供withViewData
方法,相反,您可以在调用Inertia::render
时传递第三个参数。这就像正常控制器行为一样将数据传递到 kirby 模板。
return function ($page, $site, $kirby) { return Inertia::render( $page->intendedTemplate(), $page->toArray(), [ 'meta' => 'hello' ] ); }; // In your template: <?= $meta ?>
会话数据
包含了一个InertiaSession
辅助器,用于将会话数据传递到您的 Inertia 视图。这对于服务器端验证或闪存消息非常有用,类似于 Laravel 的Inertia::share
。您可以在设置共享数据时处理 Inertia 会话数据,在config.php
中。
return [ 'monoeq.inertia.shared' => [ 'messages' => function () { // pull() fetches any session data stored under messages, and then wipes it return InertiaSession::pull('messages'); }, 'errors' => function () { // pull() fetches any session data stored under errors, and then wipes it return InertiaSession::pull('errors'); } ] ];
所以,您可以在表单控制器中使用此辅助器,如下所示
return function ($page, $site, $kirby) { // Form Handling if (kirby()->request()->method() === 'POST') { try { $kirby->impersonate('kirby'); $page->changeTitle(get('title', '')); InertiaSession::append('messages', 'Thank You!'); } catch (Exception $e) { InertiaSession::append('errors', $e->getMessage()); // or if you want to have named errors // InertiaSession::merge('errors', [ 'title' => $e->getMessage() ]); } go($page); // <- Redirect back to GET request for Inertia } return Inertia::render( $page->intendedTemplate(), $page->toArray() ); };
然后,在您的 JavaScript 视图中,您可以获取这些数据
<div v-if="$page.messages">{{ $page.messages }}</div> <div v-if="$page.errors">{{ $page.errors }}</div>
配置
return [ 'monoeq.inertia.version' => '1.0', 'monoeq.inertia.shared' => [ 'site' => function () { return [ 'title' => site()->title()->value() ]; } ] ];
类 API
Inertia
Inertia::render($name, $data, $viewData)
从您的 Kirby 控制器返回以渲染 Inertia 响应。
InertiaSession
在kirby()->session()
周围包装的类,用于将数据传递到您的 Inertia 视图。底层使用inertia
命名空间,以避免与其他 Kirby 会话数据冲突。
InertiaSession::set($key, $value)
InertiaSession::append($key, $value)
将值追加到指定的键(如果没有定义,则设置键)。
InertiaSession::append('messages', 'beep'); InertiaSession::append('messages', 'boop'); InertiaSession::get('messages'); // => ['beep', 'boop']
InertiaSession::merge($key, $value)
将值合并到指定的键(如果没有定义,则设置键)。
InertiaSession::merge('messages', [ 'beep' => 'boop' ]); InertiaSession::merge('messages', [ 'bleep' => 'bloop' ]); InertiaSession::get('messages'); // => [ 'beep' => 'boop', 'bleep' => 'bloop' ]
InertiaSession::get($key)
InertiaSession::pull($key)
InertiaSession::remove($key)
安装
下载
下载并将此存储库复制到 /site/plugins/kirby-inertia
。
Git 子模块
git submodule add https://github.com/monoeq/kirby-inertia.git site/plugins/kirby-inertia
Composer
composer require monoeq/kirby-inertia
其他注意事项
自动模板
在 Kirby 中,通常需要为控制器创建一个实际的模板文件。但是当使用 Inertia 时,通常只需要 default.php
模板。作为一个辅助工具,这个插件会自动将任何没有匹配模板文件的控制器文件分配给 default.php
,这样您就可以只创建控制器而不必担心创建模板。
前端示例
有关如何构建 Inertia 前端的详细信息,请参阅 Inertia.js 文档,但这里有一个使用 Vue 的基本示例。
app.js
查看代码
import { InertiaApp } from '@inertiajs/inertia-vue' import Vue from 'vue' import 'nprogress/nprogress.css' Vue.use(InertiaApp) const app = document.getElementById('app') // Include templates here const templates = { 'default': require('./templates/default').default } new Vue({ render: h => h(InertiaApp, { props: { initialPage: JSON.parse(app.dataset.page), // Falls back to default template, Kirby-style resolveComponent: name => templates[name] || templates['default'] }, }), }).$mount(app)
templates/default.vue
查看代码
<template> <div>{{ content.title }}</div> </template> <script> export default { props: { content: Object } } </script>
待办事项
- 缓存
- 启用 Kirby 缓存将目前破坏 Inertia 功能。