Skip to content

Conditional Logic and Rules

One template often has to produce contracts that aren’t identical. An NDA signed by a company needs different recital language than one signed by an individual. A clause about sanctions screening should only appear when the party is flagged. Maintaining a separate template for every combination quickly becomes unmanageable.

Conditional logic solves this inside a single template. You tag a block of text with a condition, and at generation time Pactly keeps the block or drops it based on the values that came in from the intake form. One template, many shapes of output.

The three ways to make content conditional

Section titled “The three ways to make content conditional”

Pactly templating has three tags for showing and hiding content. They differ in how the condition is expressed, not in what they produce.

TagWhen to use it
{{if X}}…{{/if}}Show content when a single variable or party attribute is true. The simplest case.
{{rule Name}}…{{/rule}}Show content based on a named rule defined on the template, so the logic lives in one place and the document stays readable.
{{rules expr}}…{{/rules}}Show content based on a boolean expression combining several flags with &&, `

All three drop or keep the wrapped content. The choice is about where the logic lives and how complex it is.

Every conditional tag works in two forms, and the difference matters.

Block form puts the opening and closing tags each on their own paragraph, wrapping one or more whole paragraphs. When the condition is false, the entire section is removed, including the paragraph breaks.

{{if hasWarranty}}
5. WARRANTY. The Supplier warrants that the Services will be
performed in a professional manner consistent with industry
standards.
{{/if}}

Inline form keeps the tags and the content inside a single line of running text.

The fee is payable {{if isAnnual}}annually{{/if}}{{if !isAnnual}}monthly{{/if}} in advance.

Use block form for clauses and sections, inline form for a word or phrase inside a sentence. A block tag must occupy its own paragraph end to end, and an inline tag cannot span a line break: the whole tag, including the content it wraps, has to stay on one line.

The {{if}} tag checks one flag and keeps the content when it is true. Prefix the name with ! to keep the content when it is false or undefined.

{{if requiresInsurance}}
The Contractor shall maintain commercial general liability
insurance of not less than {{@currency}}{{insuranceAmount}}.
{{/if}}
{{if !requiresInsurance}}
The Contractor is not required to maintain separate insurance
for the Services.
{{/if}}

The flag is usually a boolean variable mapped to a form field, or a party attribute such as party1.isEntity or party1.isSanctioned.

The most common branch is a party signing as a company versus as a person. Party attributes resolve directly in conditions, so you write the two recitals side by side and let party1.isEntity choose between them.

{{if party1.isEntity}}
BETWEEN: {{party1.entityName}}, a company incorporated in
{{party1.country}} (Registration No. {{party1.entityRegNo}})
(the "Company").
{{/if}}
{{if !party1.isEntity}}
BETWEEN: {{party1.firstName}} {{party1.lastName}} of
{{party1.address}} (the "Individual").
{{/if}}

At generation time only one of the two blocks survives, and the variables inside it fill from the party’s record. The reader of the finished contract never sees the branch that was dropped.

A rule is a named condition you define once on the template, then reference by name in the document. It keeps the Word file readable ({{rule Sanctioned}} says what it means) and lets one condition drive many clauses without repeating the logic.

{{rule Sanctioned}}
SANCTIONS. The parties acknowledge that one or more parties
to this Agreement is subject to sanctions screening, and
agree to the enhanced compliance obligations set out in
Schedule 2.
{{/rule}}

Rules support negation the same way {{if}} does:

{{rule !Exempt}}
Standard compliance terms apply to this Agreement.
{{/rule}}

Rules are defined in the template’s rule configuration, where each rule has a name and is tied to a variable or value map. A rule built on a value map can be exclusive (matches one specific choice) or combine several choices with AND / OR. Because the definition lives in one place, changing what “Sanctioned” means updates every clause that references it.

When the decision depends on more than one flag, use {{rules}} with a boolean expression. The expression combines flags with && (and), || (or), ! (not), and parentheses for grouping.

{{rules isCommercial && hasApproval}}
This commercial agreement has received the required internal
approvals.
{{/rules}}
{{rules (Sanctioned || SensitiveEntity) && isCommercial}}
Enhanced due diligence requirements apply to this commercial
engagement.
{{/rules}}

This is also the supported way to express “both A and B,” since conditional tags cannot be nested. Replace the nesting with a single && expression:

Instead of nesting {{if A}}{{if B}}…{{/if}}{{/if}}, write:
{{rules A && B}}
Text shown only when both A and B are true.
{{/rules}}

When two flags each have two states, there are four possible outcomes. Rather than nesting, write one {{rules}} block for each combination. Exactly one block survives for any given contract.

{{rules A && B}}
Text shown when both A and B are true.
{{/rules}}
{{rules A && !B}}
Text shown when A is true but B is false.
{{/rules}}
{{rules !A && B}}
Text shown when B is true but A is false.
{{/rules}}
{{rules !A && !B}}
Text shown when neither A nor B is true.
{{/rules}}

This pattern scales: a multi-select form field can drive several rule statements so that one section renders a different combination of sub-clauses for each contract, without a separate template per variant.

A flag counts as false when it is unset, empty, or explicitly false. If a form field that drives a condition is left blank, the condition is treated as false and any {{if X}} or {{rule X}} block keyed to it is dropped (and its ! counterpart kept). Plan your negated branches with that in mind, so a missing answer produces sensible language rather than nothing.

Conditions that key off a dropdown selection depend on the choice label matching in several places at once: the contract property’s options, each form field’s list options, and the template’s value map and rule definitions. Editing a label in one place without the others silently breaks the condition: the rule stops matching and its clause never appears. When you rename or add a choice, update it everywhere it is referenced, then test-generate to confirm the clause still renders.

Because conditional logic only fails at generation time, treat every change to it as something to verify, not assume.

Chat with us

We typically reply within a few minutes