frappe-agent-architect
Use when designing multi-app Frappe architectures, deciding whether to split functionality into separate apps, or implementing cross-app communication…
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
$ npx -y skills add Impertio-Studio/Frappe_Claude_Skill_Package --skill frappe-syntax-print --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/frappe-syntax-printContext preview
The summary Claude sees to decide when to auto-load this skill.
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
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
Repo: Impertio-Studio/Frappe_Claude_Skill_Package
Use when designing multi-app Frappe architectures, deciding whether to split functionality into separate apps, or implementing cross-app communication…
Use when debugging Frappe errors, using bench console for live inspection, analyzing tracebacks, or reading Frappe log files. Prevents wasted debugging time…
Use when receiving vague or unclear ERPNext/Frappe development requests that need interpretation. Transforms requirements like 'make invoice auto-calculate' or…
Use when migrating a Frappe app between major versions, detecting breaking API changes, or resolving post-migration errors. Prevents failed migrations from…
Use when reviewing or validating Frappe/ERPNext code against best practices and common pitfalls. Checks generated code before deployment, validates against all…
Use when building ERPNext/Frappe API integrations (v14/v15/v16) including REST API, RPC API, authentication, webhooks, and rate limiting. Covers external API…