using NCC.ClayObject.Extensions;
using NCC.Dependency;
using NCC.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace NCC.Templates.Extensions
{
///
/// 字符串渲染模板拓展类
///
[SuppressSniffer]
public static class StringRenderExtensions
{
///
/// 模板正则表达式
///
private const string commonTemplatePattern = @"\{(?
.+?)\}";
///
/// 读取配置模板正则表达式
///
private const string configTemplatePattern = @"\#\((?
.*?)\)";
///
/// 渲染模板
///
///
///
///
public static void Render(this string template, object templateData, bool encode = false)
{
if (template == null) return;
template.Render(templateData == null ? default : templateData.ToDictionary(), encode);
}
///
/// 渲染模板
///
///
///
///
///
public static string Render(this string template, IDictionary templateData, bool encode = false)
{
if (template == null) return default;
// 如果模板为空,则跳过
if (templateData == null || templateData.Count == 0) return template;
// 判断字符串是否包含模板
if (!Regex.IsMatch(template, commonTemplatePattern)) return template;
// 获取所有匹配的模板
var templateValues = Regex.Matches(template, commonTemplatePattern)
.Select(u => new {
Template = u.Groups["p"].Value,
Value = MatchTemplateValue(u.Groups["p"].Value, templateData)
});
// 循环替换模板
foreach (var item in templateValues)
{
template = template.Replace($"{{{item.Template}}}", encode ? Uri.EscapeDataString(item.Value?.ToString() ?? string.Empty) : item.Value?.ToString());
}
return template;
}
///
/// 从配置中渲染字符串模板
///
///
///
///
public static string Render(this string template, bool encode = false)
{
if (template == null) return default;
// 判断字符串是否包含模板
if (!Regex.IsMatch(template, configTemplatePattern)) return template;
// 获取所有匹配的模板
var templateValues = Regex.Matches(template, configTemplatePattern)
.Select(u => new {
Template = u.Groups["p"].Value,
Value = App.Configuration[u.Groups["p"].Value]
});
// 循环替换模板
foreach (var item in templateValues)
{
template = template.Replace($"#({item.Template})", encode ? Uri.EscapeDataString(item.Value?.ToString() ?? string.Empty) : item.Value?.ToString());
}
return template;
}
///
/// 匹配模板值
///
///
///
///
private static object MatchTemplateValue(string template, IDictionary templateData)
{
string tmpl;
if (!template.Contains('.', StringComparison.CurrentCulture)) tmpl = template;
else tmpl = template.Split('.', StringSplitOptions.RemoveEmptyEntries).First();
var templateValue = templateData.ContainsKey(tmpl) ? templateData[tmpl] : default;
return ResolveTemplateValue(template, templateValue);
}
///
/// 解析模板的值
///
///
///
///
private static object ResolveTemplateValue(string template, object data)
{
// 根据 . 分割模板
var propertyCrumbs = template.Split('.', StringSplitOptions.RemoveEmptyEntries);
return GetValue(propertyCrumbs, data);
// 静态本地函数
static object GetValue(string[] propertyCrumbs, object data)
{
if (data == null || propertyCrumbs == null || propertyCrumbs.Length <= 1) return data;
var dataType = data.GetType();
// 如果是基元类型则直接返回
if (dataType.IsRichPrimitive()) return data;
object value = null;
// 递归获取下一级模板值
for (var i = 1; i < propertyCrumbs.Length; i++)
{
var propery = dataType.GetProperty(propertyCrumbs[i]);
if (propery == null) break;
value = propery.GetValue(data);
if (i + 1 < propertyCrumbs.Length)
{
value = GetValue(propertyCrumbs.Skip(i).ToArray(), value);
}
else break;
}
return value;
}
}
}
}