【问题标题】:How to get list of variables referenced in a liquid template如何获取液体模板中引用的变量列表
【发布时间】:2015-04-17 10:08:07
【问题描述】:

我正在开发一个使用 Liquid 模板语言的项目。我有一个带有 iframe 的页面,其中显示了一些渲染的液体模板和一个编辑器部分。在编辑器部分,用户可以更改液体模板中引用的一些变量的值。此时需要重新渲染一些模板,但我只想重新渲染那些引用已更改变量的模板。

我坚持的一点是如何最好地获取液体模板中引用的变量列表。

如果我这样做:

templates=[]
templates[0] = Liquid::Template.parse("hi {{name}}") 
templates[1] = Liquid::Template.parse("my cat is called {{cat_name}}") 

我想知道'name'被引用但(例如)'cat'不在模板0中。然后当名字改变时我可以重新渲染模板[0]并且当cat改变时我可以重新-渲染模板[1]。

我发现我可以获取节点列表并检查每个节点以查看它是否是变量,例如templates[0].root.nodelist[1] 的类型为“Liquid::Variable”,但变量的“name”方法返回一个“Liquid::VariableLookup”类型的对象,而该对象似乎没有一种从中获得名字的方法,这感觉就像我可能会以错误的方式去做。

【问题讨论】:

  • 好吧,也许这是一个错误,我刚刚提交了这个:github.com/Shopify/liquid/issues/547
  • 由于我向液体开发人员询问了这一点,因此改变了此行为,液体 4.0.2 支持此行为

标签: ruby liquid


【解决方案1】:

https://github.com/Shopify/liquid/issues/685#issuecomment-471499796 之后,您可以使用FileTreeVisitor 类。即:

template = Liquid::Template.parse("hi {{name}}")

Liquid::ParseTreeVisitor.for(template.root)
  .add_callback_for(Liquid::VariableLookup) do |node|
  [node.name, *node.lookups].join('.')
end.visit.flatten.compact # => ["name"]

【讨论】:

【解决方案2】:

Liquid::VariableLookup 有一个name 方法。这有效:

markup = 'My name is {{ my_name }} and I live in {{ my_address}}.'
template = Liquid::Template.parse(markup)  
template.root.nodelist
  .select{ |node| node.is_a?(Liquid::Variable)}
  .map{ |var| var.name.name } # => ["my_name", "my_address"]

但如果标记有其他标签,则可能会出现问题。解决方案将因此标记而失败:

'My name is {% if condition == "big" %} Big {% endif %} {{ name }}'

它无法在if 标记内捕获变量condition。最好坚持@asok 建议的ParseTreeVisitor 解决方案。

【讨论】:

    猜你喜欢
    • 2022-11-28
    • 1970-01-01
    • 2021-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-22
    • 2012-01-05
    • 2013-01-07
    相关资源
    最近更新 更多