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

时间:2011-10-27 17:06:08

标签: ruby-on-rails-3 template-engine liquid

我在Liquid中创建了一个自定义链接标记,我试图将液体变量传递给该标记的调用,如此

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

然而,这会导致article参数按照上面的assign语句以'id'而不是'something'传递。

有谁知道如何将变量传递给标记调用?

4 个答案:

答案 0 :(得分:6)

我最近通过将变量的名称作为标记参数传递给Jekyll 0.11.2和Liquid 2.3.0来解决这个问题。

{% assign v = 'art' %}
{% link_to_article v %}

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

Liquid::Tag.initialize中,@markup是第二个参数,即标记名称后面的字符串。已分配的变量位于context的顶层。

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

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

答案 1 :(得分:4)

看起来这不可能,我的解决方案是将变量名称传递给标记,并将其从标记正在呈现的上下文中抓取。如下所示:

{% 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

答案 2 :(得分:4)

这解决了我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)

*这只是Jonathan Julian上面给出的答案的一个更丰富的例子

答案 3 :(得分:0)

拥有一个可以使用文字和变量(如

)调用的标记会很棒
{% 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