调整版本并做测试
This commit is contained in:
123
pyenjoy/template/Template.py
Normal file
123
pyenjoy/template/Template.py
Normal 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
|
||||
Reference in New Issue
Block a user