Proposal Templates
Build reusable proposal documents visually — stack blocks, pick a theme, and drop in variables that automatically populate project data, equipment lists, and cost summaries.
Overview
The visual proposal builder lets you assemble professional proposal documents from blocks:
- Cover page, executive summary, and rich text sections
- Equipment blocks for individual rooms or all rooms combined (cards or table layout), with an optional Include add alternates switch that prints your optional rooms as marked boxes
- Investment summary with customizable splits and tax lines, plus an optional Add alternates table and Acceptance checklist
- Images and side-by-side column layouts
- Terms & acceptance with optional signature, print name and title lines
Getting Started
- Go to Settings > Proposal Templates
- Click New for a blank template, or New from gallery to start from a themed design
- In the builder, click blocks in the Add Block palette to stack them, and drag to reorder
- Select a block to configure it; long text (Rich Text, Terms, Executive Summary fallback) opens in the wide content workspace below the block stack
- Insert variables from the searchable browser next to the editor — the live preview fills them with sample data
- Design the cover page (hero image, headline, logos) back on the Proposal Templates page
- Save, then choose the template when generating a proposal from a project
They keep generating proposals exactly as before — they just can't be edited anymore. Rebuild them in the block builder when you need to make changes.
Add Alternates
A proposal can show your optional rooms as add alternates, extras the client may accept on top of the base price. A room becomes optional through Mark optional (right-click it in the rooms list), and optional rooms join one alternate through Create Group in the Detailed Summary. See Rooms → Add/Alt Groups for the steps.
Every optional (Add Alt) room counts. A group prints as one alternate, and an optional room that is in no group prints as an alternate of its own. Alternates are numbered in the order they print: groups first, then the ungrouped rooms. An alternate with no lines and a total of zero does not print. With Show prices off, a priced alternate with no lines is skipped and its number is not reused.
Alternates print only when you turn them on in the block settings. The switches are off by default.
- Room Equipment and All Equipment blocks: the Include add alternates checkbox
- Investment Summary block, in the Add alternates group: the Add alternates table and Acceptance checklist checkboxes
With a switch on, the proposal prints:
- Include add alternates — each alternate as a dashed box after the base rooms. The box is headed "OPTIONAL · ADD ALTERNATE 1" (then 2, 3 and so on), carries the note "Not included in base total", and ends with an "ADD TO BASE" line that shows the alternate's total including tax when prices are shown.
- Add alternates table — an "Add Alternates" table under the Investment Summary, with one row per alternate, the summary's own money columns and an "Add" column.
- Acceptance checklist — an "ACCEPTANCE" box under the Investment Summary. It starts with "Base Proposal only" at the System Total, then has one line per alternate.
The base total never includes alternates.
The {'{'}all.equipment.addalt{'}'} variable is unchanged and still prints its plain equipment table. See the Add Alt Total Variables heading below for the matching totals.
Alternates that replace a room
The steps are in Rooms → Add/Alt Groups → Linked alternates. In short, to offer a substitute for a room, duplicate it as an alternate. The alternate then prints as a difference from the room it replaces. Its amount carries a sign: a plus for an add and a minus for a deduct. The base total still never includes it.
- Box eyebrow and closing line — a Deduct alternate costs less than the room it replaces. Its box is headed "OPTIONAL · DEDUCT ALTERNATE 2" and ends with "DEDUCT FROM BASE" and a minus amount, such as "DEDUCT FROM BASE - $1,100.00". An alternate that costs more is headed "OPTIONAL · ADD ALTERNATE 2" and ends with "ADD TO BASE" and a plus amount. When the two cost the same there is No change: the box is headed "OPTIONAL · ALTERNATE 2" and ends with "NO CHANGE TO BASE $0.00".
- In lieu of — the note of a box reads "In lieu of Boardroom · Not included in base total". In a group box the note stays "Not included in base total", and each linked room carries "(in lieu of Boardroom)" after its name.
- Alternates table — when any alternate deducts or changes nothing, the table is titled "Alternates", its sub-line reads "Optional. Add or deduct any alternate from the base total." and its last column is headed "Add / Deduct". When every alternate adds, the table keeps the title "Add Alternates" and the column "Add". The amounts of linked alternates carry their sign.
- Acceptance checklist — a linked alternate reads "Deduct Alt 2: Boardroom (Alt) · in lieu of Boardroom", "Add Alt 2: …" or "Alt 2 (no change): …". When two or more alternates replace the same room, a note after the last of them reads "Alternates 2 and 3 both replace Boardroom. Choose one."
An alternate with a broken link prints at full price as an add alternate, the same as an optional room that replaces nothing.
With one flat freight charge for the project, freight is not part of a Deduct or Add, because swapping rooms does not change it; the two room boxes therefore differ by more than the Deduct.
The Sales Summary PDF, the Financial Report, the Tables Only output and the project.addAlt.* variables do not use the links. They show every optional room at its full price, linked or not.
Variable Reference
Variables are placeholders that get replaced with actual project data. Insert them from the variable browser in the content workspace, or type them directly using the {'{'}variable.name{'}'} syntax inside Rich Text, Terms, and Executive Summary blocks.
Project Variables
| Variable | Description | Example Output |
|---|---|---|
{'{'}project.name{'}'} | Project name | Corporate HQ AV System |
{'{'}project.jobNumber{'}'} | Job/reference number | 2026-0108 |
{'{'}project.status{'}'} | Current status | In Progress |
{'{'}project.total{'}'} | Project total cost | $125,450.00 |
{'{'}project.equipmentTotal{'}'} | Equipment total | $98,500.00 |
{'{'}project.laborTotal{'}'} | Labor total | $26,950.00 |
Client Variables
| Variable | Description |
|---|---|
{'{'}client.company{'}'} | Bill-to company name |
{'{'}client.contact{'}'} | Bill-to contact name |
{'{'}client.address{'}'} | Full bill-to address |
{'{'}client.email{'}'} | Bill-to email |
{'{'}client.phone{'}'} | Bill-to phone |
Date Variables
| Variable | Description | Example Output |
|---|---|---|
{'{'}date.today{'}'} | Current date | February 4, 2026 |
{'{'}date.proposal{'}'} | Proposal date | February 4, 2026 |
{'{'}date.year{'}'} | Current year | 2026 |
Equipment Tables
Equipment tables display product information for rooms. You can use default columns or specify custom columns.
All Equipment (All Rooms)
| Variable | Description |
|---|---|
{'{'}all.equipment{'}'} | Equipment table for all rooms with default columns (Room, Item, Qty, Price) |
{'{'}all.equipment:columns{'}'} | Custom columns. Example: {'{'}all.equipment:Description,Qty,Extended{'}'} |
{'{'}all.equipment.addalt{'}'} | Equipment table for Add Alt rooms only |
{'{'}all.equipment.addalt:columns{'}'} | Add Alt equipment with custom columns |
Available Equipment Columns
- Description - Product description
- Make - Manufacturer name
- Model - Product model number
- Notes - Line item notes
- Qty - Quantity
- Rate - Unit sell price
- Extended - Extended price (Qty x Rate)
Combined Cost Tables
Combined cost tables provide a room-by-room financial summary, showing equipment costs, non-equipment costs, taxes, and totals.
Combined cost tables give you a professional cost summary similar to what you'd find on a formal proposal or invoice.
Combined Cost Variables
| Variable | Description |
|---|---|
{'{'}project.combinedCost{'}'} | Default combined cost table for all rooms (shows #, Room, Qty, Sys. Cost, Total w/Tax) |
{'{'}project.combinedCost:columns{'}'} | Custom columns version |
{'{'}project.addAlt.combinedCost{'}'} | Combined cost table for Add Alt rooms only |
{'{'}project.addAlt.combinedCost:columns{'}'} | Add Alt combined cost with custom columns |
Available Combined Cost Columns
| Column Name | Header | Description |
|---|---|---|
Item | # | Row number |
RoomName | Room | Room name |
EquipmentSellEa | Equip. Sell | Equipment sell price per room |
NonEquipmentSellEa | Non-Equip. | Non-equipment sell (labor, etc.) per room |
Taxes | Tax | Taxes per room |
TaxesExt | Tax Ext. | Taxes extended (Tax x Qty) |
CostPerRoom | Cost/Room | Total cost per room (before tax) |
Qty | Qty | Room quantity |
SystemCost | Sys. Cost | System cost (Cost/Room x Qty) |
SystemCostWithTax | Total w/Tax | System cost with tax (includes tax x Qty) |
Example Usage
<h3>Cost Summary</h3>
<div style="font-size: 14px;">
{'{'}project.combinedCost:RoomName,Qty,SystemCost,SystemCostWithTax{'}'}
</div>
Add Alt Total Variables
Display totals for Add Alt (optional/alternative) rooms as simple values (not tables). These follow the same naming convention as the project totals:
| Variable | Description |
|---|---|
{'{'}project.addAlt.total{'}'} | Total of all Add Alt rooms (before tax) |
{'{'}project.addAlt.tax{'}'} | Total tax for all Add Alt rooms |
{'{'}project.addAlt.totalWithTax{'}'} | Total of all Add Alt rooms including tax |
{'{'}project.addAlt.equipmentTotal{'}'} | Total equipment sell for all Add Alt rooms |
{'{'}project.addAlt.laborTotal{'}'} | Total non-equipment (labor, services) for all Add Alt rooms |
Example Usage
<h3>Optional Items</h3>
{'{'}project.addAlt.combinedCost:RoomName,Qty,SystemCostWithTax{'}'}
<p><strong>Add Alt Total:</strong> {'{'}project.addAlt.totalWithTax{'}'}</p>
Text Wrapping Control
Control how text wraps in table columns by adding :wrap or :nowrap after any column name.
Syntax
| Modifier | Description | Example |
|---|---|---|
:wrap | Force text to wrap onto multiple lines | RoomName:wrap |
:nowrap | Prevent text from wrapping (single line) | Description:nowrap |
Smart Defaults
Most columns have sensible defaults, so you only need to add modifiers when overriding:
| Default Behavior | Columns |
|---|---|
| Wrap (text columns) | Description, Notes, RoomName |
| No wrap (short/numeric) | Make, Model, Qty, Rate, Extended, all cost columns |
Examples
<!-- Equipment table with Description that doesn't wrap -->
{'{'}room.equipment:Description:nowrap,Make,Model,Qty{'}'}
<!-- Cost table with RoomName that wraps -->
{'{'}project.combinedCost:RoomName:wrap,Qty,SystemCost,SystemCostWithTax{'}'}
Room Loops
Use loops to repeat content for each room in the project.
Regular Room Loop
{'{'}#foreach room{'}'}
<h3>{'{'}room.name{'}'}</h3>
<p>Quantity: {'{'}room.quantity{'}'}</p>
<p>Room Total: {'{'}room.total{'}'}</p>
{'{'}room.equipment{'}'}
{'{'}room.summary{'}'}
{'{'}'/'}foreach{'}'}
Add Alt Room Loop
Use {'{'}#foreach addalt{'}'} to loop through Add Alt (optional/alternative) rooms only:
{'{'}#foreach addalt{'}'}
<h3>Optional: {'{'}room.name{'}'}</h3>
{'{'}room.equipment:Description,Qty,Extended{'}'}
{'{'}'/'}foreach{'}'}
Room Loop Variables
| Variable | Description |
|---|---|
{'{'}room.name{'}'} | Current room name |
{'{'}room.index{'}'} | 1-based room index |
{'{'}room.quantity{'}'} | Room quantity |
{'{'}room.total{'}'} | Room total cost |
{'{'}room.equipment{'}'} | Equipment table with default columns |
{'{'}room.equipment:columns{'}'} | Equipment table with custom columns |
{'{'}room.summary{'}'} | Room executive summary (if uploaded) |
Best Practices
- Use <div> not <span> when wrapping table variables. Tables are block elements and cannot be inside inline elements like spans.
- Don't place tables inside heading tags (h1-h6). Put the heading first, then the table variable on the next line.
- Use the variable browser to insert variables - they're inserted as protected chips that survive editor formatting.
- Use Code View (the
</>button) in a Rich Text block to inspect HTML structure if tables aren't rendering correctly.
Correct Table Wrapper
<!-- CORRECT: Use div for table variables -->
<div style="font-size: 14px;">
{'{'}project.combinedCost:RoomName,Qty,SystemCost,SystemCostWithTax{'}'}
</div>
<!-- WRONG: Don't use span -->
<span style="font-size: 14px;">{'{'}project.combinedCost{'}'}</span>
Correct Heading Usage
<!-- CORRECT: Heading separate from table -->
<h3>Equipment List</h3>
{'{'}room.equipment{'}'}
<!-- WRONG: Table inside heading -->
<h3>{'{'}room.equipment{'}'}</h3>
Other Variables
Room Lists
| Variable | Description |
|---|---|
{'{'}all.rooms{'}'} | Comma-separated list of all room names |
{'{'}all.addalts{'}'} | Comma-separated list of Add Alt room names |
{'{'}all.summary{'}'} | Full executive summary (all rooms) |
Specific Room Access
Access a specific room by name (remove spaces from room name):
| Variable | Description |
|---|---|
{'{'}room.ConferenceRoomA.equipment{'}'} | Equipment table for a specific room |
{'{'}room.ConferenceRoomA.total{'}'} | Total for a specific room |
{'{'}room.ConferenceRoomA.summary{'}'} | Summary for a specific room |
- The builder's live preview shows the whole proposal with sample data and updates as you edit
- Variables that don't match any data (like
{{project.addAlt.combinedCost}}when there are no Add Alt rooms) render as empty, not as literal text - Create multiple templates for different proposal styles (detailed, summary, etc.)
