Includes

BoxLang's include system allows you to merge templates together for code reuse, with full scope absorption and dynamic template execution.

Template includes are BoxLang's server-side inclusion mechanism that embeds one template into another at runtime. When you include a template, it becomes part of the current execution context with complete access to all scopes in the including template.

📋 Table of Contents

🎯 What Are Includes?

An include is a file that is embedded (or included) within another file, making it part of the current execution. The included template has complete access to the including template's scopes.

Key Characteristics

Runtime Merging - Templates are merged at execution time

Scope Absorption - Included templates inherit all parent scopes

Bidirectional Access - Both templates can read/write shared variables

Dynamic Execution - Template paths can be computed at runtime

Multiple Formats - Script and template syntax supported

Common Use Cases

  • Header/Footer Templates - Shared site layouts

  • Utility Functions - Reusable function libraries

  • Configuration Files - Shared settings and constants

  • Mixins - Injecting helper methods into contexts

  • Partial Views - Reusable UI components

Modern Term: In object-oriented programming, this pattern is called a mixin - a class/template that provides methods for use by other classes/templates without requiring inheritance.

📝 Include Syntax

BoxLang provides multiple syntax options for including templates:

Script Syntax

Template Syntax

Include Attributes

Attribute
Type
Required
Default
Description

template

string

✅ Yes

-

Path to template file (relative, absolute, or mapping)

externalOnly

boolean

❌ No

false

If true, prevents including templates from within classes

Syntax Examples

🔄 Scope Absorption

The most important characteristic of includes is complete scope absorption. When a template is included, it has full access to all scopes in the including template.

How Scope Absorption Works

Bidirectional Access

Both the including and included templates can read and write shared variables:

main.bxm:

helper.bxm:

Scope Access Example

process-helper.bxm:

Scope Visibility Comparison

Scope
Included Template Access
Can Modify

Variables

✅ Full

✅ Yes

Local

✅ Full

✅ Yes

Arguments

✅ Full

✅ Yes

This

✅ Full

✅ Yes

Application

✅ Full

✅ Yes

Session

✅ Full

✅ Yes

Request

✅ Full

✅ Yes

Server

✅ Full

✅ Yes

CGI

✅ Full

❌ Read-only

Form

✅ Full

✅ Yes

URL

✅ Full

✅ Yes

Practical Scope Examples

Example 1: Shared Utility Functions

main.bxm:

utils/string-helpers.bxm:

Example 2: Configuration Mixin

app.bxm:

config/settings.bxm:

Example 3: Function Scope Access

order-processor.bxm:

🗺️ Template Path Resolution

BoxLang resolves template paths using multiple strategies:

Path Types

Path Type
Example
Resolution

Relative

"includes/header.bxm"

Relative to current template directory

Absolute

"/var/www/app/shared.bxm"

Absolute filesystem path

Mapping

"/app/includes/util.bxm"

BoxLang mapping (starts with /mapping/)

Dot-Notation

"../shared/functions.bxm"

Parent directory traversal

Path Resolution Examples

Dynamic Path Resolution

Path Resolution Algorithm

⚙️ Configuration

You can configure which file extensions BoxLang will process as valid templates using the validTemplateExtensions setting in boxlang.json.

Default Template Extensions

BoxLang includes these core template extensions by default:

  • .bxs - BoxLang script

  • .bxm - BoxLang markup (template)

  • .bxml - BoxLang XML

  • .cfm - ColdFusion markup

  • .cfml - ColdFusion markup language

  • .cfs - ColdFusion script

Adding Custom Extensions

boxlang.json:

Note: The validTemplateExtensions array is additive - it adds to the core extensions, not replaces them. You don't need to include .bxm, .cfm, etc. as they're always available.

Allow All Extensions

Use the wildcard * to allow any extension to be processed as a template:

boxlang.json:

Configuration Examples

Example 1: Add Custom Extensions

Example 2: Development vs Production

Extension Validation Process

From Configuration.java:

Template Extension Best Practices

Use Standard Extensions - Stick to .bxm, .cfm, .cfs when possible ✅ Descriptive Custom Extensions - Use .inc for includes, .part for partials ✅ Avoid Wildcards - Don't use * in production environments ✅ Document Custom Extensions - Make custom extensions clear to your team ❌ Don't Override Security - Don't allow dangerous extensions like .exe, .dll

📚 Use Cases

layout.bxm:

includes/header.bxm:

Use Case 2: Function Libraries

main.bxm:

Use Case 3: Configuration Mixins

Application.bx:

Use Case 4: ColdBox Framework Mixins

ColdBox allows mixin injection at runtime:

Use Case 5: Dynamic Partial Loading

💡 Best Practices

1. Use Descriptive Naming

2. Organize Includes in Directories

3. Document Scope Dependencies

4. Avoid Circular Includes

5. Use Include Guards for One-Time Execution

6. Prefer Composition Over Includes

7. Secure Include Paths

⚠️ A Stern Warning

Easy ≠ Maintainable

Just because includes are easy doesn't mean they're the right solution. Modern design patterns often provide better alternatives:

Better Alternatives

Pattern
Use Instead Of
Benefits

Components

Function includes

Encapsulation, testability, reusability

Dependency Injection

Config includes

Loose coupling, flexibility

Composition

Mixin includes

Clear dependencies, maintainability

Modules

Library includes

Namespacing, versioning, isolation

Services

Utility includes

Stateful operations, lifecycle management

🔀 Includes vs Other Patterns

Includes vs Components

Advantages of Components:

  • Clear dependencies

  • Easier to test

  • No scope pollution

  • Better encapsulation

Includes vs Dependency Injection

Includes vs Modules

📋 Summary

BoxLang includes provide powerful template merging:

Full Scope Absorption - Included templates access all parent scopes

Flexible Syntax - Script, template, and CFML compatibility

Dynamic Paths - Relative, absolute, and mapping-based resolution

Configurable Extensions - Control which files are valid templates

Bidirectional Access - Both templates can read/write shared data

⚠️ Use Sparingly - Consider components, DI, and composition first

CFML Compatibility: BoxLang's include system is fully compatible with ColdFusion's <cfinclude> tag and behavior, making migration seamless.

Last updated

Was this helpful?