ruby Moustache lambda可以获得内插值吗?

问题描述 投票:1回答:1

使用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}}'

有线索吗?

ruby mustache
1个回答
0
投票

你真正想要做的是添加逻辑,所以最简单的方法就是应用它:

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,我认为逻辑和模板之间的分离很棒!

© www.soinside.com 2019 - 2024. All rights reserved.