diff --git a/MANIFEST.in b/MANIFEST.in index 0f4ef16..7352f35 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,3 +1,3 @@ include README.md include LICENSE -recursive-include py_enjoy * +recursive-include pyenjoy * diff --git a/README.md b/README.md index d10d661..42d2606 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# py_enjoy +# py-enjoy jfinal-enjoy的 python3.9+ 实现 diff --git a/README.py b/README.py index 3083da9..be6d96d 100644 --- a/README.py +++ b/README.py @@ -9,7 +9,7 @@ This is a Python 3.9+ implementation of the JFinal Template Engine (Enjoy). Project Structure ----------------- -py_enjoy/ +pyenjoy/ ├── __init__.py # Main package initialization ├── kit/ # Utility classes │ ├── StrKit.py # String utilities @@ -93,19 +93,19 @@ Installation ```bash # Clone or download the project -cd py_enjoy +cd pyenjoy # No installation required, just add to PYTHONPATH import sys -sys.path.append('/path/to/py_enjoy') +sys.path.append('/path/to/pyenjoy') ``` Quick Start ----------- ```python -from py_enjoy.template.Engine import Engine -from py_enjoy.kit.Kv import Kv +from pyenjoy.template.Engine import Engine +from pyenjoy.kit.Kv import Kv # Get the template engine engine = Engine.use() @@ -145,7 +145,7 @@ data = Kv.of("items", [ ### Custom Directives ```python -from py_enjoy.template.Directive import Directive +from pyenjoy.template.Directive import Directive class UpperDirective(Directive): def exec(self, env, scope, writer): diff --git a/py_enjoy/__init__.py b/pyenjoy/__init__.py similarity index 97% rename from py_enjoy/__init__.py rename to pyenjoy/__init__.py index 3706e16..b99ec7a 100644 --- a/py_enjoy/__init__.py +++ b/pyenjoy/__init__.py @@ -4,7 +4,7 @@ py_enjoy - Python implementation of JFinal Template Engine """ -__version__ = "5.2.2" +__version__ = "1.0.1" __author__ = "James Zhan 詹波 (original), Python port by mrzhou@miw.cn" __license__ = "Apache License 2.0" diff --git a/py_enjoy/kit/Func.py b/pyenjoy/kit/Func.py similarity index 100% rename from py_enjoy/kit/Func.py rename to pyenjoy/kit/Func.py diff --git a/py_enjoy/kit/HashKit.py b/pyenjoy/kit/HashKit.py similarity index 100% rename from py_enjoy/kit/HashKit.py rename to pyenjoy/kit/HashKit.py diff --git a/py_enjoy/kit/JavaKeyword.py b/pyenjoy/kit/JavaKeyword.py similarity index 100% rename from py_enjoy/kit/JavaKeyword.py rename to pyenjoy/kit/JavaKeyword.py diff --git a/py_enjoy/kit/Kv.py b/pyenjoy/kit/Kv.py similarity index 100% rename from py_enjoy/kit/Kv.py rename to pyenjoy/kit/Kv.py diff --git a/py_enjoy/kit/Okv.py b/pyenjoy/kit/Okv.py similarity index 100% rename from py_enjoy/kit/Okv.py rename to pyenjoy/kit/Okv.py diff --git a/py_enjoy/kit/Prop.py b/pyenjoy/kit/Prop.py similarity index 100% rename from py_enjoy/kit/Prop.py rename to pyenjoy/kit/Prop.py diff --git a/py_enjoy/kit/PropKit.py b/pyenjoy/kit/PropKit.py similarity index 100% rename from py_enjoy/kit/PropKit.py rename to pyenjoy/kit/PropKit.py diff --git a/py_enjoy/kit/ReflectKit.py b/pyenjoy/kit/ReflectKit.py similarity index 100% rename from py_enjoy/kit/ReflectKit.py rename to pyenjoy/kit/ReflectKit.py diff --git a/py_enjoy/kit/StrKit.py b/pyenjoy/kit/StrKit.py similarity index 100% rename from py_enjoy/kit/StrKit.py rename to pyenjoy/kit/StrKit.py diff --git a/py_enjoy/kit/SyncWriteMap.py b/pyenjoy/kit/SyncWriteMap.py similarity index 100% rename from py_enjoy/kit/SyncWriteMap.py rename to pyenjoy/kit/SyncWriteMap.py diff --git a/py_enjoy/kit/TimeKit.py b/pyenjoy/kit/TimeKit.py similarity index 100% rename from py_enjoy/kit/TimeKit.py rename to pyenjoy/kit/TimeKit.py diff --git a/py_enjoy/kit/TypeKit.py b/pyenjoy/kit/TypeKit.py similarity index 100% rename from py_enjoy/kit/TypeKit.py rename to pyenjoy/kit/TypeKit.py diff --git a/py_enjoy/proxy/ProxyClass.py b/pyenjoy/proxy/ProxyClass.py similarity index 100% rename from py_enjoy/proxy/ProxyClass.py rename to pyenjoy/proxy/ProxyClass.py diff --git a/py_enjoy/proxy/ProxyClassLoader.py b/pyenjoy/proxy/ProxyClassLoader.py similarity index 100% rename from py_enjoy/proxy/ProxyClassLoader.py rename to pyenjoy/proxy/ProxyClassLoader.py diff --git a/py_enjoy/proxy/ProxyCompiler.py b/pyenjoy/proxy/ProxyCompiler.py similarity index 100% rename from py_enjoy/proxy/ProxyCompiler.py rename to pyenjoy/proxy/ProxyCompiler.py diff --git a/py_enjoy/template/Directive.py b/pyenjoy/template/Directive.py similarity index 100% rename from py_enjoy/template/Directive.py rename to pyenjoy/template/Directive.py diff --git a/py_enjoy/template/Engine.py b/pyenjoy/template/Engine.py similarity index 100% rename from py_enjoy/template/Engine.py rename to pyenjoy/template/Engine.py diff --git a/py_enjoy/template/EngineConfig.py b/pyenjoy/template/EngineConfig.py similarity index 100% rename from py_enjoy/template/EngineConfig.py rename to pyenjoy/template/EngineConfig.py diff --git a/py_enjoy/template/Env.py b/pyenjoy/template/Env.py similarity index 100% rename from py_enjoy/template/Env.py rename to pyenjoy/template/Env.py diff --git a/py_enjoy/template/Template.py b/pyenjoy/template/Template.py similarity index 100% rename from py_enjoy/template/Template.py rename to pyenjoy/template/Template.py diff --git a/py_enjoy/template/TemplateException.py b/pyenjoy/template/TemplateException.py similarity index 100% rename from py_enjoy/template/TemplateException.py rename to pyenjoy/template/TemplateException.py diff --git a/py_enjoy/template/expr/__init__.py b/pyenjoy/template/expr/__init__.py similarity index 100% rename from py_enjoy/template/expr/__init__.py rename to pyenjoy/template/expr/__init__.py diff --git a/py_enjoy/template/expr/ast/Arith.py b/pyenjoy/template/expr/ast/Arith.py similarity index 100% rename from py_enjoy/template/expr/ast/Arith.py rename to pyenjoy/template/expr/ast/Arith.py diff --git a/py_enjoy/template/expr/ast/Compare.py b/pyenjoy/template/expr/ast/Compare.py similarity index 100% rename from py_enjoy/template/expr/ast/Compare.py rename to pyenjoy/template/expr/ast/Compare.py diff --git a/py_enjoy/template/expr/ast/Const.py b/pyenjoy/template/expr/ast/Const.py similarity index 100% rename from py_enjoy/template/expr/ast/Const.py rename to pyenjoy/template/expr/ast/Const.py diff --git a/py_enjoy/template/expr/ast/Expr.py b/pyenjoy/template/expr/ast/Expr.py similarity index 100% rename from py_enjoy/template/expr/ast/Expr.py rename to pyenjoy/template/expr/ast/Expr.py diff --git a/py_enjoy/template/expr/ast/FieldKeyBuilder.py b/pyenjoy/template/expr/ast/FieldKeyBuilder.py similarity index 100% rename from py_enjoy/template/expr/ast/FieldKeyBuilder.py rename to pyenjoy/template/expr/ast/FieldKeyBuilder.py diff --git a/py_enjoy/template/expr/ast/FieldKit.py b/pyenjoy/template/expr/ast/FieldKit.py similarity index 100% rename from py_enjoy/template/expr/ast/FieldKit.py rename to pyenjoy/template/expr/ast/FieldKit.py diff --git a/py_enjoy/template/expr/ast/MethodKit.py b/pyenjoy/template/expr/ast/MethodKit.py similarity index 100% rename from py_enjoy/template/expr/ast/MethodKit.py rename to pyenjoy/template/expr/ast/MethodKit.py diff --git a/py_enjoy/template/expr/ast/SharedMethodKit.py b/pyenjoy/template/expr/ast/SharedMethodKit.py similarity index 100% rename from py_enjoy/template/expr/ast/SharedMethodKit.py rename to pyenjoy/template/expr/ast/SharedMethodKit.py diff --git a/py_enjoy/template/expr/ast/__init__.py b/pyenjoy/template/expr/ast/__init__.py similarity index 100% rename from py_enjoy/template/expr/ast/__init__.py rename to pyenjoy/template/expr/ast/__init__.py diff --git a/py_enjoy/template/ext/__init__.py b/pyenjoy/template/ext/__init__.py similarity index 100% rename from py_enjoy/template/ext/__init__.py rename to pyenjoy/template/ext/__init__.py diff --git a/py_enjoy/template/ext/directive/CallDirective.py b/pyenjoy/template/ext/directive/CallDirective.py similarity index 100% rename from py_enjoy/template/ext/directive/CallDirective.py rename to pyenjoy/template/ext/directive/CallDirective.py diff --git a/py_enjoy/template/ext/directive/DateDirective.py b/pyenjoy/template/ext/directive/DateDirective.py similarity index 100% rename from py_enjoy/template/ext/directive/DateDirective.py rename to pyenjoy/template/ext/directive/DateDirective.py diff --git a/py_enjoy/template/ext/directive/EscapeDirective.py b/pyenjoy/template/ext/directive/EscapeDirective.py similarity index 100% rename from py_enjoy/template/ext/directive/EscapeDirective.py rename to pyenjoy/template/ext/directive/EscapeDirective.py diff --git a/py_enjoy/template/ext/directive/NumberDirective.py b/pyenjoy/template/ext/directive/NumberDirective.py similarity index 100% rename from py_enjoy/template/ext/directive/NumberDirective.py rename to pyenjoy/template/ext/directive/NumberDirective.py diff --git a/py_enjoy/template/ext/directive/RandomDirective.py b/pyenjoy/template/ext/directive/RandomDirective.py similarity index 100% rename from py_enjoy/template/ext/directive/RandomDirective.py rename to pyenjoy/template/ext/directive/RandomDirective.py diff --git a/py_enjoy/template/ext/directive/RenderDirective.py b/pyenjoy/template/ext/directive/RenderDirective.py similarity index 100% rename from py_enjoy/template/ext/directive/RenderDirective.py rename to pyenjoy/template/ext/directive/RenderDirective.py diff --git a/py_enjoy/template/ext/directive/StringDirective.py b/pyenjoy/template/ext/directive/StringDirective.py similarity index 100% rename from py_enjoy/template/ext/directive/StringDirective.py rename to pyenjoy/template/ext/directive/StringDirective.py diff --git a/py_enjoy/template/ext/directive/__init__.py b/pyenjoy/template/ext/directive/__init__.py similarity index 100% rename from py_enjoy/template/ext/directive/__init__.py rename to pyenjoy/template/ext/directive/__init__.py diff --git a/py_enjoy/template/ext/sharedmethod/SharedMethodLib.py b/pyenjoy/template/ext/sharedmethod/SharedMethodLib.py similarity index 100% rename from py_enjoy/template/ext/sharedmethod/SharedMethodLib.py rename to pyenjoy/template/ext/sharedmethod/SharedMethodLib.py diff --git a/py_enjoy/template/ext/sharedmethod/__init__.py b/pyenjoy/template/ext/sharedmethod/__init__.py similarity index 100% rename from py_enjoy/template/ext/sharedmethod/__init__.py rename to pyenjoy/template/ext/sharedmethod/__init__.py diff --git a/py_enjoy/template/io/EncoderFactory.py b/pyenjoy/template/io/EncoderFactory.py similarity index 100% rename from py_enjoy/template/io/EncoderFactory.py rename to pyenjoy/template/io/EncoderFactory.py diff --git a/py_enjoy/template/io/JdkEncoder.py b/pyenjoy/template/io/JdkEncoder.py similarity index 100% rename from py_enjoy/template/io/JdkEncoder.py rename to pyenjoy/template/io/JdkEncoder.py diff --git a/py_enjoy/template/io/JdkEncoderFactory.py b/pyenjoy/template/io/JdkEncoderFactory.py similarity index 100% rename from py_enjoy/template/io/JdkEncoderFactory.py rename to pyenjoy/template/io/JdkEncoderFactory.py diff --git a/py_enjoy/template/io/WriterBuffer.py b/pyenjoy/template/io/WriterBuffer.py similarity index 100% rename from py_enjoy/template/io/WriterBuffer.py rename to pyenjoy/template/io/WriterBuffer.py diff --git a/py_enjoy/template/io/__init__.py b/pyenjoy/template/io/__init__.py similarity index 100% rename from py_enjoy/template/io/__init__.py rename to pyenjoy/template/io/__init__.py diff --git a/py_enjoy/template/source/ClassPathSource.py b/pyenjoy/template/source/ClassPathSource.py similarity index 100% rename from py_enjoy/template/source/ClassPathSource.py rename to pyenjoy/template/source/ClassPathSource.py diff --git a/py_enjoy/template/source/ClassPathSourceFactory.py b/pyenjoy/template/source/ClassPathSourceFactory.py similarity index 100% rename from py_enjoy/template/source/ClassPathSourceFactory.py rename to pyenjoy/template/source/ClassPathSourceFactory.py diff --git a/py_enjoy/template/source/FileSource.py b/pyenjoy/template/source/FileSource.py similarity index 100% rename from py_enjoy/template/source/FileSource.py rename to pyenjoy/template/source/FileSource.py diff --git a/py_enjoy/template/source/FileSourceFactory.py b/pyenjoy/template/source/FileSourceFactory.py similarity index 100% rename from py_enjoy/template/source/FileSourceFactory.py rename to pyenjoy/template/source/FileSourceFactory.py diff --git a/py_enjoy/template/source/ISourceFactory.py b/pyenjoy/template/source/ISourceFactory.py similarity index 100% rename from py_enjoy/template/source/ISourceFactory.py rename to pyenjoy/template/source/ISourceFactory.py diff --git a/py_enjoy/template/source/StringSource.py b/pyenjoy/template/source/StringSource.py similarity index 100% rename from py_enjoy/template/source/StringSource.py rename to pyenjoy/template/source/StringSource.py diff --git a/py_enjoy/template/source/__init__.py b/pyenjoy/template/source/__init__.py similarity index 100% rename from py_enjoy/template/source/__init__.py rename to pyenjoy/template/source/__init__.py diff --git a/py_enjoy/template/stat/Compressor.py b/pyenjoy/template/stat/Compressor.py similarity index 100% rename from py_enjoy/template/stat/Compressor.py rename to pyenjoy/template/stat/Compressor.py diff --git a/py_enjoy/template/stat/OutputDirectiveFactory.py b/pyenjoy/template/stat/OutputDirectiveFactory.py similarity index 100% rename from py_enjoy/template/stat/OutputDirectiveFactory.py rename to pyenjoy/template/stat/OutputDirectiveFactory.py diff --git a/py_enjoy/template/stat/Parser.py b/pyenjoy/template/stat/Parser.py similarity index 69% rename from py_enjoy/template/stat/Parser.py rename to pyenjoy/template/stat/Parser.py index e7a4d89..943dc2c 100644 --- a/py_enjoy/template/stat/Parser.py +++ b/pyenjoy/template/stat/Parser.py @@ -274,8 +274,108 @@ class SimpleExprList: # Replace 'for.' with '_for.' in the expression expr_str = expr_str.replace('for.', '_for.') - # Evaluate the expression - return eval(expr_str, {}, wrapped_vars) + # Remove newline characters from expression + expr_str = expr_str.replace('\n', '').replace('\r', '') + + # Split expression by | to handle filters + expr_parts = expr_str.split('|') + main_expr = expr_parts[0].strip() + + # Evaluate main expression first + if '??' in main_expr: + # Custom evaluation for expressions with ?? operator + def evaluate_null_coalescing(expr): + if '??' not in expr: + try: + return eval(expr, {}, wrapped_vars) + except (NameError, AttributeError): + return None + + # Process from right to left for nested ?? + idx = expr.rfind('??') + + # Find left expression + left_expr = expr[:idx].strip() + right_expr = expr[idx+2:].strip() + + # Evaluate left part + left_val = evaluate_null_coalescing(left_expr) + + if left_val is not None: + return left_val + else: + # Evaluate right part + return evaluate_null_coalescing(right_expr) + + result = evaluate_null_coalescing(main_expr) + else: + # Regular evaluation for expressions without ?? + try: + result = eval(main_expr, {}, wrapped_vars) + except (NameError, AttributeError): + result = None + + # Apply filters + for filter_part in expr_parts[1:]: + filter_part = filter_part.strip() + if not filter_part: + continue + + # Parse filter name and arguments + if '(' in filter_part: + filter_name = filter_part[:filter_part.find('(')].strip() + # Extract arguments + args_str = filter_part[filter_part.find('(')+1:filter_part.rfind(')')].strip() + # Simple argument parsing - split by commas, ignoring commas inside quotes + args = [] + current_arg = '' + in_quotes = False + quote_char = '' + for char in args_str: + if char in "'\"" and (not in_quotes or char == quote_char): + if not in_quotes: + in_quotes = True + quote_char = char + else: + in_quotes = False + current_arg += char + elif char == ',' and not in_quotes: + args.append(current_arg.strip()) + current_arg = '' + else: + current_arg += char + if current_arg: + args.append(current_arg.strip()) + else: + filter_name = filter_part.strip() + args = [] + + # Apply filter + if filter_name == 'join': + # Join filter implementation + if len(args) > 0: + # Remove quotes from separator if present + sep = args[0] + if (sep.startswith('"') and sep.endswith('"')) or (sep.startswith("'") and sep.endswith("'")): + sep = sep[1:-1] + else: + sep = '' + + if isinstance(result, (list, tuple)): + result = sep.join(str(item) for item in result) + else: + result = str(result) + elif filter_name == 'upper': + # Upper case filter + result = str(result).upper() + elif filter_name == 'lower': + # Lower case filter + result = str(result).lower() + elif filter_name == 'strip': + # Strip whitespace filter + result = str(result).strip() + + return result except Exception as e: # Handle evaluation errors gracefully return f"Error evaluating expression '{self._expr_str}': {e}" diff --git a/py_enjoy/template/stat/Scope.py b/pyenjoy/template/stat/Scope.py similarity index 100% rename from py_enjoy/template/stat/Scope.py rename to pyenjoy/template/stat/Scope.py diff --git a/py_enjoy/template/stat/ast/Define.py b/pyenjoy/template/stat/ast/Define.py similarity index 100% rename from py_enjoy/template/stat/ast/Define.py rename to pyenjoy/template/stat/ast/Define.py diff --git a/py_enjoy/template/stat/ast/For.py b/pyenjoy/template/stat/ast/For.py similarity index 74% rename from py_enjoy/template/stat/ast/For.py rename to pyenjoy/template/stat/ast/For.py index 139c63d..f0e8c07 100644 --- a/py_enjoy/template/stat/ast/For.py +++ b/pyenjoy/template/stat/ast/For.py @@ -28,15 +28,39 @@ class For(Stat): def exec(self, env: Env, scope: Scope, writer) -> None: """ Execute for loop - + Args: env: Template environment scope: Execution scope writer: Output writer """ try: + # Wrap dict values to allow attribute access + def wrap_dict(d): + """Wrap a dict to allow attribute access""" + if isinstance(d, dict): + # Create a wrapper that allows both dot access and bracket access + class DictWrapper: + def __init__(self, data): + self.__dict__ = data + def __getitem__(self, key): + return data[key] + return DictWrapper(d) + return d + + # Create wrapped vars similar to SimpleExprList.eval() + wrapped_vars = {} + for key, value in scope._data.items(): + if isinstance(value, dict): + wrapped_vars[key] = wrap_dict(value) + elif isinstance(value, list): + # Wrap dictionaries in lists + wrapped_vars[key] = [wrap_dict(item) for item in value] + else: + wrapped_vars[key] = value + # Get the iterable from the expression - iterable = eval(self._iter_expr, {}, scope._data.copy()) + iterable = eval(self._iter_expr, {}, wrapped_vars) # Convert iterable to list for easier manipulation items = list(iterable) diff --git a/py_enjoy/template/stat/ast/Output.py b/pyenjoy/template/stat/ast/Output.py similarity index 100% rename from py_enjoy/template/stat/ast/Output.py rename to pyenjoy/template/stat/ast/Output.py diff --git a/py_enjoy/template/stat/ast/Stat.py b/pyenjoy/template/stat/ast/Stat.py similarity index 100% rename from py_enjoy/template/stat/ast/Stat.py rename to pyenjoy/template/stat/ast/Stat.py diff --git a/py_enjoy/template/stat/ast/Text.py b/pyenjoy/template/stat/ast/Text.py similarity index 100% rename from py_enjoy/template/stat/ast/Text.py rename to pyenjoy/template/stat/ast/Text.py diff --git a/py_enjoy/template/stat/ast/__init__.py b/pyenjoy/template/stat/ast/__init__.py similarity index 100% rename from py_enjoy/template/stat/ast/__init__.py rename to pyenjoy/template/stat/ast/__init__.py diff --git a/render_example.py b/render_example.py new file mode 100644 index 0000000..bb38d91 --- /dev/null +++ b/render_example.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python3.9 +# -*- coding: utf-8 -*- +""" +Example demonstrating how to use the render function +""" + +from pyenjoy.template.Engine import Engine + +# Initialize the engine (global instance) +engine = Engine.use() + +# Configure the engine (optional) +engine.base_template_path = "./templates" # Set base template directory +engine.encoding = "utf-8" # Set template encoding +engine.dev_mode = True # Enable auto-reload for development + +def render(page, data): + """ + Render a template file with provided data + + Args: + page: Template file name (relative to base_template_path) + data: Dictionary with template data + + Returns: + Rendered template string + """ + template = engine.get_template(page) + result = template.render_to_string(data) + return result + +def render_string(template_content, data): + """ + Render a template string with provided data + + Args: + template_content: Template content as string + data: Dictionary with template data + + Returns: + Rendered template string + """ + template = engine.get_template_by_string(template_content) + result = template.render_to_string(data) + return result + +# Example usage +if __name__ == "__main__": + # Example 1: Render from file + print("Example 1: Render from file") + print("=" * 50) + try: + # Create a simple template file for testing + import os + # os.makedirs("./templates", exist_ok=True) + # with open("./templates/test.html", "w", encoding="utf-8") as f: + # f.write("Hello, #(name)!") + + # Render the template + data = {"name": "World", "items": [ + {"id": 1, "title": "文章1", "author": "张三", "tags": ["cdms", "管理系统"], "create_time": "2023-01-01"}, + {"id": 2, "title": "文章2", "author": "李四", "tags": ["python"], "create_time": "2023-02-01"} + ]} + result = render("test.html", data) + print(f"Rendered result: {result}") + + # Clean up + # os.remove("./templates/test.html") + # os.rmdir("./templates") + except Exception as e: + print(f"Error: {e}") + + # Example 2: Render from string + print("\nExample 2: Render from string") + print("=" * 50) + template_content = "Name: #(name), Age: #(age??'未知')" + data = {"name": "张三"} + result = render_string(template_content, data) + print(f"Rendered result: {result}") + + # Example 3: Render with filters + print("\nExample 3: Render with filters") + print("=" * 50) + template_content = "Tags: #(tags | join(', '))" + data = {"tags": ["cdms", "管理系统"]} + result = render_string(template_content, data) + print(f"Rendered result: {result}") + + print("\nAll examples completed!") diff --git a/setup.py b/setup.py index 367fde3..80d7b40 100644 --- a/setup.py +++ b/setup.py @@ -8,14 +8,14 @@ with open(os.path.join(os.path.dirname(__file__), 'README.md'), 'r', encoding='u long_description = f.read() setup( - name='py_enjoy', - version='5.2.2', - description='Python implementation of JFinal Template Engine', + name='py-enjoy', + version='1.0.1', + description='JFinal-Enjoy Python 3.9+ 实现,基于5.2.2版本', long_description=long_description, long_description_content_type='text/markdown', author='James Zhan 詹波 (original), Python port by mrzhou@miw.cn', author_email='mrzhou@miw.cn', - url='https://github.com/yourusername/py_enjoy', # 请替换为实际的GitHub仓库URL + url='https://git.miw.cn/mrzhou/py_enjoy.git', # 请替换为实际的GitHub仓库URL license='Apache-2.0', packages=find_packages(), include_package_data=True, @@ -33,5 +33,5 @@ setup( 'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: Text Processing :: Markup', ], - keywords='template engine, jfinal, python', + keywords='template engine, jfinal, enjoy, python', ) diff --git a/templates/test.html b/templates/test.html new file mode 100644 index 0000000..da224d0 --- /dev/null +++ b/templates/test.html @@ -0,0 +1,23 @@ +Hello, #(name.join("====="))! + +#for(item in items) + +