使用Mustache的ruby实现,我试图通过使用lambdas提供一些数字格式化程序。我想要做的是接收插值和处理。这是一个类似于我一直在尝试的例子:
context = {
products: [
{ name: 'Widget', price: 1.2 },
{ name: 'Cog', price: 0.75 }
],
currency: ->(val) { '$' + BigDecimal(val).round(2) }
}
template = <<-EOF
|Product|Price|
{{#products}}
|{{name}}|{{#currency}}{{price}}{{/currency}}|
{{/products}}
EOF
Mustache.render(template, context)
我希望的是让货币lambda与产品的价格一起调用。相反,我收到了'{{price}}'
。我试图在lambda中使用Mustache.render(val)
,但它(似乎)没有适当的上下文来评估'{{price}}'
有线索吗?
你真正想要做的是添加逻辑,所以最简单的方法就是应用它:
context.each do |product|
product[:price] = to_currency.call(product[:price])
end
但是,我确实更深入地研究了这一点,并发现你可以做的是创建一个Mustache
类:
class Product < Mustache
attr_reader :name
def initialize(name, price)
@name, @price = name, price
end
def price
currency(@price)
end
private
def currency(price)
num_str = BigDecimal(price.to_s).round(2).to_s('F')
int, flt = num_str.split('.')
"$#{[int, flt.ljust(2, '0')].join('.')}"
end
end
template = <<-EOF
|Product|Price|
{{#products}}
|{{name}}|{{price}}|
{{/products}}
EOF
Mustache.render(template, products: [Product.new('Widget', 1.2), Product.new('Cog', 0.75)])
你甚至可以动态传递块:
class Foo < Mustache
def initialize(&block)
@block = block
end
def foo
@block.call(2)
end
end
tmp = <<~TMP
Blah Blah
blah {{foo}} blah
Blah
TMP
foo = Foo.new { |x| (x + x).to_s + "asdf" }
foo.render(tmp)
Mustache.render(tmp, foo)
在此之前我从未使用过Mustache,我认为逻辑和模板之间的分离很棒!