payload
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePayload CMS Operations
Payload CMS 操作指南
Manage Payload CMS content via REST API. Works with any Payload deployment (production or local).
通过REST API管理Payload CMS内容。适用于任何Payload部署环境(生产环境或本地环境)。
When to Use
适用场景
- Creating or editing posts/pages in Payload CMS
- Converting markdown content to Lexical rich text format
- Listing and querying Payload collections
- Bulk content updates
- 在Payload CMS中创建或编辑帖子/页面
- 将Markdown内容转换为Lexical富文本格式
- 列出和查询Payload集合
- 批量内容更新
Workflow: REST API with Authentication
工作流:带身份验证的REST API
Step 1: Determine the API Endpoint
步骤1:确定API端点
Ask the user for their Payload site URL, or check common locations:
bash
undefined向用户询问其Payload站点URL,或检查常见地址:
bash
undefinedProduction site (ask user or check project config)
生产站点(询问用户或检查项目配置)
curl -s "https://your-site.com/api/posts?limit=1" | head -c 100
curl -s "https://your-site.com/api/posts?limit=1" | head -c 100
Local development
本地开发环境
curl -s "http://localhost:3000/api/posts?limit=1" 2>/dev/null | head -c 100
curl -s "http://localhost:3010/api/posts?limit=1" 2>/dev/null | head -c 100
undefinedcurl -s "http://localhost:3000/api/posts?limit=1" 2>/dev/null | head -c 100
curl -s "http://localhost:3010/api/posts?limit=1" 2>/dev/null | head -c 100
undefinedStep 2: Authenticate
步骤2:身份验证
For mutations (create/update/delete), authentication is required. Payload uses session-based auth.
Option A: User provides credentials
bash
undefined对于创建/更新/删除等变更操作,需要身份验证。Payload使用基于会话的身份验证。
选项A:用户提供凭据
bash
undefinedLogin to get auth token
登录获取认证令牌
curl -X POST "https://your-site.com/api/users/login"
-H "Content-Type: application/json"
-d '{"email": "user@example.com", "password": "..."}'
-c cookies.txt
-H "Content-Type: application/json"
-d '{"email": "user@example.com", "password": "..."}'
-c cookies.txt
curl -X POST "https://your-site.com/api/users/login"
-H "Content-Type: application/json"
-d '{"email": "user@example.com", "password": "..."}'
-c cookies.txt
-H "Content-Type: application/json"
-d '{"email": "user@example.com", "password": "..."}'
-c cookies.txt
Use the cookie file for authenticated requests
使用Cookie文件进行已认证请求
curl -X POST "https://your-site.com/api/posts"
-H "Content-Type: application/json"
-b cookies.txt
-d '{"title": "...", "content": {...}}'
-H "Content-Type: application/json"
-b cookies.txt
-d '{"title": "...", "content": {...}}'
**Option B: User logs in via admin UI**
Have the user log in at `/admin`, then extract the `payload-token` cookie from their browser for use in API calls.curl -X POST "https://your-site.com/api/posts"
-H "Content-Type: application/json"
-b cookies.txt
-d '{"title": "...", "content": {...}}'
-H "Content-Type: application/json"
-b cookies.txt
-d '{"title": "...", "content": {...}}'
**选项B:用户通过管理UI登录**
让用户在`/admin`路径登录,然后从其浏览器中提取`payload-token` Cookie用于API调用。Step 3: Create/Update Content
步骤3:创建/更新内容
bash
undefinedbash
undefinedCreate a post
创建帖子
curl -X POST "https://your-site.com/api/posts"
-H "Content-Type: application/json"
-b cookies.txt
-d '{ "title": "Post Title", "slug": "post-slug", "content": { "root": { ... } }, "_status": "published" }'
-H "Content-Type: application/json"
-b cookies.txt
-d '{ "title": "Post Title", "slug": "post-slug", "content": { "root": { ... } }, "_status": "published" }'
curl -X POST "https://your-site.com/api/posts"
-H "Content-Type: application/json"
-b cookies.txt
-d '{ "title": "帖子标题", "slug": "post-slug", "content": { "root": { ... } }, "_status": "published" }'
-H "Content-Type: application/json"
-b cookies.txt
-d '{ "title": "帖子标题", "slug": "post-slug", "content": { "root": { ... } }, "_status": "published" }'
Update a post
更新帖子
curl -X PATCH "https://your-site.com/api/posts/POST_ID"
-H "Content-Type: application/json"
-b cookies.txt
-d '{"content": { "root": { ... } }}'
-H "Content-Type: application/json"
-b cookies.txt
-d '{"content": { "root": { ... } }}'
undefinedcurl -X PATCH "https://your-site.com/api/posts/POST_ID"
-H "Content-Type: application/json"
-b cookies.txt
-d '{"content": { "root": { ... } }}'
-H "Content-Type: application/json"
-b cookies.txt
-d '{"content": { "root": { ... } }}'
undefinedStep 4: Verify
步骤4:验证
bash
undefinedbash
undefinedCheck the post was created
检查帖子是否创建成功
curl -s "https://your-site.com/api/posts?where[slug][equals]=post-slug" | jq '.docs[0]'
undefinedcurl -s "https://your-site.com/api/posts?where[slug][equals]=post-slug" | jq '.docs[0]'
undefinedLexical JSON Structure
Lexical JSON结构
Payload's Lexical editor stores content as JSON:
json
{
"root": {
"type": "root",
"format": "",
"indent": 0,
"version": 1,
"direction": "ltr",
"children": [
{
"type": "paragraph",
"format": "",
"indent": 0,
"version": 1,
"direction": "ltr",
"children": [
{"type": "text", "text": "Content here", "mode": "normal", "format": 0, "detail": 0, "version": 1, "style": ""}
]
}
]
}
}Payload的Lexical编辑器以JSON格式存储内容:
json
{
"root": {
"type": "root",
"format": "",
"indent": 0,
"version": 1,
"direction": "ltr",
"children": [
{
"type": "paragraph",
"format": "",
"indent": 0,
"version": 1,
"direction": "ltr",
"children": [
{"type": "text", "text": "内容示例", "mode": "normal", "format": 0, "detail": 0, "version": 1, "style": ""}
]
}
]
}
}Supported Node Types
支持的节点类型
| Markdown | Lexical Node |
|---|---|
| Paragraphs | |
| |
| text with format: 1 |
| text with format: 2 |
| text with format: 16 |
| Code blocks | |
| Lists | |
| |
| Markdown | Lexical 节点 |
|---|---|
| 段落 | |
| |
| format值为1的文本 |
| format值为2的文本 |
| format值为16的文本 |
| 代码块 | blockType为"code"的 |
| 列表 | 包含 |
| |
Text Format Bitmask
文本格式位掩码
| Value | Format |
|---|---|
| 0 | Normal |
| 1 | Bold |
| 2 | Italic |
| 3 | Bold + Italic |
| 16 | Code |
| 数值 | 格式 |
|---|---|
| 0 | 普通文本 |
| 1 | 粗体 |
| 2 | 斜体 |
| 3 | 粗体+斜体 |
| 16 | 代码 |
Markdown to Lexical Conversion
Markdown转Lexical格式
The skill includes a Python script for converting markdown to Lexical JSON:
bash
python3 ${SKILL_DIR}/scripts/md_to_lexical.py article.md > /tmp/content.json此Skill包含一个将Markdown转换为Lexical JSON的Python脚本:
bash
python3 ${SKILL_DIR}/scripts/md_to_lexical.py article.md > /tmp/content.jsonCommon Collections
常见集合
| Collection | Slug | Purpose |
|---|---|---|
| Posts | | Blog posts |
| Pages | | Static pages |
| Media | | Uploaded files |
| Users | | User accounts |
| 集合 | 别名 | 用途 |
|---|---|---|
| Posts | | 博客帖子 |
| Pages | | 静态页面 |
| Media | | 上传文件 |
| Users | | 用户账户 |
Local Development Alternative
本地开发替代方案
If working locally and REST auth is problematic, write an inline script in the project:
typescript
// scripts/create-post.ts
import { getPayload } from 'payload'
import config from '../src/payload.config'
const payload = await getPayload({ config })
await payload.create({
collection: 'posts',
data: { title: '...', content: {...}, _status: 'published' }
})
process.exit(0)Run with:
source .env.local && bunx tsx scripts/create-post.tsNote: If Drizzle prompts for schema migration, answer 'n' and use REST API instead.
如果在本地开发时REST身份验证存在问题,可以在项目中编写内联脚本:
typescript
// scripts/create-post.ts
import { getPayload } from 'payload'
import config from '../src/payload.config'
const payload = await getPayload({ config })
await payload.create({
collection: 'posts',
data: { title: '...', content: {...}, _status: 'published' }
})
process.exit(0)运行命令:
source .env.local && bunx tsx scripts/create-post.ts注意:如果Drizzle提示进行 schema 迁移,请输入'n'并改用REST API。
Payload CLI Commands
Payload CLI命令
The Payload CLI provides comprehensive database and project management:
Payload CLI提供全面的数据库和项目管理功能:
Migration Commands
迁移命令
bash
undefinedbash
undefinedCheck migration status
检查迁移状态
bun run payload migrate:status
bun run payload migrate:status
Run pending migrations
运行待处理的迁移
bun run payload migrate
bun run payload migrate
Create a new migration
创建新迁移
bun run payload migrate:create migration-name
bun run payload migrate:create migration-name
Rollback last migration
回滚上一次迁移
bun run payload migrate:down
bun run payload migrate:down
Rollback and re-run all migrations
回滚并重新运行所有迁移
bun run payload migrate:refresh
bun run payload migrate:refresh
Reset all migrations (rollback everything)
重置所有迁移(回滚全部)
bun run payload migrate:reset
bun run payload migrate:reset
Fresh start - drop all tables and re-run migrations
全新启动 - 删除所有表并重新运行迁移
bun run payload migrate:fresh
undefinedbun run payload migrate:fresh
undefinedGeneration Commands
生成命令
bash
undefinedbash
undefinedGenerate TypeScript types from collections
从集合生成TypeScript类型
bun run payload generate:types
bun run payload generate:types
Generate import map
生成导入映射
bun run payload generate:importmap
bun run payload generate:importmap
Generate Drizzle database schema
生成Drizzle数据库schema
bun run payload generate:db-schema
undefinedbun run payload generate:db-schema
undefinedUtility Commands
实用命令
bash
undefinedbash
undefinedShow Payload project info
显示Payload项目信息
bun run payload info
bun run payload info
Run a custom script with Payload initialized
在Payload初始化后运行自定义脚本
bun run payload run scripts/my-script.ts
undefinedbun run payload run scripts/my-script.ts
undefinedJobs Commands (if using Payload Jobs)
任务命令(若使用Payload Jobs)
bash
undefinedbash
undefinedRun queued jobs
运行队列中的任务
bun run payload jobs:run
bun run payload jobs:run
Run jobs with options
带选项运行任务
bun run payload jobs:run --limit 10 --queue default
bun run payload jobs:run --limit 10 --queue default
Handle scheduled jobs
处理定时任务
bun run payload jobs:handle-schedules
undefinedbun run payload jobs:handle-schedules
undefinedDatabase Security (RLS)
数据库安全(RLS)
CRITICAL: Payload uses application-level access control by default. For production security, implement Row Level Security (RLS) at the database level:
关键提示:Payload默认使用应用级别的访问控制。为了生产环境安全,请在数据库层面实现行级安全(Row Level Security,RLS):
Why RLS Matters
RLS的重要性
- Application-level filtering can be bypassed with direct database connections
- RLS enforces security at the database level
- Even table owners cannot bypass RLS when is enabled
FORCE ROW LEVEL SECURITY
- 应用级别的过滤可以通过直接数据库连接绕过
- RLS在数据库层面强制实施安全策略
- 当启用时,即使表所有者也无法绕过RLS
FORCE ROW LEVEL SECURITY
RLS Migration Template
RLS迁移模板
Create a migration for user-data tables:
typescript
// src/migrations/YYYYMMDDHHMMSS_enable_rls.ts
import { type MigrateUpArgs, type MigrateDownArgs, sql } from "@payloadcms/db-postgres";
export async function up({ db }: MigrateUpArgs): Promise<void> {
// Helper function to check admin status
await db.execute(sql`
CREATE OR REPLACE FUNCTION is_admin()
RETURNS BOOLEAN
LANGUAGE SQL
STABLE
SECURITY DEFINER
AS $$
SELECT COALESCE(
CURRENT_SETTING('app.current_user_role', TRUE) = 'admin',
FALSE
);
$$;
`);
// Enable RLS on sensitive tables
await db.execute(sql`
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
ALTER TABLE users FORCE ROW LEVEL SECURITY;
-- Users can only access their own data
CREATE POLICY users_select_policy ON users
FOR SELECT USING (id = (SELECT get_current_user_id()) OR (SELECT is_admin()));
CREATE POLICY users_update_policy ON users
FOR UPDATE USING (id = (SELECT get_current_user_id()) OR (SELECT is_admin()));
`);
}
export async function down({ db }: MigrateDownArgs): Promise<void> {
await db.execute(sql`DROP FUNCTION IF EXISTS is_admin();`);
await db.execute(sql`ALTER TABLE users DISABLE ROW LEVEL SECURITY;`);
}为用户数据表创建迁移:
typescript
// src/migrations/YYYYMMDDHHMMSS_enable_rls.ts
import { type MigrateUpArgs, type MigrateDownArgs, sql } from "@payloadcms/db-postgres";
export async function up({ db }: MigrateUpArgs): Promise<void> {
// 检查管理员状态的辅助函数
await db.execute(sql`
CREATE OR REPLACE FUNCTION is_admin()
RETURNS BOOLEAN
LANGUAGE SQL
STABLE
SECURITY DEFINER
AS $$
SELECT COALESCE(
CURRENT_SETTING('app.current_user_role', TRUE) = 'admin',
FALSE
);
$$;
`);
// 为敏感表启用RLS
await db.execute(sql`
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
ALTER TABLE users FORCE ROW LEVEL SECURITY;
-- 用户只能访问自己的数据
CREATE POLICY users_select_policy ON users
FOR SELECT USING (id = (SELECT get_current_user_id()) OR (SELECT is_admin()));
CREATE POLICY users_update_policy ON users
FOR UPDATE USING (id = (SELECT get_current_user_id()) OR (SELECT is_admin()));
`);
}
export async function down({ db }: MigrateDownArgs): Promise<void> {
await db.execute(sql`DROP FUNCTION IF EXISTS is_admin();`);
await db.execute(sql`ALTER TABLE users DISABLE ROW LEVEL SECURITY;`);
}Tables Requiring RLS
需要RLS的表
- - User profiles and sensitive data
users - - API credentials
api_keys - - Financial transaction data
deposits - - Audit trails and usage data
usage_logs - Any table with user-specific data
- - 用户资料和敏感数据
users - - API凭据
api_keys - - 金融交易数据
deposits - - 审计日志和使用数据
usage_logs - 任何包含用户特定数据的表
Performance Optimization
性能优化
- Always add indexes on columns used in RLS policies (e.g., )
user_id - Use pattern for caching auth checks per query
(SELECT function()) - Create helper functions with for complex logic
SECURITY DEFINER
- 始终为RLS策略中使用的列添加索引(例如)
user_id - 使用模式为每个查询缓存身份验证检查
(SELECT function()) - 为复杂逻辑创建带的辅助函数
SECURITY DEFINER
Migration Workflows
迁移工作流
Development Mode vs Migrations
开发模式 vs 迁移模式
Development Mode (Push):
- Automatic schema updates via (default)
push: true - Good for rapid prototyping
- NOT for production
Migration Mode:
- Explicit schema control via migration files
- Required for production databases
- Version-controlled schema changes
开发模式(Push):
- 通过自动更新schema(默认设置)
push: true - 适合快速原型开发
- 禁止在生产环境使用
迁移模式:
- 通过迁移文件显式控制schema
- 生产数据库必需
- schema变更受版本控制
Typical Workflow
典型工作流
-
Develop locally with push mode (default)
- Make changes to Payload config
- Drizzle automatically pushes changes to local DB
-
Create migration when feature is completebash
bun run payload migrate:create feature-name -
Review generated migration before committing
-
Run migrations in production before deploymentbash
# In CI/CD pipeline bun run payload migrate && bun run build
-
在本地使用push模式开发(默认)
- 修改Payload配置
- Drizzle自动将变更推送到本地数据库
-
功能完成后创建迁移bash
bun run payload migrate:create feature-name -
提交前审查生成的迁移文件
-
部署前在生产环境运行迁移bash
# 在CI/CD流水线中执行 bun run payload migrate && bun run build
Migration Sync Issues
迁移同步问题
If you get "dev mode" warnings when running migrations:
bash
undefined如果运行迁移时出现「开发模式」警告:
bash
undefinedMark existing migrations as already run
将现有迁移标记为已执行
psql "$DATABASE_URL" -c "
INSERT INTO payload_migrations (name, batch, created_at, updated_at)
SELECT * FROM (VALUES
('20250101_000000_migration_name', 1, NOW(), NOW())
) AS v(name, batch, created_at, updated_at)
WHERE NOT EXISTS (
SELECT 1 FROM payload_migrations WHERE name = v.name
);
"
undefinedpsql "$DATABASE_URL" -c "
INSERT INTO payload_migrations (name, batch, created_at, updated_at)
SELECT * FROM (VALUES
('20250101_000000_migration_name', 1, NOW(), NOW())
) AS v(name, batch, created_at, updated_at)
WHERE NOT EXISTS (
SELECT 1 FROM payload_migrations WHERE name = v.name
);
"
undefinedProject Maintenance
项目维护
Dependency Updates
依赖更新
bash
undefinedbash
undefinedCheck for outdated packages
检查过时的包
bun outdated
bun outdated
Update specific packages
更新特定包
bun update package-name
bun update package-name
Update all packages
更新所有包
bun update
undefinedbun update
undefinedType Generation
类型生成
After modifying collections or globals:
bash
bun run generate:types修改集合或全局配置后:
bash
bun run generate:typesDatabase Connection
数据库连接
Payload uses connection pooling. Common connection strings:
- - Primary connection (often pooled)
DATABASE_URI - - Direct connection for migrations
POSTGRES_URL_NON_POOLING
Payload使用连接池。常见连接字符串:
- - 主连接(通常为池化连接)
DATABASE_URI - - 用于迁移的直接连接
POSTGRES_URL_NON_POOLING
Troubleshooting
故障排除
Migration timeout: Use non-pooled connection string
bash
undefined迁移超时:使用非池化连接字符串
bash
undefinedUse POSTGRES_URL_NON_POOLING for migrations
为迁移使用POSTGRES_URL_NON_POOLING
DATABASE_URL=$(grep POSTGRES_URL_NON_POOLING .env.local | cut -d'"' -f2)
**Drizzle schema prompts**: Answer 'n' to avoid conflicts with migrations
**Type errors after updates**: Run `bun run generate:types`DATABASE_URL=$(grep POSTGRES_URL_NON_POOLING .env.local | cut -d'"' -f2)
**Drizzle schema提示**:输入'n'以避免与迁移冲突
**更新后类型错误**:运行`bun run generate:types`Additional Resources
额外资源
- - Complete Lexical node type reference
references/lexical-format.md - - Full REST API documentation
references/rest-api.md - - RLS and security best practices
references/database-security.md - - Markdown to Lexical converter
scripts/md_to_lexical.py - - Example local API script
scripts/create-post.ts - Payload Docs: https://payloadcms.com/docs
- - 完整的Lexical节点类型参考
references/lexical-format.md - - 完整的REST API文档
references/rest-api.md - - RLS和安全最佳实践
references/database-security.md - - Markdown转Lexical转换器
scripts/md_to_lexical.py - - 本地API脚本示例
scripts/create-post.ts - Payload官方文档:https://payloadcms.com/docs