- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
359 lines
8.9 KiB
Markdown
359 lines
8.9 KiB
Markdown
# View System Overview
|
|
|
|
> Advanced template processing system with DOM manipulation, component architecture, and intelligent caching.
|
|
|
|
## 🏗 Architecture
|
|
|
|
The view system is built around **DOM-based processing** using PHP 8.4's native HTML5 parser, enabling sophisticated template manipulation while maintaining performance through intelligent caching.
|
|
|
|
### Core Components
|
|
|
|
```
|
|
src/Framework/View/
|
|
├── Engine.php # Main template engine
|
|
├── TemplateRenderer.php # Rendering coordinator
|
|
├── DomProcessor.php # DOM manipulation interface
|
|
├── RenderContext.php # Template context data
|
|
├── ComponentRenderer.php # Component system
|
|
├── Processors/ # Template processors
|
|
├── Caching/ # Multi-level caching
|
|
└── Loading/ # Template resolution
|
|
```
|
|
|
|
## 📝 Basic Usage
|
|
|
|
### Simple Template Rendering
|
|
|
|
```php
|
|
// Controller
|
|
class HomeController
|
|
{
|
|
public function index(TemplateRenderer $renderer): ViewResult
|
|
{
|
|
return new ViewResult('home', [
|
|
'title' => 'Welcome',
|
|
'user' => $user,
|
|
'stats' => $this->getStats()
|
|
]);
|
|
}
|
|
}
|
|
```
|
|
|
|
### Template Structure
|
|
|
|
```html
|
|
<!-- templates/home.view.php -->
|
|
<layout name="main">
|
|
<slot name="title">{title}</slot>
|
|
<slot name="content">
|
|
<div class="welcome">
|
|
<h1>Hello, {user.name}!</h1>
|
|
<div class="stats">
|
|
<for data="stats" as="stat">
|
|
<div class="stat-item">
|
|
<span class="value">{stat.value}</span>
|
|
<span class="label">{stat.label}</span>
|
|
</div>
|
|
</for>
|
|
</div>
|
|
</div>
|
|
</slot>
|
|
</layout>
|
|
```
|
|
|
|
## 🧩 Component System
|
|
|
|
### Component Definition
|
|
|
|
```html
|
|
<!-- components/card.view.php -->
|
|
<div class="card {classes}">
|
|
<if condition="title">
|
|
<header class="card-header">
|
|
<h3>{title}</h3>
|
|
</header>
|
|
</if>
|
|
|
|
<div class="card-body">
|
|
<slot name="content">{content}</slot>
|
|
</div>
|
|
|
|
<if condition="actions">
|
|
<footer class="card-footer">
|
|
<slot name="actions"></slot>
|
|
</footer>
|
|
</if>
|
|
</div>
|
|
```
|
|
|
|
### Component Usage
|
|
|
|
```html
|
|
<component name="card" title="User Profile" classes="profile-card">
|
|
<slot name="content">
|
|
<p>User: {user.name}</p>
|
|
<p>Email: {user.email}</p>
|
|
</slot>
|
|
|
|
<slot name="actions">
|
|
<button>Edit Profile</button>
|
|
<button>View History</button>
|
|
</slot>
|
|
</component>
|
|
```
|
|
|
|
## 🔄 Template Processors
|
|
|
|
### Available Processors
|
|
|
|
| Processor | Purpose | Documentation |
|
|
|-----------|---------|---------------|
|
|
| **LayoutTagProcessor** | Layout system implementation | [Details](processors.md#layout) |
|
|
| **ComponentProcessor** | Reusable UI components | [Details](processors.md#components) |
|
|
| **SlotProcessor** | Content injection system | [Details](processors.md#slots) |
|
|
| **IfProcessor** | Conditional rendering | [Details](processors.md#conditionals) |
|
|
| **ForProcessor** | Loop iteration | [Details](processors.md#loops) |
|
|
| **PlaceholderReplacer** | Variable substitution | [Details](processors.md#placeholders) |
|
|
| **AssetInjector** | JS/CSS asset injection | [Details](processors.md#assets) |
|
|
| **MetaManipulator** | Meta tag extraction | [Details](processors.md#meta) |
|
|
|
|
### Processing Pipeline
|
|
|
|
```
|
|
1. Structure Processors
|
|
├── LayoutTagProcessor # Apply layouts
|
|
└── IncludeProcessor # Include external files
|
|
|
|
2. Component Processors
|
|
├── ComponentProcessor # Process components
|
|
└── SlotProcessor # Handle slots
|
|
|
|
3. Logic Processors
|
|
├── IfProcessor # Conditional logic
|
|
├── ForProcessor # Loops
|
|
└── SwitchCaseProcessor # Switch statements
|
|
|
|
4. Content Processors
|
|
├── PlaceholderReplacer # Variable substitution
|
|
├── DateFormatProcessor # Date formatting
|
|
└── MetaManipulator # Meta extraction
|
|
|
|
5. Asset Processors
|
|
└── AssetInjector # CSS/JS injection
|
|
|
|
6. Optimization Processors
|
|
├── CommentStripProcessor # Remove comments
|
|
├── RemoveEmptyLinesProcessor
|
|
└── VoidElementsSelfClosingProcessor
|
|
```
|
|
|
|
## 🎯 Advanced Features
|
|
|
|
### Conditional Rendering
|
|
|
|
```html
|
|
<!-- Simple conditions -->
|
|
<if condition="user.isAdmin">
|
|
<admin-panel></admin-panel>
|
|
</if>
|
|
|
|
<!-- Complex conditions -->
|
|
<if condition="user.role === 'admin' && features.adminPanel">
|
|
<component name="admin-dashboard"></component>
|
|
</if>
|
|
|
|
<!-- If-else chains -->
|
|
<if condition="user.isAdmin">
|
|
<admin-view></admin-view>
|
|
<else-if condition="user.isModerator">
|
|
<moderator-view></moderator-view>
|
|
<else>
|
|
<user-view></user-view>
|
|
</if>
|
|
```
|
|
|
|
### Loop Iteration
|
|
|
|
```html
|
|
<!-- Simple loops -->
|
|
<for data="users" as="user">
|
|
<div class="user-card">
|
|
<h3>{user.name}</h3>
|
|
<p>{user.email}</p>
|
|
</div>
|
|
</for>
|
|
|
|
<!-- Loops with keys -->
|
|
<for data="categories" as="category" key="categoryId">
|
|
<section data-category="{categoryId}">
|
|
<h2>{category.name}</h2>
|
|
<for data="category.items" as="item">
|
|
<article>{item.title}</article>
|
|
</for>
|
|
</section>
|
|
</for>
|
|
|
|
<!-- Loops with index -->
|
|
<for data="items" as="item" index="i">
|
|
<div class="item-{i}">
|
|
Position: {i + 1} - {item.name}
|
|
</div>
|
|
</for>
|
|
```
|
|
|
|
### Layout System
|
|
|
|
```html
|
|
<!-- Layout definition: layouts/main.view.php -->
|
|
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title><slot name="title">Default Title</slot></title>
|
|
<meta name="description" content="<slot name="description"></slot>">
|
|
<slot name="head"></slot>
|
|
</head>
|
|
<body>
|
|
<header>
|
|
<nav><!-- Navigation --></nav>
|
|
</header>
|
|
|
|
<main>
|
|
<slot name="content"></slot>
|
|
</main>
|
|
|
|
<footer>
|
|
<slot name="footer">© 2024 Framework</slot>
|
|
</footer>
|
|
|
|
<slot name="scripts"></slot>
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
## 💾 Caching System
|
|
|
|
### Cache Strategies
|
|
|
|
```php
|
|
// Automatic caching based on template analysis
|
|
$cacheStrategy = $analyzer->determineCacheStrategy($template);
|
|
|
|
// Manual cache control
|
|
$context = new RenderContext($data);
|
|
$context->setCacheStrategy(CacheStrategy::FULL_PAGE);
|
|
$context->setCacheTags(['user:123', 'posts']);
|
|
$context->setCacheTtl(3600);
|
|
```
|
|
|
|
### Cache Invalidation
|
|
|
|
```php
|
|
// Tag-based invalidation
|
|
$cache->invalidateByTags(['user:123']);
|
|
|
|
// Template-based invalidation
|
|
$cache->invalidateTemplate('user-profile');
|
|
|
|
// Smart invalidation on data changes
|
|
$user->save(); // Automatically invalidates user-related caches
|
|
```
|
|
|
|
## 🔧 Template Functions
|
|
|
|
### Built-in Functions
|
|
|
|
```html
|
|
<!-- URL generation -->
|
|
<a href="{url('user.profile', {id: user.id})}">Profile</a>
|
|
|
|
<!-- Image slots with responsive images -->
|
|
<img src="{imageSlot('hero', 'medium')}"
|
|
srcset="{imageSlot('hero', 'small')} 480w,
|
|
{imageSlot('hero', 'medium')} 768w,
|
|
{imageSlot('hero', 'large')} 1200w">
|
|
|
|
<!-- Date formatting -->
|
|
<time datetime="{user.createdAt|iso8601}">
|
|
{user.createdAt|date('d.m.Y H:i')}
|
|
</time>
|
|
|
|
<!-- Asset URLs -->
|
|
<link rel="stylesheet" href="{asset('css/app.css')}">
|
|
<script src="{asset('js/app.js')}" defer></script>
|
|
```
|
|
|
|
### Custom Functions
|
|
|
|
```php
|
|
// Register custom function
|
|
$templateEngine->registerFunction('currency', function ($amount, $currency = 'EUR') {
|
|
return number_format($amount, 2, ',', '.') . ' ' . $currency;
|
|
});
|
|
```
|
|
|
|
```html
|
|
<!-- Use custom function -->
|
|
<span class="price">{product.price|currency('USD')}</span>
|
|
```
|
|
|
|
## 🎨 Integration with CSS/JS
|
|
|
|
### Asset Management
|
|
|
|
```html
|
|
<!-- Vite asset injection -->
|
|
<head>
|
|
{vite('resources/css/app.css')}
|
|
{vite('resources/js/app.js')}
|
|
</head>
|
|
|
|
<!-- Conditional assets -->
|
|
<if condition="isDevelopment">
|
|
<script src="http://localhost:3000/@vite/client" type="module"></script>
|
|
</if>
|
|
```
|
|
|
|
### Component-specific Assets
|
|
|
|
```html
|
|
<!-- components/chart.view.php -->
|
|
<div class="chart-container" data-chart="{chartData}">
|
|
<slot name="head">
|
|
<link rel="stylesheet" href="{asset('css/charts.css')}">
|
|
</slot>
|
|
|
|
<slot name="scripts">
|
|
<script src="{asset('js/charts.js')}" defer></script>
|
|
</slot>
|
|
</div>
|
|
```
|
|
|
|
## 🔍 Debugging & Development
|
|
|
|
### Template Debugging
|
|
|
|
```html
|
|
<!-- Debug mode shows processing steps -->
|
|
<debug>
|
|
Template: {template.name}
|
|
Context: {context.data|json}
|
|
Cache: {cache.status}
|
|
</debug>
|
|
```
|
|
|
|
### Performance Analysis
|
|
|
|
```php
|
|
// Template performance metrics
|
|
$metrics = $templateEngine->getMetrics();
|
|
echo "Render time: {$metrics->renderTime}ms\n";
|
|
echo "Cache hits: {$metrics->cacheHits}\n";
|
|
echo "Processors: {$metrics->processorsRun}\n";
|
|
```
|
|
|
|
---
|
|
|
|
*For detailed processor documentation, see [Template Processors](processors.md)*
|
|
*For component examples, see [Component Library](../design-system/components.md)*
|
|
*For caching strategies, see [View Caching](caching.md)* |