Neviscater prints every menu, bill, quantity sheet and purchase order as a PDF. Four built-in report styles and the brand colour overrides cover most needs. When a report has to look exactly like your own printed menu card or your stationery, you can write a custom PDF template: a page of HTML with Twig placeholders for the data, plus optional CSS. This guide explains how templates work, walks through a complete event-menu template, and lists everything a template can use.
Custom templates are available on every plan and are managed by the account owner.
Template or report style?
- Want the same layout in different colours or a different font? Use Application Setup → Preferences → Report Styles: pick Classic, Royale, Metro or Letterhead and override the Brand Colors & Font. No template needed. See Printing and PDF Templates.
- Want a different layout — the logo on the left with the customer details beside it, item names in capitals, the bill arranged like your old invoice? That is a template.
A template is written per report type. You can have a template for the Event Menu and leave Bill Details on a built-in style.
How a template works
- Each report type can hold several templates, but only one is active. The active template is used for every print of that type by everyone in the account. A type with no active template prints in the selected built-in style.
- You write only the content of the page. Font size, background images, cover and footer artwork and the colour overrides from Preferences are applied around your content automatically.
- The data comes in as variables (the order, the event, the menu items) and as building blocks — ready-made pieces such as the company header or the grouped menu list that already follow your printing preferences.
- Templates run in a sandbox. They can print values, loop, and test conditions. They cannot include files, call functions or run code, and every value is HTML-escaped when printed.
- If an active template fails to render at print time, the report quietly prints in the built-in style instead, so a customer never receives a broken PDF.
Open the Template Studio
Application Setup → Tools & Settings → PDF Templates opens the Report Templates page: one table of every template with Report, Template, Active, Created and Actions. The report type is shown once per group, with its own + New link:
- + New Template at the top, or + New under a report type, opens the editor.
- Activate and Deactivate switch a template on or off for its type.
- Edit, Export and Delete act on one template.
- Import File at the top loads a template exported from another Neviscater account.
The editor has three tabs on the left — HTML (Twig), CSS and Reference — and a live preview on the right. The preview re-renders with sample data about a second after you stop typing. An error is shown in a red box above the preview. PDF Preview downloads the same page as a real PDF, page breaks included.
A complete example: an event menu
This template prints the company logo on the left half of the page, the customer and function facts on the right in capitals, and then the menu grouped under its sub-menu headings.
HTML (Twig)
<table class="top">
<tr>
<td class="logo"><img src="{{ company_logo() }}" alt=""></td>
<td class="facts">
<div><span class="label">Customer</span> {{ order.customer.customer_name|upper }}</div>
<div><span class="label">Function</span> {{ event.event_name|upper }}</div>
<div><span class="label">Date</span> {{ event.event_date|date("d M Y") }}</div>
<div><span class="label">Guests</span> {{ event.guests }}</div>
</td>
</tr>
</table>
{{ menu_sections(sub_menu_items_array) }}
CSS
.top { width: 100%; margin-bottom: 20px; }
.top td { vertical-align: top; width: 50%; }
.top img { max-width: 100%; max-height: 150px; width: auto; height: auto; }
.facts div { font-size: 16px !important; padding: 3px 0; }
.facts .label { display: inline-block; width: 90px; color: #777; }
.prnt-list .submenu-name { color: indigo; text-decoration: underline; font-weight: normal; }
.prnt-list .item-name { text-transform: uppercase; }
What each part does:
-
{{ company_logo() }}is the logo uploaded under Preferences → Business Details, embedded in the page. It prints nothing when no logo is uploaded. -
{{ order.customer.customer_name|upper }}prints a value through theupperfilter.|date("d M Y")formats a date. -
{{ menu_sections(sub_menu_items_array) }}is a building block: the items of the event grouped under their sub-menu headings, honouring your printing preferences for sub-menu names, Veg / Non-Veg presentation and page breaks. - The last two CSS rules restyle the block's output. The shared print stylesheet sets the font size and padding of table cells with high priority, so a size of your own on a cell or a row needs
!important, as in the.facts divrule.
Save it as, say, event-menu-v1, check the preview, then Activate it. Every Event Menu printed from then on uses it.
Writing the menu loop yourself
The building blocks are the easy path, but you can also loop over the data directly:
{% for submenu, items in sub_menu_items_array %}
<h3>{{ submenu }}</h3>
<ul>
{% for item in items %}
<li>{{ item.display_name }}{% if item.diet_type == "non_veg" %} (non-veg){% endif %}</li>
{% endfor %}
</ul>
{% endfor %}
A hand-written loop gives you total control but does not follow the printing preferences and does not handle page breaks the way the blocks do.
Variables by report type
The Reference tab in the editor lists these for the report type you are editing. print_options — your company details and printing choices — is available in every template.
| Report type | Variables |
|---|---|
| Event Menu | order (order_number, order_type, status, customer.customer_name); event (event_name, event_date, start_time, end_time, guests, specified_rate_per_plate); menu_items (flat list: display_name, display_desc, display_submenu, diet_type, diet_label); sub_menu_items_array (sub-menu name → items); menu_items_by_diet, sub_menu_items_by_diet and diet_labels for Veg / Non-Veg layouts |
| Order Menus | order; events_menuitems_array (per event: event, menu_items, menu_items_by_diet); events_submenus_items_array (per event: event, sub_menu_items_array, sub_menu_items_by_diet); diet_labels; sort_by |
| Bill Details | order (order_number, order_type, customer.customer_name, start_date_str, end_date_str, place); orderBillDetails (orderBills[] with date_str, description, ratePerUnitStr, quantity, costStr; taxes[] with name, rate, amountStr; orderBillsTotalStr, orderBillsGrandTotalStr); totalPaymentsStr; paymentOutstandingStr |
| Customer Invoice | invoiceDetails (invoice_number, status, issued_at); order from the invoice snapshot; orderBillDetails as for Bill Details |
Other report types — item quantities, raw materials, Payment Details, Receipt, misc expenses, All Resources Checklist, Item Tags, Catalog Menu and the Kitchen Plan reports — accept templates too. Their variable lists are not yet written up in the Reference tab, and their preview uses event-menu sample data; the building blocks still work.
Building blocks
| Block | Prints |
|---|---|
page_header(event) |
The company header. Use page_header(null, order) for order-level reports and page_header(null, order, true) to add the GST and FSSAI numbers |
menu_items(menu_items) |
The flat menu list, following your printing preferences |
menu_sections(sub_menu_items_array) |
Items grouped under sub-menu headings. A short group stays whole on a page; a long one flows across pages with its heading held to its first items |
bills_table(orderBillDetails, totalPaymentsStr, paymentOutstandingStr) |
Bill lines, taxes and totals; the two payment arguments are optional |
payment_footer() |
The bank, UPI and QR footer according to your printing options |
company_logo() |
The uploaded logo, for <img src="{{ company_logo() }}">; empty when none is uploaded |
Styling the blocks
The blocks render their own markup — tables, not headings and list items — so a CSS rule on h2 or li never reaches them. Style them through their classes, which the Reference tab lists under Styling the blocks:
| Selector | What it is |
|---|---|
.prnt-list |
The list printed by menu_sections / menu_items; 40px side margins by default |
.prnt-list .menu-items-list |
One section of menu_sections: a flex column that centres its lines by default. align-items: flex-start left-aligns it |
.prnt-list .submenu-name |
The section heading: centred, bold, 16px, brand colour by default |
.prnt-list .item-name |
One item: centred, 14px, brand colour by default. Items carry no numbers; number them with .prnt-list .menu-items-list { counter-reset: item } and .prnt-list .item-name::before { counter-increment: item; content: counter(item) ". " } |
.prnt-list .srno, .prnt-list .item-desc |
menu_items (the flat list) only: its table's running-number and description cells |
.prn-page-header, .ph-company-name, .ph-company-details |
The page_header() box, company name and details |
.prn-list-header, .fact, .prn-list-footer |
The bills_table() header row, bill rows and totals row |
.payment-details |
The payment_footer() box |
The blocks' own styles load after yours with single-class selectors, so the two-class selectors above win; add !important to font-size and padding rules on table cells.
Both menu blocks follow the Veg / Non-Veg on menus preference. To fix a layout in the template instead, pass the mode as a second argument — menu_sections(sub_menu_items_array, "columns") — using none, markers, sections, sections_marks, columns or columns_marks. Any other word is a template error.
What the template language allows
-
{{ … }}prints a value, HTML-escaped.{% if %},{% for %}and{% set %}are the only tags. Inside a loop,loop.indexis the running number. - Text filters:
upper,lower,capitalize,title,trim,nl2br,striptags,replace,split,join,slice,first,last,length,sort,default,escape,raw. - Number and date filters:
date,number_format,round,abs. - A missing field prints as blank rather than failing.
- Not allowed: including or extending other templates, macros, and calling methods on the data. The sandbox refuses these when the template is saved or imported, and the error names the line.
Create from Document
Have a design already — last year's printed menu card, a bill from your previous software, the menu your designer made in Word or Canva? In the editor click Create from Document and upload it: a PDF, or a JPEG, PNG, WebP or GIF, up to 10 MB. Neviscater creates a new draft template from it, named after the file (or after the name you typed), and opens it in the editor. The draft is never activated on its own, and usually needs a round of adjustment in the preview before you activate it. Conversion takes a few minutes.
A PDF exported from a design tool gives by far the best result, because Neviscater reads it rather than looking at it:
- A page that is a picture with only a few lines of text — the cover — becomes a cover page of the template, with the picture exactly as it was and its text lines (date, venue, time, guest count) placed where they were and wired to the event's details.
- The background picture the content pages share — a frame, a border, a watermark — becomes the template's page background. A trailing picture-only page becomes a closing page.
- The content pages' margins, fonts, heading sizes, numbering and capitals are measured, and the template is written to match them.
The template then carries its own artwork, listed in a strip above the editor with a view link per page and a remove link. It prints with the template while the template is active, in place of the Report Background, Cover Pages and Footer Pages chosen under Preferences → Printing for that report type; deactivate the template and the Preferences artwork is back. Templates with artwork show an Artwork badge on the Report Templates page. The artwork pages print scaled into the page's printable area, inside the 10 mm print margins.
A JPEG or a scanned PDF has no text to read, so Neviscater's AI redraws the design as HTML and CSS instead. Backgrounds and decorations are approximated, not copied; for those designs, add the original picture under Preferences → Printing as a background or cover page.
Export and import between accounts
Export downloads a template as a .nctemplate.json file holding its report type, name, HTML, CSS and, when it has any, its artwork pages with their images. Import File on another account — or on the same one, as a copy — reads such a file, checks that the template and every artwork overlay render on that system, and adds it inactive: It is not active yet — activate it when you are ready. A file that does not render is refused with the reason, and nothing is imported. Files from before artwork existed still import.
Use this to carry a design from a trial account to the live one, to share a layout between two businesses you run, or to receive a template someone designed for you.
Logos and images
-
company_logo()embeds the logo uploaded under Business Details. The uploaded logo is stored small, 60 × 60 pixels, which is fine for a header line but not for a half-page logo. - For a large logo or any other picture, paste the image into the HTML as a data URI (
<img src="data:image/png;base64,…">). It then travels with the template, including through export and import. - Full-page pictures — a cover, a frame behind every page — belong in the template's artwork, which Create from Document fills from a PDF, or in the Report Background, Cover Pages and Footer Pages under Preferences. The Preferences artwork prints around custom templates too, except while an active template brings artwork of its own. If a logo appears twice, check whether a background image for that report type already carries it.
Common questions
My template prints, but in the built-in style. The active template failed to render, so Neviscater fell back. Open it under PDF Templates → Edit and read the error above the preview. The usual causes are a misspelt variable inside a loop, or a filter that is not allowed.
My font size or padding on a cell is ignored. The shared print stylesheet sets font-size and the vertical padding of table cells with high priority. Add !important to your own rule.
The sub-menu headings are missing. menu_sections follows the Print Sub Menu Names preference. Turn it on under Preferences → Printing, or pass a mode that always prints headings, such as "sections" or "columns".
Can I change the report type of a template? No. Create a new template for the other type and copy the HTML and CSS across.
Who can see the PDF Templates page? The account owner. Everyone in the account gets the active template on their prints.
Can I keep two layouts and switch between them? Yes. Keep both under the same report type and Activate the one you want; only one is active at a time.