frappe-agent-architect
Use when designing multi-app Frappe architectures, deciding whether to split functionality into separate apps, or implementing…
Use when creating print formats or generating PDFs in Frappe v14-v16. Covers Jinja print formats, Print Designer [v15+], Letter Head, PDF generation API (get_pdf, download_pdf), Report print formats ({%= %} syntax), page breaks, and print CSS patterns. Prevents common mistakes
Claude Code
$ npx -y skills add Impertio-Studio/Frappe_Claude_Skill_Package --skill frappe-syntax-print --agent claude-code
Codex
$ npx skills add Impertio-Studio/Frappe_Claude_Skill_Package --skill frappe-syntax-print -a codex -y
Cursor
$ npx skills add Impertio-Studio/Frappe_Claude_Skill_Package --skill frappe-syntax-print -a cursor -y
Gemini CLI
$ npx skills add Impertio-Studio/Frappe_Claude_Skill_Package --skill frappe-syntax-print -a gemini-cli -y
GitHub Copilot
$ npx skills add Impertio-Studio/Frappe_Claude_Skill_Package --skill frappe-syntax-print -a github-copilot -y
OpenCode
$ npx skills add Impertio-Studio/Frappe_Claude_Skill_Package --skill frappe-syntax-print -a opencode -y
Windsurf
$ npx skills add Impertio-Studio/Frappe_Claude_Skill_Package --skill frappe-syntax-print -a windsurf -y
name: frappe-syntax-print
description: >
Use when creating print formats or generating PDFs in Frappe v14-v16.
Covers Jinja print formats, Print Designer [v15+], Letter Head,
PDF generation API (get_pdf, download_pdf), Report print formats
({%= %} syntax), page breaks, and print CSS patterns.
Prevents common mistakes with template engine confusion and PDF rendering.
Keywords: print format, PDF, get_pdf, Jinja, Letter Head, print designer,, PDF not generating, print format broken, custom PDF, letter head, wkhtmltopdf error.
wkhtmltopdf, WeasyPrint, page-break, download_pdf.
license: MIT
compatibility: "Claude Code, Claude.ai Projects, Claude API. Frappe v14-v16."
metadata:
author: OpenAEC-Foundation
version: "3.0"> Deterministic reference for print formats, Letter Head, and PDF generation in Frappe v14/v15/v16.
---
USE when:
DO NOT USE for:
---
Need a printable/PDF document?
├─ YES → Is it a Query/Script Report?
│ ├─ YES → Use JS Template ({%= %} microtemplate)
│ │ Set print_format_for = "Report"
│ └─ NO → Need visual drag-and-drop editor?
│ ├─ YES → On v15+?
│ │ ├─ YES → Use Print Designer (WeasyPrint)
│ │ └─ NO → NOT available on v14. Use Jinja.
│ └─ NO → Need full layout control?
│ ├─ YES → Use Jinja Print Format (custom_format=1)
│ └─ NO → Use Standard Print Format (auto layout)
└─ NO → This skill does not apply.---
| Type | Engine | Version | When to Use | |------|--------|---------|-------------| | Standard | Auto from DocType field layout | v14+ | No customization needed | | Jinja | Server-side Jinja2 (wkhtmltopdf) | v14+ | Full layout control | | JS Template | Client-side microtemplate | v14+ | Report print formats only | | Print Designer | WeasyPrint / Chrome | v15+ | Visual drag-and-drop builder |
ALWAYS the default. Frappe auto-generates layout from DocType fields. No code needed. Controlled via Print Settings and field `print_hide` property.
Set `custom_format = 1` on the Print Format document. Full Jinja2 with server-side rendering.
**Context variables available in every Jinja Print Format:**
| Variable | Type | Content | |----------|------|---------| | `doc` | Document | The document being printed | | `meta` | Meta | DocType metadata | | `layout` | list | Field layout sections | | `letter_head` | str | Rendered Letter Head HTML | | `footer` | str | Rendered footer HTML | | `print_settings` | dict | Print Settings configuration | | `frappe` | module | Full frappe module access |
**Example — Minimal Jinja Print Format:**
<h1>{{ doc.name }}</h1>
<p>Customer: {{ doc.customer_name }}</p>
<p>Date: {{ doc.posting_date | global_date_format }}</p>
<table class="table table-bordered">
<thead>
<tr><th>Item</th><th>Qty</th><th>Rate</th><th>Amount</th></tr>
</thead>
<tbody>
{% for row in doc.items %}
<tr>
<td>{{ row.item_name }}</td>
<td>{{ row.qty }}</td>
<td>{{ frappe.utils.fmt_money(row.rate, currency=doc.currency) }}</td>
<td>{{ frappe.utils.fmt_money(row.amount, currency=doc.currency) }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<p><strong>Grand Total:</strong> {{ frappe.utils.fmt_money(doc.grand_total, currency=doc.currency) }}</p>ONLY for Query Reports and Script Reports. Uses `{%= %}` microtemplate syntax, NOT Jinja.
// In report's .js file
{%= row.item_name %}
{% if (row.qty > 10) { %}
<strong>Bulk order</strong>
{% } %}
{% for (var i = 0; i < rows.length; i++) { %}
<tr>
<td>{%= rows[i].item_name %}</td>
<td>{%= rows[i].qty %}</td>
</tr>
{% } %}**CRITICAL:** NEVER mix Jinja `{{ }}` and JS `{%= %}` syntax. They are completely separate template engines.
---
Letter Head provides consistent header/footer across all print formats.
| Field | Purpose | |-------|---------| | `source` | `"Image"` or `"HTML"` | | `content` | Header HTML (Jinja-rendered with `doc` context) | | `footer` | Footer HTML (Jinja-rendered, **PDF only**) | | `image` | Header image (when source = "Image") | | `align` | Image alignment: Left, Center, Right |
**IMPORTANT:** The `footer` field only displays in PDF output, never in browser print preview.
# Server-side: render Letter Head programmatically
from frappe.utils.print_format import render_letterhead_for_print
letterhead_html = render_letterhead_for_print(
letter_head_name="My Company",
doc=doc
)Letter Head `content` and `footer` fields support Jinja with `doc` context:
<!-- In Letter Head content field -->
<div style="text-align: right;">
<strong>{{ doc.company }}</strong><br>
Date: {{ doc.posting_date | global_date_format }}
</div>---
> See `references/pdf-api.md` for complete API reference.
60 deterministic Claude AI skills for Frappe Framework & ERPNext v14-v16 development and operations
Use when designing multi-app Frappe architectures, deciding whether to split functionality into separate apps, or implementing…
Use when debugging Frappe errors, using bench console for live inspection, analyzing tracebacks, or reading Frappe log files.…
Use when receiving vague or unclear ERPNext/Frappe development requests that need interpretation. Transforms requirements like…
Use when migrating a Frappe app between major versions, detecting breaking API changes, or resolving post-migration errors.…
Use when reviewing or validating Frappe/ERPNext code against best practices and common pitfalls. Checks generated code before…
Use when building ERPNext/Frappe API integrations (v14/v15/v16) including REST API, RPC API, authentication, webhooks, and rate…
Behavioral guidelines to reduce common LLM coding mistakes. Use when writing, reviewing, or refactoring code to avoid…
Design and build AI agents for any domain. Use when users: (1) ask to "create an agent", "build an assistant", or "design an AI…