Skip to main content
ClaudeWave
Skill125 estrellas del repoactualizado 2mo ago

frappe-ops-website-deploy

>

Instalar en Claude Code
Copiar
git clone --depth 1 https://github.com/Impertio-Studio/Frappe_Claude_Skill_Package /tmp/frappe-ops-website-deploy && cp -r /tmp/frappe-ops-website-deploy/skills/source/ops/frappe-ops-website-deploy ~/.claude/skills/frappe-ops-website-deploy
Después abre una sesión nueva de Claude Code; el skill carga automáticamente.

SKILL.md

# Deploy Websites on ERPNext/Frappe

> Patterns for deploying static HTML/CSS websites to ERPNext v15/v16 using Web Pages, Page Builder, and the REST API.

---

## Critical: ERPNext v16 Does NOT Render main_section

In Frappe v16, the `main_section` field on a Web Page is stored but **not rendered** in the browser — even with `content_type: "HTML"` or `dynamic_template: 1`. The Page Builder (`page_blocks`) is the primary rendering mechanism.

**You must use `page_blocks` with a custom Web Template to render HTML content.**

---

## Decision Tree

```
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
```

---

## Step 1: Create the Raw HTML Section Web Template

This is a one-time setup. The template accepts raw HTML and renders it as-is.

```
POST /api/resource/Web%20Template
```

```json
{
  "name": "Raw HTML Section",
  "type": "Section",
  "template": "{{ values.html_content }}",
  "fields": [
    {
      "fieldname": "html_content",
      "fieldtype": "Text",
      "label": "HTML Content"
    }
  ]
}
```

**Important constraints:**
- The `fieldtype` must be `"Text"` — Frappe rejects `"Code"` for Web Template fields
- Allowed fieldtypes: `Attach Image`, `Check`, `Data`, `Int`, `Link`, `Select`, `Small Text`, `Text`, `Markdown Editor`, `Section Break`, `Column Break`, `Table Break`
- The template uses `{{ values.html_content }}` (with `values.` prefix) to access field data

---

## Step 2: Create Web Pages with Page Builder

Each page needs `content_type: "Page Builder"` and its HTML in `page_blocks`.

```
POST /api/resource/Web%20Page
```

```json
{
  "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>\"}"
    }
  ]
}
```

**Critical: `web_template_values` is a JSON string, not an object.** Serialize it with `json.dumps()` before sending.

### Updating an existing page

```
PUT /api/resource/Web%20Page/{url_encoded_name}
```

To find a page by route:
```
GET /api/resource/Web%20Page?filters=[["route","=","my-page"]]&fields=["name"]
```

---

## Step 3: Configure Website Settings

```
PUT /api/resource/Website%20Settings/Website%20Settings
```

```json
{
  "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 Wrapper Fixes

Frappe wraps page content in several divs that add unwanted whitespace. Add these fixes to `head_html`:

```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>
```

These are the **only** `!important` overrides you should use — they target Frappe's own wrapper elements, not your content.

---

## CSS Management

### The golden rule: keep your mockup CSS intact

Use the original mockup CSS in each page's `css` field. Only add Frappe wrapper fixes in `head_html`. Do not layer `!important` overrides on top of your content CSS — this leads to cascading conflicts and unpredictable layouts.

### Where CSS goes

| CSS Type | Where | Field |
|----------|-------|-------|
| Mockup/page CSS | Per Web Page | `css` |
| Google Fonts, Frappe fixes | Website Settings | `head_html` |
| CSS variables (:root) | Website Settings | `head_html` |

### What NOT to do

Never add broad `!important` overrides for content elements like `.card`, `section`, `h2`, etc. If spacing looks wrong, the cause is almost always a Frappe wrapper div — fix that specifically rather than overriding all your content styles.

---

## Deploying from HTML Mockups

When converting a static HTML mockup to ERPNext Web Pages, follow this process:

### 1. Extract the body content

Strip everything outside the main content area — typically between `</header>` and `<footer>`. Remove the mockup's own nav and footer since Frappe provides its own via Website Settings.

### 2. Rewrite links

Replace `.html` file references with Frappe routes:
```
href="about.html"  →  href="/about"
href="index.html"  →  href="/"
```

### 3. Handle images

Local `img/` references won't work on ERPNext. Options:
- Upload images via Frappe File Manager and use the returned URL
- Use the File API: `POST /api/method/upload_file`
- Reference external image URLs

### 4. Deploy script pattern

See `scripts/deploy.py` for a complete deployment script. The key pattern:

```python
import requests, json

def deploy_page(title, route, html_content, css):
    data = {
        "title": title,
        "route": route,
        "published": 1,
        "show_tit