$npx -y skills add Impertio-Studio/Frappe_Claude_Skill_Package --skill frappe-syntax-printUse 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 wi
| 1 | # Frappe Print Formats & PDF Generation |
| 2 | |
| 3 | > Deterministic reference for print formats, Letter Head, and PDF generation in Frappe v14/v15/v16. |
| 4 | |
| 5 | --- |
| 6 | |
| 7 | ## When to Use This Skill |
| 8 | |
| 9 | USE when: |
| 10 | - Creating or modifying Print Formats (Jinja or JS) |
| 11 | - Generating PDFs programmatically (`get_pdf`, download endpoints) |
| 12 | - Configuring Letter Head (header/footer) for print output |
| 13 | - Working with Print Designer (v15+) |
| 14 | - Implementing page breaks, print CSS, or landscape layouts |
| 15 | - Building Report Print Formats ({%= %} syntax) |
| 16 | |
| 17 | DO NOT USE for: |
| 18 | - General Jinja template syntax (emails, portals) -- see `frappe-syntax-jinja` |
| 19 | - Client Script UI logic -- see `frappe-syntax-clientscripts` |
| 20 | - Web views or portal pages -- see `frappe-syntax-jinja` |
| 21 | |
| 22 | --- |
| 23 | |
| 24 | ## Decision Tree: Which Print Format Type? |
| 25 | |
| 26 | ``` |
| 27 | Need a printable/PDF document? |
| 28 | ├─ YES → Is it a Query/Script Report? |
| 29 | │ ├─ YES → Use JS Template ({%= %} microtemplate) |
| 30 | │ │ Set print_format_for = "Report" |
| 31 | │ └─ NO → Need visual drag-and-drop editor? |
| 32 | │ ├─ YES → On v15+? |
| 33 | │ │ ├─ YES → Use Print Designer (WeasyPrint) |
| 34 | │ │ └─ NO → NOT available on v14. Use Jinja. |
| 35 | │ └─ NO → Need full layout control? |
| 36 | │ ├─ YES → Use Jinja Print Format (custom_format=1) |
| 37 | │ └─ NO → Use Standard Print Format (auto layout) |
| 38 | └─ NO → This skill does not apply. |
| 39 | ``` |
| 40 | |
| 41 | --- |
| 42 | |
| 43 | ## Print Format Types |
| 44 | |
| 45 | | Type | Engine | Version | When to Use | |
| 46 | |------|--------|---------|-------------| |
| 47 | | Standard | Auto from DocType field layout | v14+ | No customization needed | |
| 48 | | Jinja | Server-side Jinja2 (wkhtmltopdf) | v14+ | Full layout control | |
| 49 | | JS Template | Client-side microtemplate | v14+ | Report print formats only | |
| 50 | | Print Designer | WeasyPrint / Chrome | v15+ | Visual drag-and-drop builder | |
| 51 | |
| 52 | ### Standard Print Format |
| 53 | |
| 54 | ALWAYS the default. Frappe auto-generates layout from DocType fields. No code needed. Controlled via Print Settings and field `print_hide` property. |
| 55 | |
| 56 | ### Jinja Print Format |
| 57 | |
| 58 | Set `custom_format = 1` on the Print Format document. Full Jinja2 with server-side rendering. |
| 59 | |
| 60 | **Context variables available in every Jinja Print Format:** |
| 61 | |
| 62 | | Variable | Type | Content | |
| 63 | |----------|------|---------| |
| 64 | | `doc` | Document | The document being printed | |
| 65 | | `meta` | Meta | DocType metadata | |
| 66 | | `layout` | list | Field layout sections | |
| 67 | | `letter_head` | str | Rendered Letter Head HTML | |
| 68 | | `footer` | str | Rendered footer HTML | |
| 69 | | `print_settings` | dict | Print Settings configuration | |
| 70 | | `frappe` | module | Full frappe module access | |
| 71 | |
| 72 | **Example — Minimal Jinja Print Format:** |
| 73 | |
| 74 | ```html |
| 75 | <h1>{{ doc.name }}</h1> |
| 76 | <p>Customer: {{ doc.customer_name }}</p> |
| 77 | <p>Date: {{ doc.posting_date | global_date_format }}</p> |
| 78 | |
| 79 | <table class="table table-bordered"> |
| 80 | <thead> |
| 81 | <tr><th>Item</th><th>Qty</th><th>Rate</th><th>Amount</th></tr> |
| 82 | </thead> |
| 83 | <tbody> |
| 84 | {% for row in doc.items %} |
| 85 | <tr> |
| 86 | <td>{{ row.item_name }}</td> |
| 87 | <td>{{ row.qty }}</td> |
| 88 | <td>{{ frappe.utils.fmt_money(row.rate, currency=doc.currency) }}</td> |
| 89 | <td>{{ frappe.utils.fmt_money(row.amount, currency=doc.currency) }}</td> |
| 90 | </tr> |
| 91 | {% endfor %} |
| 92 | </tbody> |
| 93 | </table> |
| 94 | |
| 95 | <p><strong>Grand Total:</strong> {{ frappe.utils.fmt_money(doc.grand_total, currency=doc.currency) }}</p> |
| 96 | ``` |
| 97 | |
| 98 | ### JS Template (Report Print Formats) |
| 99 | |
| 100 | ONLY for Query Reports and Script Reports. Uses `{%= %}` microtemplate syntax, NOT Jinja. |
| 101 | |
| 102 | ```javascript |
| 103 | // In report's .js file |
| 104 | {%= row.item_name %} |
| 105 | {% if (row.qty > 10) { %} |
| 106 | <strong>Bulk order</strong> |
| 107 | {% } %} |
| 108 | |
| 109 | {% for (var i = 0; i < rows.length; i++) { %} |
| 110 | <tr> |
| 111 | <td>{%= rows[i].item_name %}</td> |
| 112 | <td>{%= rows[i].qty %}</td> |
| 113 | </tr> |
| 114 | {% } %} |
| 115 | ``` |
| 116 | |
| 117 | **CRITICAL:** NEVER mix Jinja `{{ }}` and JS `{%= %}` syntax. They are completely separate template engines. |
| 118 | |
| 119 | ### Print Designer (v15+ Only) |
| 120 | |
| 121 | - Separate app: `bench get-app print_designer` |
| 122 | - Uses WeasyPrint (not wkhtmltopdf) |
| 123 | - Visual drag-and-drop builder in the browser |
| 124 | - NEVER attempt to use Print Designer on v14 -- it does not exist |
| 125 | |
| 126 | --- |
| 127 | |
| 128 | ## Letter Head |
| 129 | |
| 130 | Letter Head provides consistent header/footer across all print formats. |
| 131 | |
| 132 | ### Configuration |
| 133 | |
| 134 | | Field | Purpose | |
| 135 | |-------|---------| |
| 136 | | `source` | `"Image"` or |