如何在Rails 5的Liquid模板中实现日期本地化?
我之前在Rails项目里用Liquid做用户内容生成时,也碰到过这个日期本地化的问题——原生Ruby Liquid确实没内置这个功能,但我们可以通过对接Rails的I18n本地化系统来实现,和你用l方法的效果完全一致,具体可以这么做:
实现Liquid日期本地化的步骤
1. 自定义Liquid本地化日期过滤器
首先我们要写一个自定义的Liquid过滤器,让它能读取Rails的I18n配置,替代或补充原生的date过滤器。
在你的Rails项目中新建一个过滤器文件,比如app/liquid_filters/localized_date_filter.rb,内容如下:
module LocalizedDateFilter def localized_date(date, format_key = :default) # 从Liquid上下文获取传入的locale,默认用Rails全局默认locale current_locale = @context.registers[:locale] || I18n.default_locale # 调用Rails的I18n格式化方法,和你用的`l`逻辑一致 I18n.l(date, format: format_key, locale: current_locale) end end # 把过滤器注册到Liquid模板系统 Liquid::Template.register_filter(LocalizedDateFilter)
2. 给Liquid模板传递Locale参数
在初始化Liquid模板的时候,需要把当前的locale通过registers传递给模板上下文,这样过滤器才能拿到对应的本地化配置:
# 假设你已经拿到了目标locale(可以从用户设置、请求参数或I18n.locale获取) target_locale = 'fr' # 比如用户选择法语时的locale值 # 你的Liquid模板字符串,改用自定义的localized_date过滤器 template_string = "Order {{ order.id }} was created {{ order.date | localized_date: :long }}" template = Liquid::Template.parse(template_string) # 渲染时通过registers传入locale rendered_result = template.render( {'order' => {'id' => '123', 'date' => order.date}}, registers: {locale: target_locale} )
3. 完善对应语言的本地化配置
确保你已经为目标语言配置了正确的日期格式,比如法语的config/locales/fr.yml:
fr: datetime: &datetime month_names: [~, janvier, février, mars, avril, mai, juin, juillet, août, septembre, octobre, novembre, décembre] day_names: [dimanche, lundi, mardi, mercredi, jeudi, vendredi, samedi] abbr_day_names: [~, dim., lun., mar., mer., jeu., ven., sam.] formats: default: "%d/%m/%Y" long: "%A %d/%m/%Y"
4. 在Liquid模板中使用
现在你可以像使用Rails的l方法一样,在Liquid模板里调用自定义过滤器:
- 使用默认格式:
{{ order.date | localized_date }} - 指定格式key(对应本地化文件里的
formats项):{{ order.date | localized_date: :long }}
如果想直接替换原生的date过滤器(让用户不用改模板里的过滤器名),只需要把过滤器方法名改成date就行,但要注意可能和原生date过滤器的硬编码格式功能冲突,所以更推荐保留原生功能,用自定义的过滤器名称。
内容的提问来源于stack exchange,提问作者JohnSmith1976
相关产品推荐
相关产品推荐

