如何在Liquid中本地化日期?

11

在我的Rails 5应用程序中,我使用Liquid让用户生成内容。

根据用户的输入,我使用以下方式初始化模板:

string   = "Order {{ order.id }} was created {{ order.date | date: '%A %d/%m-%Y' }}"
template = Liquid::Template.parse(string)
result   = template.render({'order' => {'id' => '123', 'date' => order.date}})

这将会打印出类似于:

'Order 123 was created Sunday 14/01-2018'

但是我该如何将Liquid日期本地化构建到我的Rails应用程序中呢?

文件文档中似乎没有支持此功能。然而,Shopify自己似乎已经在他们的Liquid实现中构建了本地化

我想我需要传递模板语言环境(enfr等)和语言环境文件。我的Rails语言环境文件如下:

en:
  datetime: &datetime
    month_names:
      [~, January, February, March, April, May, June, July, August, September, October, November, December]
    day_names:
      [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
    abbr_day_names:
      [~, Sun, Mon, Thue, Wed, Thu, Fri, Sat]
    formats:
       default: "%d/%m/%Y"
       long: "%A %d/%m-%Y"

我称之为:

l(order.date, :format => :long, :locale => 'en')

我希望在我的Liquid模板中能够使用类似的日期本地化功能。


你可能可以故意调用 I18n.localize?http://www.stackednotion.com/blog/2015/01/03/formatting-dates-and-times-in-rails-with-i18n-localize/ 看起来相关 - 它展示了如何故意传递一个区域设置并使用自定义日期格式(但请注意,我只花了大约5秒钟思考这个问题...) - Taryn East
请返回已翻译的文本。 - Ben
感谢@Ben,我已经使用这种方法来注册一个过滤器,它执行l(order.date,:format =>:long,:locale =>'en')。如果没有其他更好的解决方案,我将把它写成答案。但它并不完美,因为它将我限制在一组预定义的“格式”中。 - JohnSmith1976
4个回答

2

我最终使用了@Ben提供的链接,并编写了以下解决方案:

# config/initializers/liquid_filters.rb
module I18nFilters
  def l(date, format)
    I18n.l(date, :format => format.to_sym)
  end
end

Liquid::Template.register_filter(I18nFilters)

现在,当调用这个新方法时:
{{ order.date | l: 'long' }}

它将打印出:

'Sunday 14/01-2018'

其中的Sunday是在语言环境文件中day_names中的内容。


0

当您使用order.date传递日期对象时

result   = template.render({'order' => {'id' => '123', 'date' => order.date}})

你能传递一个本地化的日期或本地化的日期时间吗?这样当它被呈现时就应该是正确的。
否则,你可以将日期添加到一个具有可定位类名的 span 中(作为备用方案),并使用纯 JavaScript 和类似 Moment.js 的库在客户端上“修复”它。
# https://dev59.com/GWgv5IYBdhLWcg3wW_l_#39161134
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;

嗨@engineerDave,使用JS进行修改是我想避免的一种hack。但第一个建议对我来说更像是一个问题。我不确定我是否理解它。 - JohnSmith1976
当您将order.date传递到Liquid模板时,我会假设您知道要显示数据的人的语言环境。如果不知道,您可以在Rails中进行设置,具体请参考http://guides.rubyonrails.org/i18n.html。这将使您能够将正确本地化的日期传递到模板中。 - engineerDave

0

看起来你只是缺少对 t 方法的引用。

而不是

string   = "Order {{ order.id }} was created {{ order.date | date: '%A %d/%m-%Y' }}"

尝试使用

string   = "Order {{ order.id }} was created {{ order.date | t: date: '%A %d/%m-%Y' }}"

0

您可以使用JavaScript Intl API来完成。

将此过滤器添加到.eleventy.js中:

  eleventyConfig.addFilter("displayDate", function(date, locale) {
    return new Intl.DateTimeFormat(locale, { dateStyle: "long" }).format(date);
  });

现在你可以在你的Liquid模板中使用以下代码来显示本地化日期:

{{ date | displayDate: locale }}

这里,date 包含日期,locale 包含区域设置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接