использование переменных Liquid внутри вызова тега Liquid - PullRequest
18 голосов
/ 27 октября 2011

Я создал пользовательский тег ссылки в 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» вместо «что-то» в соответствии с оператором assign над ним.

Кто-нибудь знает, как передавать переменные в вызовы тегов?

Ответы [ 4 ]

7 голосов
/ 12 августа 2012

Недавно я решил это очень просто с помощью 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.

5 голосов
/ 14 апреля 2014

Это решило дело для меня 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)

* Это просто более богатый пример, чем приведенный выше ответ Джонатана Джулиана

5 голосов
/ 28 октября 2011

Не похоже, что это возможно, мое решение состояло в том, чтобы просто передать имя переменной в тег и извлечь его из контекста, в котором отображается тег. Примерно так:

{% 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
1 голос
/ 29 июля 2017

Было бы здорово иметь тег, который можно вызывать с литералами и переменными, такими как

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