The quick answer
Inside the existing <#list record.item as item> loop, fill the aligned blank first row cell with ${item?counter}. The built-in returns the current loop iteration’s one-based position. Preview, save, and print the same invoice to verify its ordinals and unchanged figures. The expression must use the actual loop alias.
The counter counts loop iterations; conditions or nonstandard rows can make visible numbering differ.
Names and transaction values are fictional examples. This walkthrough covers four ordinary item rows in a table that already has an aligned blank first column.
Before you start
Work on a copied custom template in a sandbox or controlled test account, with its original source preserved. Advanced PDF/HTML Templates must be enabled. Use a role that can view the invoice and edit the applicable template; exact permissions and menus vary by account. Changing a shared template can affect every form that uses it.
The example invoice is INV52630 for Westfield Equipment, totaling $320.00. Its saved Dispatch Invoice form already uses Dispatch Invoice PDF/HTML Template for printing. Before starting, inspect the applicable form under Customization > Forms > Transaction Forms: Printing Type must be Advanced and Print Template must point to the copied template. The copy and assignment are prepared before the recording.
The template already has a blank first header cell and matching blank first cell in each item row. If yours does not, adding a column requires matching header cells, widths and layout checks. That layout change is outside this example.
01. Inspect the original print
Open INV52630 and confirm its Dispatch Invoice form and $320.00 total. Choose Print. The original output has one page and four items in this order: Work Gloves, Safety Glasses, Cable Ties and Tool Bag. Its first column is blank.
Check the quantities, rates, amounts and total before returning to the invoice. Leave the transaction unchanged.
02. Find the existing item loop
Go to Customization > Forms > Advanced PDF/HTML Templates, edit Dispatch Invoice PDF/HTML Template, and turn on Source Code if needed.
Find the existing <#list record.item as item> declaration and its row markup. The word item after as is the loop variable. Find the blank first <td> before the item-name cell and confirm that it aligns with the blank header cell. Preserve the surrounding table, header, widths and other cells.
03. Fill the blank counter cell
Replace only the blank content of that first cell. In this example it becomes:
<td align="left">${item?counter}</td>
Keep the cell inside the existing loop. Do not add a second loop or replace the other row cells.
?counter is a FreeMarker built-in. It returns 1 for the first iteration, then 2, 3 and so on. It is different from the property expression ${item.counter}. If your actual declaration uses as line, the matching expression is ${line?counter}.
04. Preview and save
Choose Preview to check the source and sample output. The example shows ordinals 1–4 beside the four ordinary item rows. Preview uses sample data and does not save the template or establish the actual invoice result.
Close the preview, choose Save and Edit, and confirm that the template was successfully saved. Resolve validation errors before printing the invoice. If the copied template’s result is unsuitable, restore its preserved original source and retest.
05. Compare the same invoice
Return to INV52630 from Recent Records. Confirm that its saved Dispatch Invoice form is unchanged, then choose Print again.
Check the figures: Work Gloves has 2 × $60.00 = $120.00; Safety Glasses has 3 × $25.00 = $75.00; Cable Ties has 4 × $10.00 = $40.00; and Tool Bag has 1 × $85.00 = $85.00. The total remains $320.00, and this example still has one page. The invoice itself was not edited. This result confirms this invoice and print action; verify other output paths before broader use.
The value is a loop position, so it can change if the loop’s sequence or ordering changes. It is not a stored transaction-line ID or a page counter, and it does not restart automatically at page breaks. Conditions that suppress rows inside a loop can leave gaps. Group, subtotal, discount, description and other nonstandard entries need separate review, as do nested loops, longer documents and other output paths.
Common questions
Why does item?counter fail in my template?
Check the actual list declaration and use its loop variable. ${item?counter} belongs inside a loop declared as item; a loop declared as line needs ${line?counter}. The built-in identifies that active iteration and is not a property on an item record.
Why do some printed numbers have gaps?
The counter advances with each loop iteration. If the loop still visits a row but a condition suppresses its printed output, later visible rows can have gaps. Grouped or nonstandard rows can also make the result differ from a simple visible-item count. Review that template’s logic separately.
Does the counter restart on each page?
It follows the loop rather than PDF pagination. A page break does not itself restart the loop counter. A separate loop has its own sequence. This recording demonstrates a one-page invoice.
Can I use these numbers to update a transaction line?
Use a supported transaction-line identifier for the relevant integration or editing workflow. These positions are generated during rendering rather than stored as permanent invoice line numbers. They can change with ordering, filtering and template logic, so they are not stable line IDs.
Why did Preview change but Print stayed the same?
Preview can show unsaved source with sample data. Save successfully, reopen the same invoice, and verify its saved form’s Advanced Print Template assignment and the print path you are testing. Email and bulk output require separate checks.