@aetherframework/template-engine 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +662 -0
- package/examples/basic-usage.js +217 -0
- package/examples/dist/basic-usage-result.html +31 -0
- package/examples/dist/layout-example-result.html +210 -0
- package/examples/dist/templates/layouts/main.aether +58 -0
- package/examples/dist/templates/pages/home.aether +116 -0
- package/examples/layout-example.js +404 -0
- package/examples/ssr-example.js +180 -0
- package/index.js +179 -0
- package/package.json +42 -0
- package/src/core/CacheManager.js +245 -0
- package/src/core/EngineRegistry.js +148 -0
- package/src/core/ModeManager.js +231 -0
- package/src/core/TemplateEngineFactory.js +373 -0
- package/src/engines/AetherEngine.js +582 -0
- package/src/engines/BaseEngine.js +101 -0
- package/src/engines/SSRModeEngine.js +139 -0
- package/src/engines/TemplateModeEngine.js +320 -0
- package/src/utils/ConfigLoader.js +279 -0
- package/src/utils/ErrorHandler.js +276 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Basic Usage Example - Demonstrates template rendering with enhanced syntax support
|
|
3
|
+
* This example shows how to use the TemplateEngineFactory to create and use renderers
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Import the factory function from the main index file
|
|
7
|
+
import { createEngine } from '../index.js';
|
|
8
|
+
import fs from 'fs/promises';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
11
|
+
|
|
12
|
+
// Helper function to get current directory in ES Module environment
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = path.dirname(__filename);
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Main function to run the basic usage example
|
|
18
|
+
* Demonstrates template rendering with Aether template engine using factory pattern
|
|
19
|
+
*/
|
|
20
|
+
async function run() {
|
|
21
|
+
console.log('🚀 Starting Basic Usage Example with Enhanced Syntax...\n');
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
// 1️⃣ Initialize Engine using Factory Pattern
|
|
25
|
+
console.log('1️⃣ Initializing Engine with Factory Pattern...');
|
|
26
|
+
|
|
27
|
+
// Create engine factory with template mode configuration
|
|
28
|
+
const factory = await createEngine({
|
|
29
|
+
mode: 'template', // Set rendering mode: 'template' or 'ssr'
|
|
30
|
+
cacheEnabled: true, // Enable template compilation caching for better performance
|
|
31
|
+
debug: true, // Enable debug mode to see compilation details
|
|
32
|
+
templateDir: path.join(__dirname, '../dist') // Optional: specify default template directory
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
console.log('✅ Engine factory initialized successfully\n');
|
|
36
|
+
|
|
37
|
+
// 2️⃣ Create Renderer from Factory
|
|
38
|
+
console.log('2️⃣ Creating Template Renderer...');
|
|
39
|
+
|
|
40
|
+
// Create a renderer instance using the factory
|
|
41
|
+
// The 'aether' engine name refers to the default Aether template engine
|
|
42
|
+
const renderer = factory.createRenderer('aether');
|
|
43
|
+
console.log('✅ Template renderer created successfully\n');
|
|
44
|
+
|
|
45
|
+
// 3️⃣ Define Template String with Aether Syntax
|
|
46
|
+
// Aether template engine uses Blade-like syntax with {{ }} for variables and @ directives for control structures
|
|
47
|
+
const template = `
|
|
48
|
+
<header class="header">
|
|
49
|
+
<nav class="navbar">
|
|
50
|
+
<div class="container">
|
|
51
|
+
<a class="navbar-brand" href="{{ route('home') }}">
|
|
52
|
+
<img src="{{ asset('images/logo.png') }}" alt="Logo" height="40">
|
|
53
|
+
</a>
|
|
54
|
+
|
|
55
|
+
<ul class="navbar-nav">
|
|
56
|
+
<li class="nav-item">
|
|
57
|
+
<a class="nav-link" href="{{ route('home') }}">Home</a>
|
|
58
|
+
</li>
|
|
59
|
+
<li class="nav-item">
|
|
60
|
+
<a class="nav-link" href="{{ route('about') }}">About</a>
|
|
61
|
+
</li>
|
|
62
|
+
|
|
63
|
+
@if(auth().check())
|
|
64
|
+
<li class="nav-item dropdown">
|
|
65
|
+
<a class="nav-link dropdown-toggle" href="#" role="button">
|
|
66
|
+
{{ auth().user.name }}
|
|
67
|
+
</a>
|
|
68
|
+
<div class="dropdown-menu">
|
|
69
|
+
<a class="dropdown-item" href="{{ route('profile') }}">Profile</a>
|
|
70
|
+
<a class="dropdown-item" href="{{ route('logout') }}">Logout</a>
|
|
71
|
+
</div>
|
|
72
|
+
</li>
|
|
73
|
+
@else
|
|
74
|
+
<li class="nav-item">
|
|
75
|
+
<a class="nav-link" href="{{ route('login') }}">Login</a>
|
|
76
|
+
</li>
|
|
77
|
+
<li class="nav-item">
|
|
78
|
+
<a class="nav-link" href="{{ route('register') }}">Register</a>
|
|
79
|
+
</li>
|
|
80
|
+
@endif
|
|
81
|
+
</ul>
|
|
82
|
+
</div>
|
|
83
|
+
</nav>
|
|
84
|
+
</header>`;
|
|
85
|
+
|
|
86
|
+
// 4️⃣ Define Template Data and Helper Functions
|
|
87
|
+
// These functions will be available in the template context during rendering
|
|
88
|
+
const data = {
|
|
89
|
+
// Mock authentication function - simulates user authentication state
|
|
90
|
+
auth: () => ({
|
|
91
|
+
check: () => true, // Change to false to test the @else block
|
|
92
|
+
user: {
|
|
93
|
+
name: 'John Doe',
|
|
94
|
+
email: 'john.doe@example.com',
|
|
95
|
+
role: 'admin'
|
|
96
|
+
}
|
|
97
|
+
}),
|
|
98
|
+
|
|
99
|
+
// Mock route function - generates URLs for named routes
|
|
100
|
+
route: (name) => {
|
|
101
|
+
const routes = {
|
|
102
|
+
'home': '/',
|
|
103
|
+
'about': '/about',
|
|
104
|
+
'login': '/login',
|
|
105
|
+
'register': '/register',
|
|
106
|
+
'profile': '/profile',
|
|
107
|
+
'logout': '/logout'
|
|
108
|
+
};
|
|
109
|
+
return routes[name] || '#';
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
// Mock asset function - generates URLs for static assets
|
|
113
|
+
asset: (filePath) => `/assets/${filePath}`,
|
|
114
|
+
|
|
115
|
+
// Additional template data can be added here
|
|
116
|
+
siteName: 'Aether Template Demo',
|
|
117
|
+
currentYear: new Date().getFullYear()
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
// 5️⃣ Render Template with Provided Data
|
|
121
|
+
console.log('3️⃣ Rendering Template with Enhanced Syntax...');
|
|
122
|
+
try {
|
|
123
|
+
// Use the renderer to process template with data
|
|
124
|
+
// The render method compiles the template and executes it with the provided context
|
|
125
|
+
const result = await renderer.render(template, data);
|
|
126
|
+
|
|
127
|
+
console.log('\n--- Rendered Output ---');
|
|
128
|
+
console.log(result);
|
|
129
|
+
console.log('-----------------------\n');
|
|
130
|
+
|
|
131
|
+
// 6️⃣ Save Rendered Output to File
|
|
132
|
+
console.log('4️⃣ Saving rendered output to file...');
|
|
133
|
+
const outputDir = path.join(__dirname, 'dist');
|
|
134
|
+
|
|
135
|
+
// Create output directory if it doesn't exist
|
|
136
|
+
try {
|
|
137
|
+
await fs.access(outputDir);
|
|
138
|
+
console.log('📁 Output directory already exists');
|
|
139
|
+
} catch {
|
|
140
|
+
await fs.mkdir(outputDir, { recursive: true });
|
|
141
|
+
console.log('📁 Created output directory');
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Define output file path and write the rendered HTML
|
|
145
|
+
const outputPath = path.join(outputDir, 'basic-usage-result.html');
|
|
146
|
+
await fs.writeFile(outputPath, result, 'utf-8');
|
|
147
|
+
|
|
148
|
+
console.log(`💾 HTML file saved to: ${outputPath}`);
|
|
149
|
+
console.log(`📄 File size: ${result.length} characters`);
|
|
150
|
+
|
|
151
|
+
} catch (error) {
|
|
152
|
+
// Enhanced error handling with detailed information
|
|
153
|
+
console.error('❌ Error during template rendering:');
|
|
154
|
+
console.error(` Message: ${error.message}`);
|
|
155
|
+
console.error(` Stack: ${error.stack}`);
|
|
156
|
+
|
|
157
|
+
// Provide helpful debugging information
|
|
158
|
+
console.error('\n🔧 Debugging Tips:');
|
|
159
|
+
console.error(' 1. Check template syntax for errors');
|
|
160
|
+
console.error(' 2. Verify all template functions are defined in data');
|
|
161
|
+
console.error(' 3. Ensure template uses correct Aether syntax');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// 7️⃣ Display Engine Statistics and Configuration
|
|
165
|
+
console.log('\n📊 Engine Factory Statistics:');
|
|
166
|
+
const stats = factory.getStats();
|
|
167
|
+
console.log(JSON.stringify(stats, null, 2));
|
|
168
|
+
|
|
169
|
+
// Additional debug information
|
|
170
|
+
console.log('\n🔧 Configuration Details:');
|
|
171
|
+
console.log(` - Mode: ${stats.mode}`);
|
|
172
|
+
console.log(` - Cache Enabled: ${stats.cacheEnabled}`);
|
|
173
|
+
console.log(` - Cache Size: ${stats.cacheSize}`);
|
|
174
|
+
console.log(` - Available Engines: ${stats.engines.join(', ')}`);
|
|
175
|
+
console.log(` - Template Directory: ${stats.templateDir || 'Not specified'}`);
|
|
176
|
+
|
|
177
|
+
// 8️⃣ Demonstrate Additional Factory Features
|
|
178
|
+
console.log('\n🎯 Additional Factory Features:');
|
|
179
|
+
|
|
180
|
+
// List all available engines
|
|
181
|
+
const availableEngines = factory.listEngines();
|
|
182
|
+
console.log(` Available engines: ${availableEngines.join(', ')}`);
|
|
183
|
+
|
|
184
|
+
// Show cache information if enabled
|
|
185
|
+
if (stats.cacheEnabled) {
|
|
186
|
+
console.log(` Cache TTL: ${stats.cacheTTL}ms`);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Demonstrate engine switching capability
|
|
190
|
+
console.log('\n🔄 Engine Switching Demo:');
|
|
191
|
+
console.log(' The factory pattern allows easy switching between different engines:');
|
|
192
|
+
console.log(' - Use createRenderer(\'aether\') for standard template rendering');
|
|
193
|
+
console.log(' - Use createRenderer(\'ssr-mode\') for server-side rendering');
|
|
194
|
+
console.log(' - Use createRenderer(\'template-mode\') for basic template mode');
|
|
195
|
+
|
|
196
|
+
} catch (error) {
|
|
197
|
+
// Handle initialization errors
|
|
198
|
+
console.error('❌ Error during engine initialization:');
|
|
199
|
+
console.error(` Message: ${error.message}`);
|
|
200
|
+
console.error(` Stack: ${error.stack}`);
|
|
201
|
+
|
|
202
|
+
console.error('\n🔧 Troubleshooting:');
|
|
203
|
+
console.error(' 1. Check that all required modules are installed');
|
|
204
|
+
console.error(' 2. Verify the index.js file exports createEngine correctly');
|
|
205
|
+
console.error(' 3. Ensure the engine modules are in the correct location');
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Execute the main function with error handling
|
|
210
|
+
run().catch(error => {
|
|
211
|
+
console.error('💥 Unhandled error in main execution:');
|
|
212
|
+
console.error(error);
|
|
213
|
+
process.exit(1);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// Export the run function for potential module usage
|
|
217
|
+
export { run };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
<header class="header">
|
|
3
|
+
<nav class="navbar">
|
|
4
|
+
<div class="container">
|
|
5
|
+
<a class="navbar-brand" href="/">
|
|
6
|
+
<img src="/assets/images/logo.png" alt="Logo" height="40">
|
|
7
|
+
</a>
|
|
8
|
+
|
|
9
|
+
<ul class="navbar-nav">
|
|
10
|
+
<li class="nav-item">
|
|
11
|
+
<a class="nav-link" href="/">Home</a>
|
|
12
|
+
</li>
|
|
13
|
+
<li class="nav-item">
|
|
14
|
+
<a class="nav-link" href="/about">About</a>
|
|
15
|
+
</li>
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
<li class="nav-item dropdown">
|
|
19
|
+
<a class="nav-link dropdown-toggle" href="#" role="button">
|
|
20
|
+
John Doe
|
|
21
|
+
</a>
|
|
22
|
+
<div class="dropdown-menu">
|
|
23
|
+
<a class="dropdown-item" href="/profile">Profile</a>
|
|
24
|
+
<a class="dropdown-item" href="/logout">Logout</a>
|
|
25
|
+
</div>
|
|
26
|
+
</li>
|
|
27
|
+
|
|
28
|
+
</ul>
|
|
29
|
+
</div>
|
|
30
|
+
</nav>
|
|
31
|
+
</header>
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Home Page - Aether Framework</title>
|
|
7
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
8
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
9
|
+
<style>
|
|
10
|
+
body {
|
|
11
|
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
12
|
+
line-height: 1.6;
|
|
13
|
+
}
|
|
14
|
+
.feature-grid {
|
|
15
|
+
display: grid;
|
|
16
|
+
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
|
17
|
+
gap: 2rem;
|
|
18
|
+
margin-top: 2rem;
|
|
19
|
+
}
|
|
20
|
+
.feature-card {
|
|
21
|
+
background: rgba(255, 255, 255, 0.05);
|
|
22
|
+
border-radius: 0.75rem;
|
|
23
|
+
padding: 1.5rem;
|
|
24
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
25
|
+
transition: all 0.3s ease;
|
|
26
|
+
}
|
|
27
|
+
.feature-card:hover {
|
|
28
|
+
transform: translateY(-5px);
|
|
29
|
+
border-color: #4f46e5;
|
|
30
|
+
box-shadow: 0 10px 25px rgba(79, 70, 229, 0.2);
|
|
31
|
+
}
|
|
32
|
+
.feature-icon {
|
|
33
|
+
font-size: 2rem;
|
|
34
|
+
color: #4f46e5;
|
|
35
|
+
margin-bottom: 1rem;
|
|
36
|
+
}
|
|
37
|
+
</style>
|
|
38
|
+
</head>
|
|
39
|
+
<body class="bg-gray-900 text-white">
|
|
40
|
+
<!-- Header Section -->
|
|
41
|
+
<header class="bg-gray-800 shadow-lg">
|
|
42
|
+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
43
|
+
<div class="flex justify-between h-16">
|
|
44
|
+
<div class="flex items-center">
|
|
45
|
+
<span class="text-xl font-bold text-indigo-400">Aether<span class="text-white">Framework</span></span>
|
|
46
|
+
</div>
|
|
47
|
+
<nav class="flex items-center space-x-4">
|
|
48
|
+
<a href="/" class="text-gray-300 hover:text-white transition-colors duration-200">Home</a>
|
|
49
|
+
<a href="/about" class="text-gray-300 hover:text-white transition-colors duration-200">About</a>
|
|
50
|
+
<a href="/docs" class="text-gray-300 hover:text-white transition-colors duration-200">Documentation</a>
|
|
51
|
+
</nav>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</header>
|
|
55
|
+
|
|
56
|
+
<!-- Main Content Section -->
|
|
57
|
+
<main class="py-8">
|
|
58
|
+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
59
|
+
<!-- Hero Section -->
|
|
60
|
+
<div class="text-center py-12">
|
|
61
|
+
<h1 class="text-4xl font-bold text-white mb-4">
|
|
62
|
+
Welcome to Aether Framework
|
|
63
|
+
</h1>
|
|
64
|
+
<p class="text-xl text-gray-300 max-w-3xl mx-auto">
|
|
65
|
+
A modern template engine with layout inheritance, SSR support, and enhanced syntax.
|
|
66
|
+
This content is injected into the main layout using @section directives.
|
|
67
|
+
</p>
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
<!-- Features Grid -->
|
|
71
|
+
<div class="feature-grid">
|
|
72
|
+
|
|
73
|
+
<div class="feature-card">
|
|
74
|
+
<div class="feature-icon">
|
|
75
|
+
<i class="fas fa-bolt"></i>
|
|
76
|
+
</div>
|
|
77
|
+
<h3 class="text-xl font-semibold text-white mb-2">
|
|
78
|
+
Fast Rendering
|
|
79
|
+
</h3>
|
|
80
|
+
<p class="text-gray-300">
|
|
81
|
+
High performance template compilation and execution with built-in caching
|
|
82
|
+
</p>
|
|
83
|
+
<div class="mt-4">
|
|
84
|
+
<span class="inline-block bg-indigo-900 text-indigo-200 text-xs font-semibold px-3 py-1 rounded-full">
|
|
85
|
+
Performance
|
|
86
|
+
</span>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
|
|
90
|
+
<div class="feature-card">
|
|
91
|
+
<div class="feature-icon">
|
|
92
|
+
<i class="fas fa-layer-group"></i>
|
|
93
|
+
</div>
|
|
94
|
+
<h3 class="text-xl font-semibold text-white mb-2">
|
|
95
|
+
Layout Inheritance
|
|
96
|
+
</h3>
|
|
97
|
+
<p class="text-gray-300">
|
|
98
|
+
Powerful @extends and @section directives for reusable layouts
|
|
99
|
+
</p>
|
|
100
|
+
<div class="mt-4">
|
|
101
|
+
<span class="inline-block bg-indigo-900 text-indigo-200 text-xs font-semibold px-3 py-1 rounded-full">
|
|
102
|
+
Productivity
|
|
103
|
+
</span>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
<div class="feature-card">
|
|
108
|
+
<div class="feature-icon">
|
|
109
|
+
<i class="fas fa-server"></i>
|
|
110
|
+
</div>
|
|
111
|
+
<h3 class="text-xl font-semibold text-white mb-2">
|
|
112
|
+
SSR Support
|
|
113
|
+
</h3>
|
|
114
|
+
<p class="text-gray-300">
|
|
115
|
+
Server-side rendering with hydration for optimal SEO and performance
|
|
116
|
+
</p>
|
|
117
|
+
<div class="mt-4">
|
|
118
|
+
<span class="inline-block bg-indigo-900 text-indigo-200 text-xs font-semibold px-3 py-1 rounded-full">
|
|
119
|
+
Modern
|
|
120
|
+
</span>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
|
|
124
|
+
<div class="feature-card">
|
|
125
|
+
<div class="feature-icon">
|
|
126
|
+
<i class="fas fa-code"></i>
|
|
127
|
+
</div>
|
|
128
|
+
<h3 class="text-xl font-semibold text-white mb-2">
|
|
129
|
+
Easy Syntax
|
|
130
|
+
</h3>
|
|
131
|
+
<p class="text-gray-300">
|
|
132
|
+
Blade-style syntax that is intuitive and easy to learn
|
|
133
|
+
</p>
|
|
134
|
+
<div class="mt-4">
|
|
135
|
+
<span class="inline-block bg-indigo-900 text-indigo-200 text-xs font-semibold px-3 py-1 rounded-full">
|
|
136
|
+
Developer Experience
|
|
137
|
+
</span>
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
|
|
141
|
+
</div>
|
|
142
|
+
|
|
143
|
+
<!-- Additional Content -->
|
|
144
|
+
<div class="mt-12 bg-gradient-to-r from-indigo-900/30 to-purple-900/30 rounded-2xl p-8 border border-indigo-800/30">
|
|
145
|
+
<h2 class="text-2xl font-bold text-white mb-4">
|
|
146
|
+
Why Choose Aether?
|
|
147
|
+
</h2>
|
|
148
|
+
<ul class="space-y-3 text-gray-300">
|
|
149
|
+
<li class="flex items-center">
|
|
150
|
+
<i class="fas fa-check text-green-400 mr-3"></i>
|
|
151
|
+
<span>Blade-style syntax with @extends, @section, and @yield directives</span>
|
|
152
|
+
</li>
|
|
153
|
+
<li class="flex items-center">
|
|
154
|
+
<i class="fas fa-check text-green-400 mr-3"></i>
|
|
155
|
+
<span>Server-side rendering (SSR) support with hydration</span>
|
|
156
|
+
</li>
|
|
157
|
+
<li class="flex items-center">
|
|
158
|
+
<i class="fas fa-check text-green-400 mr-3"></i>
|
|
159
|
+
<span>Template inheritance and component reuse</span>
|
|
160
|
+
</li>
|
|
161
|
+
<li class="flex items-center">
|
|
162
|
+
<i class="fas fa-check text-green-400 mr-3"></i>
|
|
163
|
+
<span>Built-in caching for optimal performance</span>
|
|
164
|
+
</li>
|
|
165
|
+
</ul>
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
</main>
|
|
169
|
+
|
|
170
|
+
<!-- Footer Section -->
|
|
171
|
+
<footer class="bg-gray-800 border-t border-gray-700 mt-12">
|
|
172
|
+
<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
|
|
173
|
+
<div class="flex justify-between items-center">
|
|
174
|
+
<p class="text-sm text-gray-400">
|
|
175
|
+
© 2026 Aether Template Engine. All rights reserved.
|
|
176
|
+
</p>
|
|
177
|
+
<div class="flex space-x-4">
|
|
178
|
+
<a href="#" class="text-gray-400 hover:text-white">
|
|
179
|
+
<i class="fab fa-github"></i>
|
|
180
|
+
</a>
|
|
181
|
+
<a href="#" class="text-gray-400 hover:text-white">
|
|
182
|
+
<i class="fab fa-twitter"></i>
|
|
183
|
+
</a>
|
|
184
|
+
<a href="#" class="text-gray-400 hover:text-white">
|
|
185
|
+
<i class="fab fa-discord"></i>
|
|
186
|
+
</a>
|
|
187
|
+
</div>
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
</footer>
|
|
191
|
+
|
|
192
|
+
<!-- Scripts Section -->
|
|
193
|
+
<script>
|
|
194
|
+
console.log('Home page loaded successfully');
|
|
195
|
+
|
|
196
|
+
// Add interactive features
|
|
197
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
198
|
+
const featureCards = document.querySelectorAll('.feature-card');
|
|
199
|
+
featureCards.forEach(card => {
|
|
200
|
+
card.addEventListener('click', function() {
|
|
201
|
+
this.classList.toggle('ring-2');
|
|
202
|
+
this.classList.toggle('ring-indigo-500');
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
console.log('Interactive features initialized');
|
|
207
|
+
});
|
|
208
|
+
</script>
|
|
209
|
+
</body>
|
|
210
|
+
</html>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>@yield('title', 'Aether Framework')</title>
|
|
7
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
8
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
9
|
+
@yield('head')
|
|
10
|
+
</head>
|
|
11
|
+
<body class="bg-gray-900 text-white">
|
|
12
|
+
<!-- Header Section -->
|
|
13
|
+
<header class="bg-gray-800 shadow-lg">
|
|
14
|
+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
15
|
+
<div class="flex justify-between h-16">
|
|
16
|
+
<div class="flex items-center">
|
|
17
|
+
<span class="text-xl font-bold text-indigo-400">Aether<span class="text-white">Framework</span></span>
|
|
18
|
+
</div>
|
|
19
|
+
<nav class="flex items-center space-x-4">
|
|
20
|
+
<a href="/" class="text-gray-300 hover:text-white transition-colors duration-200">Home</a>
|
|
21
|
+
<a href="/about" class="text-gray-300 hover:text-white transition-colors duration-200">About</a>
|
|
22
|
+
<a href="/docs" class="text-gray-300 hover:text-white transition-colors duration-200">Documentation</a>
|
|
23
|
+
</nav>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</header>
|
|
27
|
+
|
|
28
|
+
<!-- Main Content Section -->
|
|
29
|
+
<main class="py-8">
|
|
30
|
+
@yield('content')
|
|
31
|
+
</main>
|
|
32
|
+
|
|
33
|
+
<!-- Footer Section -->
|
|
34
|
+
<footer class="bg-gray-800 border-t border-gray-700 mt-12">
|
|
35
|
+
<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
|
|
36
|
+
<div class="flex justify-between items-center">
|
|
37
|
+
<p class="text-sm text-gray-400">
|
|
38
|
+
© {{ currentYear }} Aether Template Engine. All rights reserved.
|
|
39
|
+
</p>
|
|
40
|
+
<div class="flex space-x-4">
|
|
41
|
+
<a href="#" class="text-gray-400 hover:text-white">
|
|
42
|
+
<i class="fab fa-github"></i>
|
|
43
|
+
</a>
|
|
44
|
+
<a href="#" class="text-gray-400 hover:text-white">
|
|
45
|
+
<i class="fab fa-twitter"></i>
|
|
46
|
+
</a>
|
|
47
|
+
<a href="#" class="text-gray-400 hover:text-white">
|
|
48
|
+
<i class="fab fa-discord"></i>
|
|
49
|
+
</a>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</footer>
|
|
54
|
+
|
|
55
|
+
<!-- Scripts Section -->
|
|
56
|
+
@yield('scripts')
|
|
57
|
+
</body>
|
|
58
|
+
</html>
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
@extends('layouts/main')
|
|
2
|
+
|
|
3
|
+
@section('title', 'Home Page - Aether Framework')
|
|
4
|
+
|
|
5
|
+
@section('head')
|
|
6
|
+
<style>
|
|
7
|
+
body {
|
|
8
|
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
9
|
+
line-height: 1.6;
|
|
10
|
+
}
|
|
11
|
+
.feature-grid {
|
|
12
|
+
display: grid;
|
|
13
|
+
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
|
14
|
+
gap: 2rem;
|
|
15
|
+
margin-top: 2rem;
|
|
16
|
+
}
|
|
17
|
+
.feature-card {
|
|
18
|
+
background: rgba(255, 255, 255, 0.05);
|
|
19
|
+
border-radius: 0.75rem;
|
|
20
|
+
padding: 1.5rem;
|
|
21
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
22
|
+
transition: all 0.3s ease;
|
|
23
|
+
}
|
|
24
|
+
.feature-card:hover {
|
|
25
|
+
transform: translateY(-5px);
|
|
26
|
+
border-color: #4f46e5;
|
|
27
|
+
box-shadow: 0 10px 25px rgba(79, 70, 229, 0.2);
|
|
28
|
+
}
|
|
29
|
+
.feature-icon {
|
|
30
|
+
font-size: 2rem;
|
|
31
|
+
color: #4f46e5;
|
|
32
|
+
margin-bottom: 1rem;
|
|
33
|
+
}
|
|
34
|
+
</style>
|
|
35
|
+
@endsection
|
|
36
|
+
|
|
37
|
+
@section('content')
|
|
38
|
+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
39
|
+
<!-- Hero Section -->
|
|
40
|
+
<div class="text-center py-12">
|
|
41
|
+
<h1 class="text-4xl font-bold text-white mb-4">
|
|
42
|
+
Welcome to Aether Framework
|
|
43
|
+
</h1>
|
|
44
|
+
<p class="text-xl text-gray-300 max-w-3xl mx-auto">
|
|
45
|
+
A modern template engine with layout inheritance, SSR support, and enhanced syntax.
|
|
46
|
+
This content is injected into the main layout using @section directives.
|
|
47
|
+
</p>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
<!-- Features Grid -->
|
|
51
|
+
<div class="feature-grid">
|
|
52
|
+
@foreach(features as feature)
|
|
53
|
+
<div class="feature-card">
|
|
54
|
+
<div class="feature-icon">
|
|
55
|
+
<i class="{{ feature.icon }}"></i>
|
|
56
|
+
</div>
|
|
57
|
+
<h3 class="text-xl font-semibold text-white mb-2">
|
|
58
|
+
{{ feature.name }}
|
|
59
|
+
</h3>
|
|
60
|
+
<p class="text-gray-300">
|
|
61
|
+
{{ feature.description }}
|
|
62
|
+
</p>
|
|
63
|
+
<div class="mt-4">
|
|
64
|
+
<span class="inline-block bg-indigo-900 text-indigo-200 text-xs font-semibold px-3 py-1 rounded-full">
|
|
65
|
+
{{ feature.tag }}
|
|
66
|
+
</span>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
@endforeach
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
<!-- Additional Content -->
|
|
73
|
+
<div class="mt-12 bg-gradient-to-r from-indigo-900/30 to-purple-900/30 rounded-2xl p-8 border border-indigo-800/30">
|
|
74
|
+
<h2 class="text-2xl font-bold text-white mb-4">
|
|
75
|
+
Why Choose Aether?
|
|
76
|
+
</h2>
|
|
77
|
+
<ul class="space-y-3 text-gray-300">
|
|
78
|
+
<li class="flex items-center">
|
|
79
|
+
<i class="fas fa-check text-green-400 mr-3"></i>
|
|
80
|
+
<span>Blade-style syntax with @extends, @section, and @yield directives</span>
|
|
81
|
+
</li>
|
|
82
|
+
<li class="flex items-center">
|
|
83
|
+
<i class="fas fa-check text-green-400 mr-3"></i>
|
|
84
|
+
<span>Server-side rendering (SSR) support with hydration</span>
|
|
85
|
+
</li>
|
|
86
|
+
<li class="flex items-center">
|
|
87
|
+
<i class="fas fa-check text-green-400 mr-3"></i>
|
|
88
|
+
<span>Template inheritance and component reuse</span>
|
|
89
|
+
</li>
|
|
90
|
+
<li class="flex items-center">
|
|
91
|
+
<i class="fas fa-check text-green-400 mr-3"></i>
|
|
92
|
+
<span>Built-in caching for optimal performance</span>
|
|
93
|
+
</li>
|
|
94
|
+
</ul>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
@endsection
|
|
98
|
+
|
|
99
|
+
@section('scripts')
|
|
100
|
+
<script>
|
|
101
|
+
console.log('Home page loaded successfully');
|
|
102
|
+
|
|
103
|
+
// Add interactive features
|
|
104
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
105
|
+
const featureCards = document.querySelectorAll('.feature-card');
|
|
106
|
+
featureCards.forEach(card => {
|
|
107
|
+
card.addEventListener('click', function() {
|
|
108
|
+
this.classList.toggle('ring-2');
|
|
109
|
+
this.classList.toggle('ring-indigo-500');
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
console.log('Interactive features initialized');
|
|
114
|
+
});
|
|
115
|
+
</script>
|
|
116
|
+
@endsection
|