Includes, Layouts, and Custom Tags

Understand the reuse mechanisms that shaped classic CFML applications and learn where each one belongs.

cfinclude

An included template executes in the caller's variable context. That makes includes convenient but tightly coupled.

<!--- index.cfm --->
<cfset variables.pageTitle = "Customer Portal">
<cfinclude template="includes/header.cfm">

<p>Page content</p>

<cfinclude template="includes/footer.cfm">

The included file can read or overwrite variables from the caller. Document expected inputs and outputs or move complex behavior into a function, custom tag, or CFC.

Parameterized Includes

Because cfinclude has no formal arguments, older applications often set variables before including a template.

<cfset variables.panelTitle = "Open Tickets">
<cfset variables.panelQuery = openTickets>
<cfinclude template="includes/ticket-panel.cfm">

This works, but the dependency is implicit. A custom tag provides an explicit attributes scope.

Custom Tags

<!--- Calling template --->
<cfmodule
    template="/customtags/statusBadge.cfm"
    status="#customer.status#">
<!--- customtags/statusBadge.cfm --->
<cfparam name="attributes.status" type="string" default="unknown">

<cfswitch expression="#attributes.status#">
    <cfcase value="active"><span>Active</span></cfcase>
    <cfcase value="suspended"><span>Suspended</span></cfcase>
    <cfdefaultcase><span>Unknown</span></cfdefaultcase>
</cfswitch>

Returning a Value Through caller

<!--- customtags/calculateTotal.cfm --->
<cfparam name="attributes.quantity" type="numeric">
<cfparam name="attributes.unitPrice" type="numeric">

<cfset caller.calculatedTotal = attributes.quantity * attributes.unitPrice>
<!--- Calling template --->
<cfmodule
    template="/customtags/calculateTotal.cfm"
    quantity="3"
    unitPrice="19.95">

<cfoutput>#DollarFormat(calculatedTotal)#</cfoutput>

Start and End Modes

Paired custom tags can process body content. The tag inspects thisTag.executionMode to distinguish its opening and closing execution.

<cfswitch expression="#thisTag.executionMode#">
    <cfcase value="start">
        <section class="legacy-panel">
    </cfcase>
    <cfcase value="end">
        </section>
    </cfcase>
</cfswitch>

When to Use Each Tool

ToolBest FitRisk
cfincludeSimple shared markup and small page fragmentsImplicit shared variables and path coupling
Custom tagReusable view behavior or tag-like UI elementsCan mix business logic and presentation
User-defined functionSmall transformation with clear inputs and outputPlacement and shared scope can become unclear
CFCReusable services, gateways, and business logicIncorrect method scoping can create concurrency bugs

Legacy Layout Anti-Pattern

Some applications open HTML in a header include and close it in a footer or OnRequestEnd.cfm. A thrown exception or early cfabort can leave incomplete output. When modernizing, prefer templates whose structure is visible and balanced.