Components
BoxLang components are reusable blocks of code that extend the language's capabilities without modifying the parser.
BoxLang components are reusable blocks of code that extend the language's capabilities without modifying the parser. They provide a powerful way to create custom language constructs, encapsulate complex logic, and build modular applications. They are analogous to web components. Here is a super simple example of a component that outputs a greeting:
Greeting.bxm
<bx:output>
<h1>Hello, #attributes.yourname ?: "None Passed"#!</h1>
</bx:output>Now I can call it in my BoxLang script:
// In a BoxLang script
bx:_greeting yourname="World";Or in a BoxLang template:
<bx:_greeting yourname="World">This will output:
<h1>Hello, World!</h1>This simple example illustrates how components allow you to encapsulate functionality and reuse it across your BoxLang applications. Components can be as simple or complex as needed, and they can include attributes, logic, and even nested content.
📋 Table of Contents
Why Components Matter
Components solve common development challenges:
Eliminate Code Duplication: Write once, use everywhere
Extend the Language: Create custom block constructs that feel native
Encapsulate Logic: Keep complex operations contained and testable
Cross-Context Usage: BoxLang components work seamlessly in both script and template contexts
Basic Principles
Component Syntax
Components can be called using either script-based or template-based syntax according to where they are being used:
Script Context:
Template Context:
Component Execution Flow
When BoxLang encounters a component call, it follows this process:
Core and Module Components
Core Components
BoxLang ships with many core components that extend the language with framework capabilities. You can find them in the reference section.
Module Components
Any BoxLang module can also register and collaborate with components to the runtime.
Creating Custom Components
Custom components are user-defined components written in BoxLang that will allow you to extend the language with your own features. It will also allow you to create expressive contributions to the templating language.
Custom components can be created using two approaches:
Template-based components (
.bxmfiles): Use BoxLang's templating syntaxScript-based components (
.bxsfiles): Use pure BoxLang script syntax
Basic Custom Component Structure
Let's start with simple examples using both approaches:
Template-based Component
File: components/greeting.bxm
Script-based Component
File: components/greeting.bxs
Component Input: The attributes Scope
attributes ScopeAll data passed to your component is available in the attributes scope. Both template and script-based components can validate and process these attributes. Note that the attribute name name is reserved and is only used when invoking components via bx:component .
Template-based Component with Attributes
Script-based Component with Attributes
Component Content: The thisComponent Scope
thisComponent ScopeWhen components have start and end tags, BoxLang provides the thisComponent scope to manage content and execution. This works the same way in both template and script-based components.
The thisComponent scope contains:
executionMode: "start" or "end"hasEndTag: boolean indicating if component has closing taggeneratedContent: Content between start and end tags
Template-based Component with thisComponent
thisComponentFile: components/boldWrapper.bxm
Script-based Component with thisComponent
thisComponentFile: components/boldWrapper.bxs
Usage (same for both):
Complex Component with Start/End Logic
Here's an advanced component demonstrating the full execution cycle, shown in both template and script syntax:
Template-based Version
File: components/section.bxm
Script-based Version
File: components/section.bxs
Usage (same for both template and script versions):
Custom Component Discovery
Custom component discovery is a hierarchical lookup process that occurs when BoxLang encounters a component call that isn't a registered core or module component.
Discovery Configuration
BoxLang component locations can be defined globally or on a per-app basis.
Global Configuration (boxlang.json):
boxlang.json):Application Configuration (Application.bx):
Application.bx):File Extensions Searched
During discovery, BoxLang looks for files with these extensions in order:
.bxm(BoxLang template).bxs(BoxLang script).cfc(CFML component - for compatibility).cfm(CFML template - for compatibility)
Calling Custom Components
Method 1: Using bx:component
bx:componentScript Syntax:
Template Syntax:
Method 2: Convention-Based Calling
BoxLang looks for a component file matching the name after bx::
Script Syntax:
Template Syntax:
Component Scopes Deep Dive
The attributes Scope
attributes ScopeContains all attributes passed to the component call:
The variables Scope
variables ScopeA localized scope for the component's internal logic:
The caller Scope
caller ScopeProvides access to the calling context (use sparingly):
The thisComponent Scope
thisComponent ScopeManages component execution and content:
Associating Subtag Data with Base Tags
BoxLang provides the bx:associate component to create relationships between child components and their parent components. This powerful feature allows you to build hierarchical component structures where child components can pass data up to their parent components.
How Component Association Works
When you use bx:associate inside a child component, it creates a data structure in the parent component that contains all the associated data from its children. This enables complex component hierarchies like forms with fields, menus with items, or layouts with sections.
Basic Association Syntax
Script Syntax:
Template Syntax:
Simple Example: Menu with Menu Items
Parent Component: menu.bxm
Child Component: menuItem.bxm
Usage:
Advanced Example: Form with Form Fields
Parent Component: form.bxm
Child Components:
formField.bxm
formOption.bxm
formAction.bxm
Usage:
Key Points About bx:associate
bx:associate1. Data Collection Names
The dataCollection attribute specifies the name of the array that will be created in the parent component's thisComponent scope.
2. Automatic Array Creation
If the specified collection doesn't exist, BoxLang automatically creates it as an empty array.
3. Attribute Inheritance
All attributes from the child component are automatically added to the collection item.
4. Execution Timing
Association happens during the child component's execution, so data is available when the parent reaches its "end" execution mode.
5. Nested Associations
You can have multiple levels of association for complex hierarchies.
Advanced Pattern: Tab Container
Parent Component: tabContainer.bxm
Child Component: tab.bxm
Usage:
This association pattern enables powerful component composition where child components contribute data to their parents, creating flexible and reusable component hierarchies.
Advanced Component Patterns
Component Composition
Components can call other components for powerful composition:
Conditional Component Loading
Best Practices
1. Always Use bx:param for Attribute Validation
bx:param for Attribute ValidationTemplate-based components:
Script-based components:
2. Use Descriptive Component Names
3. Document Your Components
Template-based components:
Script-based components:
4. Minimize Use of caller Scope
caller ScopeTemplate-based components:
Script-based components:
Migration from CFML Custom Tags
BoxLang components provide enhanced functionality over CFML custom tags:
<cf_customTag>
<bx:_customTag>
<cfmodule template="path">
<bx:component template="path">
Template context only
Script and template contexts
attributes scope
attributes scope
caller scope
caller scope
thisComponent scope
thisComponent scope
Limited discovery
Enhanced discovery system
Key Advantages in BoxLang:
Components work seamlessly in both script and template contexts
Enhanced parameter validation with
bx:paramImproved discovery system with multiple lookup paths
Better error handling and debugging support
Last updated
Was this helpful?
