swagger_generator_flutter/lib/pipeline/render/impl/template_renderer.dart

93 lines
2.5 KiB
Dart

import 'dart:io';
import 'package:mustache_template/mustache_template.dart';
import 'package:path/path.dart' as p;
import 'package:swagger_generator_flutter/core/config_repository.dart';
import 'package:swagger_generator_flutter/utils/path_resolver.dart';
part 'template/template_loader.dart';
/// 模板渲染器
/// 负责加载和渲染 Mustache 模板,支持文件覆盖与内置模板
class TemplateRenderer {
TemplateRenderer({
String? templateRoot,
List<String>? extraTemplateRoots,
}) : _loader = TemplateLoader(
customRoot: templateRoot,
extraRoots: extraTemplateRoots,
),
_baseContext = _buildBaseContext();
final TemplateLoader _loader;
final Map<String, Template> _templateCache = {};
final Map<String, dynamic> _baseContext;
/// 渲染模板
///
/// [templateName] 模板名称(不含 .mustache 扩展名)
/// [data] 模板数据
String render(
String templateName,
Map<String, dynamic> data, {
Map<String, String>? partials,
}) {
final template = _getTemplate(templateName);
final context = {..._baseContext, ...data};
return template.renderString(context);
}
/// 部分模板解析器
Template? _partialResolver(String name) {
try {
return _getTemplate(name);
} on Exception {
return null;
}
}
/// 获取模板(带缓存)
Template _getTemplate(String templateName) {
if (_templateCache.containsKey(templateName)) {
return _templateCache[templateName]!;
}
final source = _getTemplateSource(templateName);
final template = Template(
source,
name: templateName,
lenient: true,
htmlEscapeValues: false,
partialResolver: _partialResolver,
);
_templateCache[templateName] = template;
return template;
}
/// 获取模板源码:优先文件,其次内嵌
String _getTemplateSource(String templateName) {
final fileTemplate = _loader.load(templateName);
if (fileTemplate != null) {
return fileTemplate;
}
throw Exception('Template not found in file system: $templateName');
}
/// 清除模板缓存
void clearCache() {
_templateCache.clear();
_loader.clearCache();
}
static Map<String, dynamic> _buildBaseContext() {
// Load once synchronously to avoid repeated disk IO
final config = ConfigRepository.loadSync();
return {
'generatorName': config.generatorName,
'author': config.author,
'copyright': config.copyright,
};
}
}