Definition
cfinclude is a ColdFusion (CFML) tag that inserts and executes the content of another template inside the current page at runtime. In simple words, it “pastes” a separate CFML file into your page when the request runs, allowing you to reuse code such as headers, footers, Navigation, email bodies, and other partials. The included file runs in the same request and shares the calling page’s variable scope.
How It Works
The Basics
When a request hits a ColdFusion page that contains cfinclude, the engine:
- Resolves the path of the template attribute (or include statement).
- Compiles the included template if needed (ColdFusion compiles CFML to bytecode).
- Executes that included code within the calling page’s context.
- Sends any output into the current page’s output stream unless you buffer or suppress it.
Because the included template runs in the same context, it can read and write the calling page’s variables (the Variables and Request scopes are shared). This is powerful, but it also means you must be careful with naming collisions.
Path resolution and Mappings
- Relative paths are typically resolved relative to the including template’s directory.
- Paths starting with “/” are resolved relative to the web root (or virtual root).
- You can define application-specific mappings (this.mappings in Application.cfc) or server-level mappings in the ColdFusion Administrator, and refer to them in your includes, e.g., /views/header.cfm.
- Use expandPath() to programmatically resolve paths if needed.
Syntax Examples
Tag-Based Example
#pageTitle#
CFScript Example
// In a .cfm or .cfc running in script mode
variables.pageTitle = “Dashboard”;
include “/includes/header.cfm”;
writeOutput(“
#variables.pageTitle#
“);
include “/includes/footer.cfm”;
Conditional and Whitelisted Dynamic Includes
allowed = {
home = “/views/home.cfm”,
about = “/views/about.cfm”,
help = “/views/help.cfm”
};
page = structKeyExists(url, “page”) ? url.page : “home”;
if (structKeyExists(allowed, page)) {
include allowed[page];
} else {
include “/views/404.cfm”;
}
This pattern avoids unsafe user-controlled paths by whitelisting allowed templates.
Common Use Cases
Reusing Layout and Partials
- Headers, footers, Navigation bars, and sidebars.
- Reusable form fragments or shared UI components.
- Modular page sections for maintainable templates.
Emails and Notifications
- Keep email bodies in .cfm partials and compose messages by including the right fragments based on context (e.g., Password reset vs. Marketing emails).
Configuration or Environment-Specific Blocks
- Include a config.cfm that sets variables and flags for the current environment.
- Swap in environment-specific partials (e.g., feature flags or banners) via whitelisted dynamic includes.
Prototyping and Rapid development
- Break large pages into smaller, understandable chunks without creating full components (CFCs) or Custom tags.
Step-by-Step: Building a Layout with CFInclude
1) Define Application Mappings (Optional but Recommended)
In Application.cfc:
this.mappings[“/views”] = expandPath(“/app/views”);
this.mappings[“/partials”] = expandPath(“/app/partials”);
This makes references to /views and /partials stable, even if your app moves.
- /partials/header.cfm: Uses variables.pageTitle if set, defaults otherwise.
- /partials/footer.cfm: Outputs site footer, links, and scripts.
3) Compose a Page Template
variables.pageTitle = “Reports”;
#variables.pageTitle#
Welcome to the reports dashboard.
4) Add Conditional Sections
<cfif structKeyExists(session, “isAdmin”) AND session.isAdmin>
This lets you show or hide UI sections without duplicating code.
Best practices
Keep Includes Focused on Presentation
- Treat includes as partials or view fragments; avoid embedding heavy Business logic.
- Use CFCs and functions for logic; use includes for markup assembly.
Avoid User-Controlled Paths
- Never feed URL or form values directly to template.
- Always use a whitelist or mapping of allowed templates to prevent directory traversal and code injection.
Manage Variable Scope Carefully
- Included files share the caller’s Variables scope. To prevent conflicts:
- Use distinctive variable names.
- Wrap view-state into a struct like variables.view or local variables if inside a function.
- Consider cfparam to enforce required inputs in included files.
Prefer Mappings Over Deep Relative Paths
- Mappings make your includes robust and portable.
- They simplify refactors and reduce path mistakes.
Handle Errors Gracefully
- Wrap includes in cftry/cfcatch if a missing or failing include should not break a page.
- Log meaningful errors to help diagnose missing templates or path issues.
Performance Considerations
- CFInclude itself is fast; included templates are compiled and cached by the engine.
- For heavy fragments, consider:
- cfcache or function-level caching for data retrieval.
- Static HTML generation for content that rarely changes.
Comparisons and Alternatives
-
CFInclude:
- Simple “paste and run” of CFML.
- Shares variable scope with caller.
- Best for partial views and small reusable fragments.
-
Custom Tags (cf_ prefix) or cfmodule:
- Encapsulate behavior with attributes (inputs).
- Provide clearer interfaces and isolation.
- Better for reusable UI widgets with parameters.
-
CFC Methods:
- Proper Encapsulation and testability.
- Ideal for Business logic and data operations.
- Pair with includes for final markup assembly.
CFInclude vs cfimport/cfcomponent-based Views
- cfimport lets you use tag libraries, including UI components, often offering more structure and Encapsulation than a raw include.
- Choose based on how much isolation, parameterization, and reuse you need.
Security Notes
Avoid Directory Traversal
- Do not allow template paths like url.template to be passed directly to CFInclude.
- Always map user choices to a safe internal list.
Use Per-Application Security
- Mappings defined in Application.cfc (this.mappings) help prevent accidental path leaks.
- Sandbox security or constrained file access in the server can enforce additional restrictions.
Sanitize Output
- Included templates should still properly escape user data to prevent XSS.
- Keep “include files” clean and focused to reduce attack surface.
Real-World Example: Templated Email System
Problem: A SaaS app sends multiple types of emails (welcome, Password reset, invoice). Marketing wants to update headers/footers without touching code logic.
Solution:
- Store email body layouts as partials: /emails/header.cfm, /emails/footer.cfm, /emails/reset.cfm, /emails/invoice.cfm.
- Compose emails by including the right body between header and footer.
- Allow A/B testing by whitelisting multiple body templates.
Example:
variables.subject = “Reset your password”;
variables.resetLink = “https://example.com/reset?token=#urlEncodedFormat(token)#”;
This keeps marketing-controlled content in partials, while developers handle token creation and sending logic elsewhere (CFCs or services).
Key Points
- CFInclude executes another CFML template inside the current page at runtime.
- It shares the calling page’s scope; be mindful of variables.
- Use mappings, whitelists, and structured includes to keep code safe and maintainable.
- Great for reusable partials like headers, footers, and email fragments.
- Consider custom tags or CFCs when you need stronger encapsulation and parameters.
Advanced Tips
H5: When to Prefer CFScript include
- Teams standardizing on CFScript often prefer the include statement for readability in script-heavy code.
- You can combine script include with output-buffering techniques (e.g., cfsavecontent or writeOutput accumulation) to control placement more precisely.
H5: Integrate With Output Buffering
- Use cfsavecontent to capture included output into a variable, then manipulate or cache it.
Example:
This pattern is useful when you need to inject the HTML later or cache the rendered fragment.
FAQ
What is the difference between cfinclude and a custom tag or cfmodule?
- cfinclude executes another template inline and shares the caller’s variables; it’s simple and quick.
- A custom tag (via cf_ prefix or cfmodule) encapsulates functionality with attributes, offering better isolation and a clearer API. Use custom tags for reusable components with parameters; use cfinclude for small partials.
How do I pass data to an included template?
- Set variables in the caller before including. The included template can read variables from the same Variables/Request scopes.
- To avoid collisions, group data in structs like variables.view or arguments (inside functions).
Can I include .html or .txt files?
- Yes. CFInclude can include non-CFML files as raw text, which will be sent to the output stream. This is handy for static fragments, but be cautious about path safety and output encoding.
Is cfinclude cached? Will it slow my site?
- ColdFusion compiles templates and caches the compiled form. The act of including is fast. If the included code does heavy work (queries, complex logic), consider caching data/results separately (e.g., query caching, cfcache, or function-level caching).
Can I include a CFC or call a component method with cfinclude?
- No. cfinclude expects a template file (like .cfm). To use CFC logic, create a component and call its methods; then render results with includes or output in your view.
