# **Chapter 7: Fusion Attributes - Precision Control of Component Behavior**
## **7.1 The Fusion Attribute Philosophy: Declarative Component Control**
Fusion attributes represent SartajPHP's revolutionary approach to connecting FrontFile markup with Component behavior. Unlike traditional frameworks where you call methods in PHP code, Fusion attributes allow you to **declare Component behavior directly in HTML** using a clean, declarative syntax.
### **7.1.1 The Problem with Traditional Approaches**
Consider how other frameworks handle component configuration:
**Imperative PHP approach (traditional):**
```php
// In controller/template
$input = new TextField();
$input->setId('username');
$input->setRequired(true);
$input->setMinLength(3);
$input->setDefaultValue('Guest');
$input->setValidationMessage('Username is required');
echo $input->render();
```
**Template directive approach (Blade/Angular):**
```html
<input type="text"
[(ngModel)]="username"
required
minlength="3"
#username="ngModel"
placeholder="Enter username">
<div *ngIf="username.errors?.required">Username is required</div>
```
Both approaches have limitations:
- **Imperative PHP**: Logic mixed with presentation, hard to maintain
- **Template directives**: Framework-specific syntax, learning curve
### **7.1.2 The Fusion Attribute Solution**
SartajPHP Fusion attributes provide a third way:
```html
<input id="txtUsername" runat="server"
type="text"
fui-setRequired=""
fui-setMinLen="3"
fui-setDefaultValue="Guest"
fui-setMsgName="Username">
```
**What makes Fusion attributes special:**
1. **Declarative**: Describe what you want, not how to do it
2. **HTML-compatible**: Uses standard attribute syntax
3. **Timing-aware**: Different prefixes for different execution phases
4. **Type-safe**: Values are properly typed for each method
5. **Discoverable**: IDE autocomplete can suggest available methods
### **7.1.3 The Mental Model: Method Calls as Attributes**
Think of Fusion attributes as **method calls translated into HTML attributes**:
```
Component Method: $component->fi_setRequired()
FrontFile Attribute: fui-setRequired=""
Component Method: $component->fu_setValue("Hello")
FrontFile Attribute: fur-setValue="Hello"
Component Method: $component->fu_setValue($dynamicVar)
FrontFile Attribute: fur-setValue="##{$dynamicVar}#"
```
This translation happens automatically during FrontFile processing.
## **7.2 The Three Fusion Prefixes: Timing is Everything**
The most crucial concept in Fusion attributes is **execution timing**. Different prefixes execute at different phases of the Component lifecycle. Fusion Attribute `fui-*` execute Fusion Methods of type `fi_` at parse phase and `fur-*` execute Fusion Methods type `fu_` at render phase. Fusion Attribute `fun-*` execute type `fi_` Fusion Methods on Parse Phase and type `fu_` Fusion Methods at Render Phase. So Fusion Attribute `fun-*` can identify automatic execution time and it is safe if you don't know how to call a fusion method.
### **7.2.1 Execution Phase Overview**
```
Component Lifecycle:
┌─────────────────────────────────────────────────────┐
│ │
│ PARSE PHASE (Initialization) │
│ ├── FrontFile parsed │
│ ├── Components created │
│ ├── fui-* attributes executed │
│ └── fun-* attributes executed type fi_* method │
│ │
│ REQUEST PROCESSING │
│ ├── Form values populated │
│ ├── Validation performed │
│ └── Gate logic executes │
│ │
│ RENDER PHASE (Output Generation) │
│ ├── fur-* attributes executed │
│ ├── fun-* attributes executed type fu_* method │
│ └── HTML generated │
│ │
└─────────────────────────────────────────────────────┘
```
### **7.2.2 fui-* (Parse Phase - "Initialization")**
**Meaning:** "Execute this during Component initialization"
**Characteristics:**
- Executes **once** when Component is created
- Runs **before** any user input is processed
- Used for **setup, configuration, validation rules**
- Calls `fi_` prefixed methods in Component class
**When to use:**
- Setting validation rules (`fui-setRequired`, `fui-setEmail`)
- Configuring Component behavior (`fui-setForm`, `fui-setMsgName`)
- Setting default values that don't change (`fui-setDefaultValue`)
- Database binding configuration
**Examples:**
```html
<!-- Validation setup -->
<input id="txt1" type="text" runat="server"
fui-setRequired=""
fui-setEmail=""
fui-setMinLen="3">
<!-- Component configuration -->
<select id="txt1" runat="server"
fui-setForm="userForm"
fui-setMsgName="Country">
<!-- Static default value -->
<input id="txt1" type="text" runat="server"
fui-setDefaultValue="United States">
```
**Behind the scenes:**
```php
// When FrontFile processes fui-setRequired=""
$component->fi_setRequired();
// When FrontFile processes fui-setMinLen="3"
$component->fi_setMinLen(3);
// When FrontFile processes fui-setDefaultValue="United States"
$component->fi_setDefaultValue("United States");
```
### **7.2.3 fur-* (Render Phase - "Runtime")**
**Meaning:** "Execute this during Component rendering"
**Characteristics:**
- Executes **every time** Component renders
- Runs **after** request processing, before HTML generation
- Used for **dynamic values, conditional output**
- Calls `fu_` prefixed methods in Component class
**When to use:**
- Setting values based on dynamic data (`fur-setValue`)
- Conditional attribute setting (`fur-_class`, `fur-_style`)
- Runtime configuration changes
- User-specific content
**Examples:**
```html
<!-- Dynamic value from Gate -->
<input id="txt1" type="text" runat="server"
fur-setValue="##{$parentgate->email}#" />
<!-- Conditional styling -->
<div id="div1" runat="server"
fur-_class="##{$isActive ? 'active' : 'inactive'}#"></div>
<!-- Runtime attribute setting -->
<img id="img1" runat="server"
fur-_src="##{$imageUrl}#"
fur-_alt="##{$imageAlt}#" />
```
**Behind the scenes:**
```php
// When FrontFile processes fur-setValue="##{$user->email}#"
// $user->email is evaluated, then:
$component->fu_setValue($evaluatedValue);
// When FrontFile processes fur-_class="active"
$component->element->setAttribute("class", "active");
```
### **7.2.4 fun-* (Auto Phase - "Smart")**
**Meaning:** "Let the framework decide when to execute"
**Characteristics:**
- **Fusion Method of type fi_** execute in Parse Phase (like `fui-*`)
- **Fusion Method of type fu_** execute in Render Phase (like `fur-*`)
- **Auto-detects** based on call of type of Fusion Method
- Can call both `fi_` and `fu_` methods depending on timing
**When to use:**
- When you're not sure about timing
- For simple cases where timing doesn't matter
- When writing generic Components/templates
**Examples:**
```html
<!-- Call of fi_setDefaultValue - executes in Parse Phase -->
<input id="txt1" runat="server" fun-setDefaultValue="USA">
<!-- Dynamic value - executes in Render Phase -->
<input id="txt1" runat="server" fun-setValue="USA">
<!-- Mixed usage -->
<select id="slt1" runat="server"
fun-setOptions="##{$optionList}#" <!-- Render Phase -->
fun-setDefaultValue="default"> <!-- Parse Phase -->
```
**The decision logic:**
```php
if (Call Fusion Method of Type "fu_*") {
// execute in Render Phase
executeAsFur($component, $method, $value);
} else {
// execute in Parse Phase
executeAsFui($component, $method, $value);
}
```
### **7.2.5 Comparison Table**
| Aspect | `fui-*` | `fur-*` | `fun-*` |
|---------------------|-------------|--------------|-------------------------------|
| **Execution Phase** | Parse Phase | Render Phase | Auto-decided |
| **Frequency** | Once | 0 to Multi | Depends on Fusion Method Type |
| **Typical Use** | Config |change outout | All cases |
| **Calls Methods** | `fi_*` Type | `fu_*` Type | Either |
| **Performance** | Best (once) | Good | Variable |
## **7.3 Method Prefix Compatibility: The fi_ vs fu_ Distinction**
Understanding the difference between `fi_` and `fu_` method prefixes in Component classes is essential for correct Fusion attribute usage.
### **7.3.1 fi_ Methods (Parse Phase Only)**
**Naming convention:** `fi_setSomething($value)`
**Characteristics:**
- **callable from `fui-*` attributes**
- Execute only once during Parse Phase
- Used for **initial setup and configuration**
- Also help in server side validation and other initial execution
- After Form Submission processing
**Typical fi_ methods:**
```php
class TextField extends \Sphp\tools\Component {
// Validation rules
public function fi_setRequired() { /* ... */ }
public function fi_setEmail() { /* ... */ }
public function fi_setMinLen($value) { /* ... */ }
// Configuration
public function fi_setForm($formId) { /* ... */ }
public function fi_setMsgName($name) { /* ... */ }
// Database binding
public function fi_bindToTable($table, $field) { /* ... */ }
// Static defaults
public function fi_setDefaultValue($value) { /* ... */ }
}
```
**Why the restriction?**
`fi_` methods often set up validation rules or configurations that must be established **before** user input is processed. If called during Render Phase, server side validation might not work correctly. So it is clear idea
for developer to mark Fusion Method with proper prefix and program The Component accordingly. So Component
work in best way.
### **7.3.2 fu_ Methods (Render Phase Preferred)**
**Naming convention:** `fu_setSomething($value)`
**Characteristics:**
- **Callable from `fur-*` attributes**
- Execute during Render Phase
- Used for **change html,css and js output**
- **Execute SQL Queries which generate HTML output**
- Anything which need to process only Render Phase
- If Front File don't render then These Methods never Call
**Typical fu_ methods:**
```php
class TextField extends Component {
// Value management
public function fu_setValue($value) { /* ... */ }
// UI state
public function fu_setAuth($permission) { /* ... */ }
public function fu_setReadonly($state) { /* ... */ }
// Dynamic attributes
public function fu_setHTMLName($Name) { /* ... */ }
public function fu_setHTMLID($id) { /* ... */ }
}
```
### **7.3.3 The Special `_` Method**
The `_` method is a generic setter for HTML attributes:
```php
// In Component class
public function _($attributeName, $value) {
$this->element->setAttribute($attributeName, $value);
}
```
**Usage in FrontFile:**
```html
<!-- Set class attribute -->
<div runat="server" fur-_class="btn btn-primary">
<!-- Set style attribute -->
<div runat="server" fur-_style="color: ##{$textColor}#;">
<!-- Set data attributes -->
<div runat="server" fur-_data-user-id="##{$userId}#">
```
**What happens:**
```
fur-_class="btn btn-primary"
↓
$component->_("class", "btn btn-primary")
↓
$component->element->setAttribute("class", "btn btn-primary")
```
### **7.3.4 Method Prefix Rules Summary**
| From FrontFile | Can Call These Methods | Typical Usage |
|----------------|------------------------|---------------|
| `fui-*` | `fi_` methods only | Setup, validation, static config |
| `fur-*` | `fu_` methods, `_` method | Runtime values, dynamic attributes |
| `fun-*` | `fi_` or `fu_` (auto-decided) | Simple cases, generic templates |
**Golden Rule:**
- Use `fui-*` for `fi_` methods (setup)
- Use `fur-*` for `fu_` methods (runtime)
- Use `fun-*` when you don't care or it's simple
## **7.4 Expression Tags in Fusion Attributes**
Expression tags (`##{}#`) evaluated at different time. it is depend upon place of Expression Tag. Expression Tag within value of Fusion attributes evaluate at the time of call Fusion Method. Expression Tag within Component Tag
will evaluate according to Component. Few Components evaluate at render time like Pagination, Grid, Loop Components and mostly Component don't eveluate it and leave on Front File which evaluate at last from Top to Down approach.
Expression Tags can use only limited PHP syntax. It doesn't support any loop syntax, Globals, Supper Globals($_REQUEST). It has also a limited function calls and inbuilt objects only call like $parentapp,$frontobj etc.
### **7.4.1 Basic Usage**
```html
<!-- Static value (no expression) -->
<input id="txt1" type="text" runat="server" fur-setValue="Static Text">
<!-- Dynamic value with expression -->
<input id="txt1" type="text" runat="server" fur-setValue="##{$user->name}#">
<!-- Mixed content -->
<input id="txt1" type="text" runat="server" fur-setValue="Hello ##{$user->name}#!">
<!-- Expression with logic -->
<div id="div1" runat="server"
fur-_class="##{$isActive ? 'active' : 'inactive'}##{$hasError ? ' error' : ''}#">
```
### **7.4.2 Execution Timing in Different Prefixes**
**With `fui-*` (Parse Phase):**
```html
<!-- Expression evaluated ONCE during initialization -->
<input id="txt1" type="text" runat="server"
fui-setDefaultValue="##{date('Y-m-d')}#">
```
The expression `date('Y-m-d')` is evaluated when the Component is created, not when it renders.
**With `fur-*` (Render Phase):**
```html
<!-- Expression evaluated EACH RENDER -->
<input id="txt1" type="text" runat="server"
fur-setValue="##{date('Y-m-d')}#">
```
The expression `date('Y-m-d')` is evaluated fresh each time the Component renders.
**With `fun-*` (Auto-detected):**
```html
<!-- Auto-detected as fu_ Method (Render Phase) -->
<input id="txt1" type="text" runat="server"
fun-setValue="##{date('Y-m-d')}#">
<!-- Auto-detected as fi_ Method (Parse Phase) -->
<input id="txt1" type="text" runat="server"
fun-setDefaultValue="##{date('Y-m-d')}#">
```
### **7.4.3 Variable Scope in Expressions**
Expression tags have access to specific variables:
```html
<!-- Access Gate properties -->
<input id="txt1" type="text" runat="server"
fur-setValue="##{$parentgate->currentUser->email}#">
<!-- Access FrontFile object -->
<input id="txt1" type="text" runat="server"
fur-setValue="##{$frontobj->getComponent('otherField')->getValue()}#">
<!-- Access framework settings -->
<input id="txt1" type="date" runat="server"
fur-_placeholder="##{$sphp_settings->slib_path}# default">
<!-- Access metadata -->
<input id="txt1" type="password" runat="server"
fur-_data-page="##{$metadata->get('pageId')}#">
<!-- NOT accessible: -->
<!-- ❌ any loop -->
<!-- ❌ $_GET, $_POST, $_REQUEST -->
<!-- ❌ Arbitrary PHP functions without framework allowance -->
```
### **7.4.4 Complex Expressions and Limitations**
**Simple expressions work:**
```html
<!-- Ternary operator -->
<div id="txt1" type="text" runat="server"
fur-_class="##{$status == 'active' ? 'text-success' : 'text-muted'}#">
<!-- Concatenation -->
<input id="txt1" type="text" runat="server"
fur-setValue="##{'ID: ' . $userId}#">
<!-- Function calls (allowed ones) -->
<input id="txt1" type="text" runat="server"
fur-setValue="##{strtoupper($userName)}#">
```
**Complex logic should be in App:**
```html
<!-- ❌ Too complex for expression, Loop is not supported -->
<input runat="server"
fur-setValue="##{
$result = '';
foreach ($items as $item) {
if ($item->active) {
$result .= $item->name . ', ';
}
}
return rtrim($result, ', ');
}#">
<!-- ✅ Move to App, call method -->
<input id="txt1" type="text" runat="server"
fur-setValue="##{$parentgate->formattedItems()}#">
```
### **7.4.5 Common Fusion Issues and Solutions**
**Issue: Fusion attribute not executing**
```html
<!-- ❌ Missing runat="server" -->
<input id="txtName" type="text" fui-setRequired="">
<!-- ✅ Component created -->
<input id="txtName" type="text" runat="server" fui-setRequired="">
```
**Issue: Expression not evaluating in fui-***
```html
<!-- ❌ fui-* with dynamic expression (may not work as expected) -->
<input id="txtName" type="text" runat="server" fui-setDefaultValue="##{$dynamic}#">
<!-- ✅ Use fur-* for dynamic values -->
<input id="txtName" type="text" runat="server" fur-setValue="##{$dynamic}#">
<!-- Or calculate in Gate -->
<input id="txtName" type="text" runat="server" fui-setDefaultValue="##{$parentgate->preCalculated}#">
```
**Issue: Method not found error**
```php
// In Component class
class MyComponent extends Component {
// ❌ Missing fi_/fu_ prefix
public function setRequired() { /* ... */ }
// ✅ Correct prefix
public function fi_setRequired() { /* ... */ }
}
```
## **7.5 Best Practices**
### **7.5.1 Organization Guidelines**
1. **Group related attributes:**
```html
<!-- Parse Phase attributes together -->
<input runat="server"
<!-- Validation -->
fui-setRequired=""
fui-setEmail=""
fui-setForm="myForm"
<!-- Configuration -->
fui-setMsgName="Email"
fui-setDefaultValue=""
<!-- Render Phase attributes together -->
fur-setValue="##{$email}#"
fur-_class="##{$emailClass}#">
```
2. **Use consistent ordering:**
- `id` and `runat="server"` first
- HTML attributes next (`type`, `class`, etc.)
- `fui-*` attributes (Parse Phase)
- `fur-*` attributes (Render Phase)
- `fun-*` attributes (if used)
- Event hooks (`on-init`, etc.)
### **7.5.2 Naming Conventions**
**For custom Fusion methods:**
```php
// Clear, descriptive names
public function fi_setMaximumFileSize($size) { /* ... */ }
public function fu_setProgressPercentage($percent) { /* ... */ }
// Use consistent prefixes
public function fi_set...() // Parse Phase
public function fu_set...() // Render Phase
```
### **7.5.3 Security Considerations**
```html
<!-- ❌ $_GET not supported, no work -->
<input id="txt1" type="email" runat="server" fur-setValue="##{$_GET['param']}#">
<!-- ✅ Safe: Framework-managed -->
<input id="txt1" type="email" runat="server" fur-setValue="##{$sphp_request->request('Param')}#">
<!-- ✅ Safe: Auto-escaped or sanitized -->
<div id="txt1" runat="server">##{$userContent}#</div>
```
## **7.6 Chapter Summary**
Fusion attributes are SartajPHP's sophisticated system for declarative Component control:
1. **Three Prefixes, Three Timings:**
- `fui-*`: Parse Phase (setup, validation, static config)
- `fur-*`: Render Phase (dynamic values, runtime attributes)
- `fun-*`: Auto-detected (simple cases, generic templates)
2. **Method Prefix Compatibility:**
- `fi_` methods ← `fui-*` attributes (Parse Phase only)
- `fu_` methods ← `fur-*` attributes (Render Phase preferred)
- The `_` method ← generic attribute setting
3. **Expression Tag Integration:**
- `##{}#` tags evaluated at attribute execution time
- Access limited to safe variables (`$parentapp`, `$frontobj`, etc.)
- Keep expressions simple; complex logic belongs in App
4. **Best Practices:**
- Use `fui-*` for setup, `fur-*` for runtime
- Group attributes by phase
- Keep expressions in Fusion attributes simple
- Pre-calculate complex values in App
Fusion attributes give you precise control over when and how Component methods execute, enabling you to build complex, dynamic UIs with clean, declarative HTML. By mastering Fusion attributes, you unlock the full power of SartajPHP's Component system.
In the next chapter, we'll explore Expression Tags in depth—understanding their evaluation rules, scope limitations, and advanced patterns for dynamic content.
---
*Next: Chapter 8 dives deep into Expression Tags, covering evaluation rules, variable scope, and advanced patterns for dynamic content in FrontFiles.*