初始提交,未完全测试

This commit is contained in:
2026-02-27 14:37:10 +08:00
parent 76c0f469be
commit e270f02073
68 changed files with 5886 additions and 0 deletions

123
template/Template.py Normal file
View File

@@ -0,0 +1,123 @@
#!/usr/bin/env python3.9
# -*- coding: utf-8 -*-
"""
JFinal Template - Template Rendering Engine
"""
from typing import Dict, Optional, Union, Callable
from io import StringIO
from .Env import Env
from .stat.ast.Stat import Stat
class Template:
"""Template rendering engine"""
def __init__(self, env: Env, ast: Stat):
"""
Initialize template
Args:
env: Template environment
ast: Abstract syntax tree
"""
if env is None or ast is None:
raise ValueError("env and ast cannot be null")
self._env = env
self._ast = ast
def render(self, data: Dict = None, output = None):
"""
Render template to output
Args:
data: Data dictionary
output: Output target (file, stream, writer, etc.)
"""
data = data or {}
scope = self._create_scope(data)
if hasattr(output, 'write'):
# It's a writer-like object
self._ast.exec(self._env, scope, output)
elif hasattr(output, 'writebytes') or hasattr(output, 'write_bytes'):
# It's a binary stream
self._render_to_binary(output, scope)
else:
# Try to convert to appropriate output
self._render_to_output(output, scope)
def render_to_string(self, data: Dict = None) -> str:
"""
Render template to string
Args:
data: Data dictionary
Returns:
Rendered string
"""
output = StringIO()
self.render(data, output)
return output.getvalue()
def render_to_string_builder(self, data: Dict = None) -> StringIO:
"""
Render template to StringIO
Args:
data: Data dictionary
Returns:
StringIO object
"""
output = StringIO()
self.render(data, output)
return output
def _create_scope(self, data: Dict) -> 'Scope':
"""Create execution scope"""
from .stat.Scope import Scope
shared_objects = self._env.engine_config.shared_object_map or {}
return Scope(data, shared_objects)
def _render_to_binary(self, output, scope):
"""Render to binary output"""
# Simplified binary output handling
result = self._ast.exec(self._env, scope, StringIO())
if isinstance(result, str):
output.write(result.encode('utf-8'))
def _render_to_output(self, output, scope):
"""Render to various output types"""
result = self._ast.exec(self._env, scope, StringIO())
if isinstance(result, str):
if hasattr(output, '__fspath__'):
# It's a file path
with open(output, 'w', encoding='utf-8') as f:
f.write(result)
elif isinstance(output, str):
# It's a file path string
with open(output, 'w', encoding='utf-8') as f:
f.write(result)
else:
# Try to convert to string
output_str = str(result)
if hasattr(output, 'write'):
output.write(output_str)
def is_modified(self) -> bool:
"""Check if template has been modified (for dev mode)"""
return self._env.is_source_list_modified()
def get_env(self) -> Env:
"""Get template environment"""
return self._env
def get_ast(self) -> Stat:
"""Get abstract syntax tree"""
return self._ast
# Import Scope to avoid circular import
from .stat.Scope import Scope