如果您不想将前端和后端绑定在一起,我们会看一下 Payload,这是一个有趣的 CMS 和应用程序框架选择。
关于 Web 开发的有趣事情之一就是尝试将视觉设计与数据设计融合在一起。虽然它们需要在网站和 Web 应用中结合在一起,但它们是完全独立的学科。像Ruby on Rails这样的框架一直在努力将它们结合起来。
Payload CMS勇敢地将自己描述为“无头 CMS 和应用程序框架”。虽然我们不将用户界面称为“头”,但无头只是指没有专用前端的框架。内容管理系统 (CMS) 只是一个处理结构化数据的框架。例如,如果数据是博客,那么管理的内容就是帖子。
什么是 Payload页面很好地展示了这一困境,并试图解释其自身的观点。当它认识到 CMS 倾向于“将内容的呈现与内容的存储绑定在一起”时,它就大获成功。因此,Payload 的目标是与您想要使用的任何前端配合使用。
截至目前,Payload 处于一些重大更改和版本 3 之间,因此旧文档可能已过时。按照我的指示,我得到了一个旧版本。
安装
到目前为止,安装先决条件选项对于数据库来说有点狭窄,但有一个关系和一个基于文档的示例可供选择:
在我的 MacBook 上,我通过 Homebrew 安装了社区MongoDB:
然后我通过将 Mongo 添加为服务来启动它:
我们可以将连接字符串看作 URL,因此我们应该能够设置 Payload。
在另一个浏览器选项卡中,我安装了 Payload 应用程序:
我建立了一个演示项目,很快我们就可以启动了:
其中一个示例项目失败了,因为它需要 Discord!正如我所说,由于即将发生的变化,一些文档和视频还不太匹配。这当然是件好事——该项目非常活跃。我选择了 payload-demo 模板,效果很好。
然后“yarn dev”运行该项目:
连接到 MongoDB 后,它将启动有效负载管理员(在 localhost:3000/admin)以及演示应用程序(标记为 Next.js 应用程序,用于模板的 React 框架)。
有效载荷应用程序
直接进入应用程序我们会看到:
此时,还没有内容,因此您将被引导至管理仪表板开始制作一些内容。管理仪表板允许我创建带有电子邮件的管理员角色或用户角色。
仪表板本身有助于解释 Payload 的实际含义:
Payload 将所有内容组织成集合中的类型集。这包括页面和用户。我们可以创建新类型并立即开始使用它们,就像我们将做的那样。
这里有点令人困惑:首先,您按下“种子数据库”链接,您将获得大量演示内容。这将清除所有已存在的内容。您还需要创建一个“主页”,否则您只会看到上面的默认模板页面,这可能会让您认为您没有内容,但实际上您有内容。
当我理解了这个系统后,我就在页面类型上创建了一些简单但毫无新意的内容:
使用管理界面添加收藏后,您就可以发布任何更改(提交它们)。这将自动更新您的网站。
用代码做所有事情
现在,在这个阶段,我做的还远远不及你能用 Publii 做的事情,Publii也像一个经典的 CMS。然而,Payload 有两点非常突出。你不仅可以在 REST 中与它对话,还可以重用 Payload 的某些部分,从而模糊谁拥有什么的区别。而且,你可以在代码中完成所有事情,这就是我们现在要做的事情。
例如,您可以看到 Users 是一种集合类型,可供我们使用:
这些注册在哪里?都在文件中。首先将它们导入,然后(如下所示)添加到已知集合中:payload.config.ts
在 Users 文件夹中,我们有一个基本的 index.ts 文件,它定义了 Users 类型。虽然这包含相当多的 Typescript,但其中大部分只是描述管理员访问权限。Payload 允许相当多的细粒度访问控制:
import type { CollectionConfig } from 'payload/types' import { admins } from '../../access/admins' import { anyone } from '../../access/anyone' import adminsAndUser from './access/adminsAndUser' import { checkRole } from './checkRole' import { ensureFirstUserIsAdmin } from './hooks/ensureFirstUserIsAdmin' import { loginAfterCreate } from './hooks/loginAfterCreate' const Users: CollectionConfig = { slug: 'users', admin: { useAsTitle: 'name', defaultColumns: ['name', 'email'], }, access: { read: adminsAndUser, create: anyone, update: adminsAndUser, delete: admins, admin: ({ req: { user } }) => checkRole(['admin'], user), }, hooks: { afterChange: [loginAfterCreate], }, auth: true, fields: [ { name: 'name', type: 'text', }, { name: 'roles', type: 'select', hasMany: true, defaultValue: ['user'], options: [ { label: 'admin', value: 'admin', }, { label: 'user', value: 'user', }, ], hooks: { beforeChange: [ensureFirstUserIsAdmin], }, access: { read: admins, create: admins, update: admins, }, }, ], timestamps: true, } export default Users
然而,我们将削减这个功能并创建我们自己的集合类型,不需要管理员或钩子。
假设我们只想要一个名为 Members 的类型。我将创建相应的文件夹并创建一个精简版的 index.ts:
import type { CollectionConfig } from 'payload/types' const Members: CollectionConfig = { slug: 'members', fields: [ { name: 'name', type: 'text', }, { name: 'membership', type: 'number', }, ], timestamps: true, } export default Members
这只是用名称和数字成员字段来描述类型。Payload 通过不同的字段完成了很多工作。
服务器检测到更改:
最后一件事。让我们通过 REST 访问我们的新成员:
所以我们被锁定了。但是等一下……还记得我们为了简化成员集合而删除的细粒度访问权限吗?让我们尝试放回一点:
import type { CollectionConfig } from 'payload/types' import { anyone } from '../../access/anyone' const Members: CollectionConfig = { slug: 'members', access: { read: anyone, }, fields: [ { name: 'name', type: 'text', }, { name: 'memebership', type: 'number', }, ], timestamps: true, } export default Members
我所做的只是添加“任何人”的导入并添加访问权限。现在让我们尝试一下:
非常好。我们创建了一个新集合,在管理控制台中看到了它,为其创建了一个条目,甚至通过 REST 请求了它。因此,这些内容现在已可用于我的网站。
结论
正如我之前所说,Payload 目前正在过渡到版本 3,因此在调查之前,可能需要等待一段时间。话虽如此,如果你不坚持让你的前端和后端经历一场大联合,这个想法已经很强大了。
网友评论文明上网理性发言 已有0人参与
发表评论: