在液体标签调用中使用液体变量

Posted

技术标签:

【中文标题】在液体标签调用中使用液体变量【英文标题】:using Liquid variables inside of a liquid tag call 【发布时间】:2011-12-16 16:56:32 【问题描述】:

我在 Liquid 中创建了一个自定义链接标签,并且我正在尝试能够像这样将液体变量传递到该标签的调用中

 assign id = 'something'  // this value is actual dynamic while looping through data 
% link_to article: id, text: 'Click Me!' % // my custom tag

但是,这会导致 article 参数按照上面的分配语句作为“id”而不是“something”传入。

有人知道如何将变量传递给标签调用吗?

【问题讨论】:

【参考方案1】:

我最近使用 Jekyll 0.11.2 和 Liquid 2.3.0 非常简单地解决了这个问题,方法是将变量的 name 作为标记参数传递。

% assign v = 'art' %
% link_to_article v %

您还可以在循环中传递控件变量的名称,例如上面的article

Liquid::Tag.initialize中,@markup是第二个参数,标签名后面的字符串。分配的变量在 context 的顶层可用。

def render(context)
  "/#context[@markup.strip]/"
end

这显然只允许传递一个参数。更复杂的解决方案会解析 x: 2, y: 3 之类的参数。

【讨论】:

【参考方案2】:

这为我解决了这个问题context[@markup.strip]

我的问题是我希望能够像这样将变量传递给我的自定义 Liquid 标签:% get_menu main_menu navigation.html settings.theme.id %

为了做到这一点,我首先将变量字符串拆分为每个空格字符上的不同变量。

class GetMenu < Liquid::Tag
    include ApplicationHelper
    def initialize(tag_name, variables, tokens)

        @variables = variables.split(" ")

        @menu_object = @variables[0]
        @file_name = @variables[1]
        @theme_id = @variables[2]

        super
    end

    def render(context)

        # This is where i use context[@theme_id.strip] to get the variable of "settings.theme.id"
        content = CodeFile.find_by(hierarchy: 'snippet', name: @file_name.to_s, theme_id: context[@theme_id.strip])

        @menu ||= Menu.find_by_slug(@menu_object)

        context.merge('menu' => @menu)

        Liquid::Template.parse(content.code).render(context)

    end

end

Liquid::Template.register_tag('get_menu', GetMenu)

*这只是一个比上面乔纳森朱利安的答案更丰富的例子

【讨论】:

【参考方案3】:

看起来这不可能,我的解决方案是将变量名传递给标签,然后从标签呈现的上下文中获取它。像这样:

% for article in category.articles %
  % link_to variable: article, text: title %
% endfor %

在我的标签代码中(精简):

def render(context)
  uri = "article/#context[@options[:variable]]['id']"
  "<a href='#uri'>#build_link_text context</a>"
end

【讨论】:

【参考方案4】:

如果有一个可以用文字和变量调用的标签,那就太好了

% assign v = 'art' %
% link_to_article v %

% link_to_article 'art' %

% link_to_article "art" %

当然还有

% link_to_article include.article %

为此我提出了一个辅助函数

def get_value(context, expression)
  if (expression[0]=='"' and expression[-1]=='"') or (expression[0]=="'" and expression[-1]=="'")
    # it is a literal
    return expression[1..-2]
  else
    # it is a variable
    lookup_path = expression.split('.')
    result = context
    puts lookup_path
    lookup_path.each do |variable|
      result = result[variable] if result
    end
    return result
  end
end

并且在渲染中只需调用辅助函数来获取文字或变量的值。

def render(context)
  v = get_value(context, @markup.strip)
end

仅供参考,初始化程序如下所示:

def initialize(tag_name, markup, tokens)
  @markup = markup
  super
end

【讨论】:

如果我目前只在 Shopify 平台上编辑液体,您能否指点我实现您的辅助功能的快车?

以上是关于在液体标签调用中使用液体变量的主要内容,如果未能解决你的问题,请参考以下文章

如何转义液体模板标签?

在 YAML 变量中包含 jekyll / 液体模板数据?

在 Shopify 液体模板中使用 vue.js

ruby Jekyll:Font Awesome icons液体标签

ruby Jekyll:Font Awesome icons液体标签

ruby Jekyll:Font Awesome icons液体标签