Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>Portal CMSNew to Visual Studio Code? Get it now.
Portal CMS

Portal CMS

gzbang

|
3 installs
| (0) | Free
Headless CMS inside VSCode — schema builder, content editor, JSON export
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Portal CMS

在 VSCode 中运行的本地 Headless CMS 插件

Portal CMS 是一个完全运行在 VSCode 内部的内容管理系统插件。它不依赖服务器或数据库,所有内容以 JSON 文件形式存储在工作区的 .cms/ 目录中,并可一键导出为标准扁平化 JSON,直接供前端项目使用。


它解决什么问题

构建博客、官网、文档站等前端项目时,开发者常常面临一个矛盾:需要结构化内容管理,但部署一套完整的 Headless CMS 又过于繁重。

Portal CMS 提供了第三条路:

  • 内容在本地以 JSON 文件存储,与代码一起纳入 Git 版本控制
  • 编辑界面在 VSCode 中,无需离开开发环境
  • 导出格式扁平、结构清晰,前端代码可直接使用

功能特性

  • 内容类型定义:通过图形化 Schema Builder 定义内容结构,支持 7 种字段类型
  • 条目管理:列表 / 新建 / 编辑 / 删除,支持草稿与发布两种状态
  • 媒体管理:从本地选择图片/文件,自动复制到 .cms/content/{slug}/media/ 目录
  • 嵌套组件:component 类型字段支持任意层级嵌套
  • 一键导出:单类型导出或全量导出,输出扁平化 JSON 文件
  • 远程开发兼容:所有文件 I/O 通过 vscode.workspace.fs,支持 Remote SSH / Dev Container
  • 零配置启动:打开任意文件夹,点击侧边栏图标即自动初始化

系统要求

依赖 版本要求
Visual Studio Code >= 1.89.0
工作区 需要打开文件夹(不支持无工作区模式)

安装

方式一:应用市场安装

Extensions 面板 → 搜索 "Portal CMS" → Install

方式二:手动安装 .vsix

Ctrl+Shift+P → Extensions: Install from VSIX...

使用教程

1. 打开面板

安装后有两种方式打开 Portal CMS:

  • 点击左侧活动栏中的 Portal CMS 图标
  • 点击任意编辑器标签右侧的 CMS 入口图标

首次打开时,插件会自动在工作区根目录创建 .cms/ 目录并完成初始化。


2. 创建内容类型

内容类型(Content Type)定义了一类内容的数据结构,例如"文章"、"产品"、"团队成员"等。

步骤:

  1. 点击面板左侧导航底部的 "+ 新建内容类型" 按钮
  2. 填写名称(如 Article),Key 会自动生成为小写形式(article),创建后不可更改
  3. 可选填写描述,帮助团队成员理解该内容类型的用途
  4. 依次点击 "+ 添加字段" 添加所需字段
  5. 点击 "保存" 完成创建

字段类型说明:

类型 说明 示例用途
string 单行文本,可设最大/最小长度 标题、名称、URL
text 多行长文本 正文、描述、Markdown 内容
number 整数或浮点数,可设范围 价格、排序权重、数量
boolean 开关(true/false) 是否置顶、是否启用
date 日期时间,ISO 8601 格式 发布日期、截止时间
media 图片或文件引用 封面图、附件、头像
component 嵌套结构,可包含上述所有类型 作者信息、SEO 配置、地址

component 类型支持任意层级嵌套,例如:

字段:author(component)
  └── name   (string)
  └── email  (string)
  └── avatar (media)

编辑已有内容类型: 在左侧导航悬停内容类型名称,点击出现的编辑图标即可修改字段,但 Key 不可变更。


3. 录入条目

内容类型创建完成后,在左侧导航点击对应类型名称进入条目列表。

新建条目:

  1. 点击右上角的 "+ 新建" 按钮
  2. 在编辑器中依次填写各字段内容
  3. 点击右下角 "保存" 按钮

编辑条目: 在列表中点击任意条目即可重新打开编辑器。

删除条目: 打开编辑器后点击左下角 "删除" 按钮,确认后条目文件将从磁盘删除,关联的媒体文件同步清理。


4. 草稿与发布状态

每条条目都有两种状态,可在编辑器底部切换:

  • 草稿(Draft):publishedAt 为空,不会出现在导出文件中,适合未完成或待审核的内容
  • 已发布(Published):publishedAt 记录发布时间,正常出现在导出文件中

条目列表顶部会显示当前内容类型的草稿数量,方便快速了解发布状态。


5. 媒体文件管理

media 类型字段支持从本地选择图片或文件:

  1. 在条目编辑器中点击媒体字段的 "选择文件" 按钮
  2. 在弹出的系统文件选择框中选择文件
  3. 文件自动复制到 .cms/content/{slug}/media/ 目录,同名文件会直接覆盖

保存成功后,媒体文件在列表中可直接预览;点击文件名可在 VSCode 编辑器中打开原文件。删除条目时,不再被任何条目引用的媒体文件会被自动清理。

导出 JSON 中的媒体字段保存的是工作区相对路径(如 .cms/content/article/media/cover.png),前端可根据项目的静态资源处理方式进行引用。


6. 导出 JSON

点击条目列表右上角的导出按钮:

  • 绿色"发布并导出":存在未发布草稿时显示,点击后将所有草稿标记为已发布并导出
  • 黄色"重新导出":有条目变更尚未导出时显示
  • 灰色"导出":内容已是最新状态

导出文件位于 .cms/export/ 目录,文件名为内容类型 Key 的复数形式(如 articles.json、products.json)。


7. 在前端项目中使用

导出的 JSON 文件可直接在前端项目中使用,字段位于顶层,无嵌套 attributes。

通用用法(ES Module import):

import articlesData from '../.cms/export/articles.json'

// 过滤已发布条目
const articles = articlesData.data.filter(a => a.publishedAt !== null)

articles.forEach(a => {
  console.log(a.title)        // 自定义字段直接访问
  console.log(a.documentId)   // 唯一 ID(nanoid)
  console.log(a.publishedAt)  // 发布时间
})

Vue 3 示例:

<script setup>
import { computed } from 'vue'
import articlesData from '../.cms/export/articles.json'

const articles = computed(() =>
  articlesData.data.filter(a => a.publishedAt !== null)
)
</script>

<template>
  <article v-for="a in articles" :key="a.documentId">
    <h2>{{ a.title }}</h2>
    <img v-if="a.cover" :src="https://github.com/opensourceways/vscode-portal-cms/raw/HEAD/a.cover.url" :alt="a.cover.name" />
    <p>{{ a.body }}</p>
  </article>
</template>

Next.js / Nuxt 静态生成示例:

// next.js - getStaticProps
import articlesData from '../../.cms/export/articles.json'

export async function getStaticProps() {
  const articles = articlesData.data.filter(a => a.publishedAt !== null)
  return { props: { articles } }
}

.cms/ 目录结构

.cms/
├── manifest.json                    # 元数据(版本号 + slug 列表 + 脏标记)
├── schemas/
│   └── article.json                 # 内容类型定义(字段结构)
├── content/
│   └── article/
│       ├── v7l2kpx3n8eq.json        # 单条条目(文件名 = 条目 ID)
│       ├── m4rqzw9y1jce.json
│       └── media/                   # 该内容类型的媒体文件
│           └── cover.png
└── export/
    └── articles.json                # 导出的扁平化 JSON

建议将 .cms/ 整体纳入 Git 版本控制,内容与代码统一管理。若只需版本控制结构定义而不提交内容数据,可在 .gitignore 中排除 .cms/content/。


开发指南

环境准备

git clone <repo>
cd vscode-portal-cms
yarn install    # 安装所有 workspace 依赖
yarn compile    # 初次构建(extension + webview)

工具要求:Node.js >= 18.x,yarn >= 1.22。

开发模式

推荐在两个终端分别运行:

# 终端 1:监听 extension 变更
yarn watch:ext

# 终端 2:监听 webview 变更
yarn watch:ui

或直接按 F5,launch.json 配置的 watch:all 任务会同时启动两个 watcher。

调试流程

  1. 按 F5(选择 Run Extension (Watch))启动 Extension Development Host
  2. 在 Development Host 窗口中打开一个文件夹
  3. 点击活动栏的 Portal CMS 图标

修改 Extension 代码后: esbuild 自动重新打包,Ctrl+R 重载 Development Host。

修改 Webview 代码后: Vite 自动重新打包,关闭面板后重新打开即可。

调试 Webview JS:

Development Host → Ctrl+Shift+P → Developer: Open Webview Developer Tools

构建与发布

yarn vscode:prepublish   # 生产模式构建(minify)
yarn package             # 打包为 .vsix(需要 @vscode/vsce)

代码结构与核心设计请参阅 docs/design.md。


常见问题

Q:.cms/ 目录应该提交到 Git 吗?

建议提交。内容与代码同步管理,团队成员克隆后立即拥有完整数据。若只是本地草稿,可在 .gitignore 中排除 .cms/content/。

Q:插件在 Remote SSH / Dev Container 中可以用吗?

可以。所有文件操作使用 vscode.workspace.fs,I/O 自动路由到远程文件系统。

Q:为什么打开面板时显示空白?

请先运行 yarn compile,然后按 Ctrl+R 重载 Development Host 窗口。

Q:导出的媒体路径是绝对路径还是相对路径?

相对路径(以工作区根目录为基准),例如 .cms/content/article/media/cover.png。前端通过 Vite 的静态资源处理或 CDN 上传均可使用。

Q:如何重置 CMS 数据?

直接删除工作区中的 .cms/ 目录,重新打开面板后自动重新初始化。

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft