mcpField
F
frappe-ops-website-deploy

frappe-ops-website-deploy

github.com/impertio-studio云与 DevOps19897 次安装30 周前更新
代码仓库

关于 frappe-ops-website-deploy

frappe-ops-website-deploy 是用于将静态 HTML/CSS 网站部署到 ERPNext v15/v16 的技能。内容涵盖 Page Builder、REST API、样式与图片处理及内置讨论功能,并说明 v16 的页面渲染限制。

主要功能

  1. 01Page Builder 部署指导
  2. 02原始 HTML 的 Web Template 配置
  3. 03Web Page 与 Website Settings API 模式
  4. 04CSS 放置与包装元素修正
  5. 05讨论论坛集成指导
  6. 06认证与部署故障排查

适用场景

  1. 01将静态 HTML 模型页面部署为 ERPNext 页面
  2. 02通过 REST API 更新页面和站点设置
  3. 03为网站添加讨论论坛

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/impertio-studio/frappe_claude_skill_package --skill frappe-ops-website-deploy

安装后在 Claude Code 中输入/frappe-ops-website-deploy确认已加载。

附带文件references/frappe-wrapper-elements.mdscripts/deploy.py

详细介绍

在 ERPNext/Frappe 上部署网站

使用 Web Pages、Page Builder 和 REST API,将静态 HTML/CSS 网站部署到 ERPNext v15/v16 的模式。


重要:ERPNext v16 不会渲染 main_section

在 Frappe v16 中,Web Page 上的 main_section 字段会被存储,但不会在浏览器中渲染——即使设置了 content_type: "HTML" 或 dynamic_template: 1 也是如此。Page Builder(page_blocks)是主要的渲染机制。

必须使用 page_blocks 和自定义 Web Template 来渲染 HTML 内容。


决策树

What do you need?
├── Deploy HTML pages to ERPNext
│   ├── Step 1: Create "Raw HTML Section" Web Template (one-time)
│   ├── Step 2: Create Web Pages with page_blocks
│   └── Step 3: Configure Website Settings
│
├── Add a forum / discussion system
│   └── Use Frappe's built-in Discussion Topic/Reply + Discussions Web Template
│
├── Manage CSS
│   ├── Per-page CSS → Web Page `css` field
│   ├── Global CSS → Website Settings `head_html`
│   └── WARNING: Never stack !important overrides (see CSS Management)
│
└── Configure navigation
    └── Website Settings: top_bar_items, footer_items, brand_html, home_page

第 1 步:创建 Raw HTML Section Web Template

这是一次性设置。该模板接受原始 HTML 并按原样渲染。

POST /api/resource/Web%20Template
{
  "name": "Raw HTML Section",
  "type": "Section",
  "template": "{{ values.html_content }}",
  "fields": [
    {
      "fieldname": "html_content",
      "fieldtype": "Text",
      "label": "HTML Content"
    }
  ]
}

重要限制:

  • fieldtype 必须为 "Text"——Frappe 不接受 Web Template 字段使用 "Code"
  • 允许的字段类型:Attach Image、Check、Data、Int、Link、Select、Small Text、Text、Markdown Editor、Section Break、Column Break、Table Break
  • 模板使用 {{ values.html_content }}(带 values. 前缀)访问字段数据

第 2 步:使用 Page Builder 创建 Web Pages

每个页面都需要设置 content_type: "Page Builder",并将 HTML 放入 page_blocks。

POST /api/resource/Web%20Page
{
  "title": "Page Title",
  "route": "my-page",
  "published": 1,
  "show_title": 0,
  "full_width": 1,
  "content_type": "Page Builder",
  "css": "<per-page CSS here>",
  "page_blocks": [
    {
      "web_template": "Raw HTML Section",
      "web_template_values": "{\"html_content\": \"<div>Your HTML here</div>\"}"
    }
  ]
}

重要:web_template_values 是 JSON 字符串,而不是对象。 发送前请使用 json.dumps() 将其序列化。

更新现有页面
PUT /api/resource/Web%20Page/{url_encoded_name}

按路由查找页面:

GET /api/resource/Web%20Page?filters=[["route","=","my-page"]]&fields=["name"]

第 3 步:配置 Website Settings

PUT /api/resource/Website%20Settings/Website%20Settings
{
  "home_page": "home",
  "brand_html": "<span style=\"...\">NL</span> My Brand",
  "head_html": "<link href=\"fonts.css\" rel=\"stylesheet\">\n<style>/* global CSS */</style>",
  "top_bar_items": [
    {"label": "About", "url": "/about", "right": 0}
  ],
  "footer_items": [
    {"label": "About", "url": "/about"}
  ]
}
head_html:修复 Frappe 包装元素

Frappe 会将页面内容包裹在多个 div 中,从而产生多余的空白。将以下修复添加到 head_html:

<style>
.page-header-wrapper { display: none !important; }
.page-breadcrumbs { display: none !important; }
.page-content-wrapper { padding: 0 !important; margin: 0 !important; }
.page_content { padding: 0 !important; margin: 0 !important; }
.webpage-content { padding: 0 !important; margin: 0 !important; }
.web-page-content { padding: 0 !important; margin: 0 !important; max-width: none !important; }
.section.section-padding-top { padding-top: 0 !important; }
.section.section-padding-bottom { padding-bottom: 0 !important; }
.web-template-section { padding: 0 !important; margin: 0 !important; }
main { padding: 0 !important; margin: 0 !important; }
</style>

这些是你应该使用的唯一 !important 覆盖规则——它们针对的是 Frappe 自身的包装元素,而不是你的内容。


CSS 管理

黄金法则:保留原始样稿 CSS

在每个页面的 css 字段中使用原始样稿 CSS。只在 head_html 中添加 Frappe 包装元素修复。不要在内容 CSS 上叠加 !important 覆盖规则——这会造成层叠冲突和不可预测的布局。

CSS 的放置位置
CSS 类型位置字段
样稿/页面 CSS每个 Web Pagecss
Google Fonts、Frappe 修复Website Settingshead_html
CSS 变量(:root)Website Settingshead_html
不要这样做

不要为 .card、section、h2 等内容元素添加宽泛的 !important 覆盖规则。如果间距看起来不对,原因几乎总是 Frappe 的某个包装 div——应针对该元素修复,而不是覆盖所有内容样式。


从 HTML 样稿部署

将静态 HTML 样稿转换为 ERPNext Web Pages 时,请按以下流程操作:

1. 提取 body 内容

删除主要内容区域以外的所有内容——通常是 </header> 和 <footer> 之间的内容。移除样稿自带的导航栏和页脚,因为 Frappe 会通过 Website Settings 提供自己的导航栏和页脚。

2. 重写链接

将 .html 文件引用替换为 Frappe 路由:

href="about.html"  →  href="/about"
href="index.html"  →  href="/"
3. 处理图片

本地 img/ 引用在 ERPNext 上无法使用。可选方案:

  • 通过 Frappe File Manager 上传图片,并使用返回的 URL
  • 使用 File API:POST /api/method/upload_file
  • 引用外部图片 URL
4. 部署脚本模式

完整的部署脚本请参阅 scripts/deploy.py。核心模式如下:

import requests, json

def deploy_page(title, route, html_content, css):
    data = {
        "title": title,
        "route": route,
        "published": 1,
        "show_title": 0,
        "full_width": 1,
        "content_type": "Page Builder",
        "css": css,
        "page_blocks": [{
            "web_template": "Raw HTML Section",
            "web_template_values": json.dumps({"html_content": html_content})
        }]
    }
    # Create or update (check 409 conflict for existing pages)
    resp = requests.post(f"{BASE_URL}/api/resource/Web%20Page",
                         headers=HEADERS, json=data)
    if resp.status_code == 409:
        # Find and update existing
        ...

将论坛集成到 Frappe Discussions

Frappe 内置了可嵌入任意 Web Page 的讨论 DocType。

可用的 DocType
  • Discussion Topic — 与参考文档关联的讨论串/主题
  • Discussion Reply — 主题中的回复
创建论坛页面

将内置的 "Discussions" Web Template 用作页面区块:

{
  "page_blocks": [
    {
      "web_template": "Raw HTML Section",
      "web_template_values": "{\"html_content\": \"<section><div class=\\\"container\\\"><h1>Forum</h1></div></section>\"}"
    },
    {
      "web_template": "Discussions",
      "web_template_values": "{\"title\": \"Discussies\", \"cta_title\": \"Nieuw onderwerp\", \"docname\": \"forum\", \"single_thread\": 0}"
    }
  ]
}
讨论 Web 模板字段
字段类型用途
title数据区块标题
cta_title数据新建主题的按钮文本
docname链接要关联讨论的网页
single_thread复选框0 = 多个主题,1 = 单个讨论串
通过 API 管理主题
POST /api/resource/Discussion%20Topic
{"subject": "My topic", "reference_doctype": "Web Page", "reference_docname": "forum"}

POST /api/resource/Discussion%20Reply
{"topic": "TOPIC0001", "reply": "My reply text"}

身份验证

所有 API 调用都需要通过令牌标头进行身份验证:

Authorization: token {api_key}:{api_secret}

在 ERPNext 中生成 API 密钥:用户设置 → API 访问 → 生成密钥。

切勿将 API 密钥存储在技能文件、SKILL.md 中,也不要将其提交到 git。 请将其作为环境变量传入,或从安全配置中读取。


故障排除

页面空白 / main_section 未渲染

你遇到了 v16 页面构建器问题。请切换为 content_type: "Page Builder" 和 page_blocks。参见步骤 2。

内容上方出现白条

Frappe 的 .page-header-wrapper 和 .page-breadcrumbs 会增加空白。通过 head_html 隐藏它们。参见步骤 3。

创建 Web 模板时出现字段类型错误

字段类型请使用 "Text",不要使用 "Code"。Frappe Web 模板仅允许使用部分字段类型。

CSS 显示异常 / 间距不正确

检查 Frappe 的 .section.section-padding-top 或 .page-content-wrapper 是否添加了内边距。请针对它们进行修复,不要使用 !important 覆盖内容 CSS。

网格布局折叠为单列

如果你的模型 CSS 中包含会覆盖网格列数的媒体查询,这些规则也会应用于 ERPNext。请检查渲染后的 CSS 是否存在冲突的媒体查询规则。

图片未显示

模型中的本地 img/ 路径无法解析。请将文件上传到 ERPNext,或使用绝对 URL。

评论

支持 Markdown