是否可以使用提供的格式格式化每个值?

Is it possible to format each value using supplied format?

我有这个程序

private static void RunUsingILiquidizable()
{
    const string templateString = @"TopInt prop: '{{TopInt}}'; Child.Prop prop: '{{L1Prop.L1Int}}'; Child.Child.Prop prop: '{{L1Prop.L2Prop.L2Int}}'; Dict item: '{{ExtendedProps.Key1}}'";
    Template.NamingConvention = new CSharpNamingConvention();
    Template.RegisterValueTypeTransformer(typeof(DateTime), (v) => ((DateTime)v).ToString("MM=dd=yy"));
    var t = Template.Parse(templateString);

    var model = new TopModel()
    {
        TopInt = 23,
        L1Prop = new L1Model()
        {
            L1Int = 34,
            L2Prop = new L2Model() { L2Int = 98 }
        },
        ExtendedProps = new Dictionary<string, object>() { { "Key1", DateTime.Now } }
    };

    string output = t.Render(Hash.FromAnonymousObject(model));

    Console.WriteLine("RunUsingILiquidizable -->" + output);

}

顶级模型定义:

public class TopModel : ILiquidizable
{
    public int TopInt { get; set; }
    public L1Model L1Prop { get; set; }
    public Dictionary<string, object> ExtendedProps { get; set; }
    public object ToLiquid()
    {
        return new { TopInt, L1Prop, ExtendedProps };
    }
}

输出:

RunUsingILiquidizable -->TopInt prop: '23'; Child.Prop prop: '34'; Child.Child.P rop prop: '98'; Dict item: '08=27=19'

我的问题是 - Template.RegisterValueTypeTransformer 全局类型格式和 template.Render(Hash.FromAnonymousObject(model), MyFormatProvider) 格式所有日期,数字相同。

我需要的是在需要时通过提供格式以不同方式格式化每个特定标记。对字典特别重要 ExtendedProps.

我也试过做过滤器,但有没有办法传递类似 {{ExtendedProps.Key1 | SpecialFormat("dd--MM")}} 的东西??

我鼓励您检查 StandardFilters class 的源代码。自定义过滤器可以做的比 wiki 文档让您相信的要多,标准过滤器展示了其中的大部分内容。如果您已经看到标准过滤器执行某些操作,您可以编写一个自定义过滤器来执行相同的操作。

这是一个示例 custom_date 过滤器:

public static class CustomFilter
{
    public static string CustomDate(Context context, object input, string format = null, string culture = null)
    {
        if (input is DateTime dt)
        {
            IFormatProvider formatProvider = !string.IsNullOrEmpty(culture)
                ? CultureInfo.GetCultureInfo(culture)
                : context.FormatProvider;

            return dt.ToString(format, formatProvider);
        }

        return null;
    }
}

兴趣点:

  1. 它接受一个初始的 Context 参数,其中包括 FormatProvider 属性 类型的 IFormatProviderCultureInfo 实现) .如果你需要它的东西,你只需要包括这个参数。

  2. 它接受多个参数:

    一个。一种格式,如某些 ToString 重载,只是通过它。

    b。它检索 CultureInfo 的区域设置,或者,如果 null"",则默认为 context.FormatProvider,这是传递给 [=24 的可选 IFormatProvider =] 或当前文化。

  3. 参数默认即可。总的来说,这可能是个好主意,因为无法在模板中要求它们。

用法示例

Template.Register(typeof(CustomFilter));

CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
var template = Template.Parse("Today is {{ today | custom_date: 'd' }} (current culture), {{ today | custom_date: 'd', 'fr-CA' }} (fr-CA), and {{ today | custom_date: 'd', elsewhere }} ({{ elsewhere }}).");
string output = template.Render(Hash.FromAnonymousObject(new { today = DateTime.Today, elsewhere = "de-DE" }));

输出

Today is 8/30/2019 (current culture), 2019-08-30 (fr-CA), and 30.08.2019 (de-DE).

更多兴趣点:

  1. 参数在冒号后指定,如果有多个参数,则用逗号分隔。

  2. 您传递给 Render 的 "hash" 中的值可以在您传递的参数中引用(例如 elsewhere)。

  3. "d" 标准格式对文化敏感,因此您可以看到当前文化 (en-US)、硬编码文化 (fr-CA ), 参数化的文化 (de-DE) 都可以使用.