Цикл и выводить content_tags в пределах content_tag в помощнике - PullRequest
28 голосов
/ 12 января 2011

Я пытаюсь использовать вспомогательный метод, который будет выводить список элементов, который будет вызываться следующим образом:

foo_list( ['item_one', link_to( 'item_two', '#' ) ... ] )

Я написал вспомогательный метод, прочитав Использование помощников в рельсах 3для вывода html :

def foo_list items
    content_tag :ul do
        items.collect {|item| content_tag(:li, item)}
    end
end

Однако я получаю пустой UL в этом случае, если я делаю это в качестве теста:

def foo_list items
    content_tag :ul do
        content_tag(:li, 'foo')
    end
end

Я получаю UL & LIкак и ожидалось.

Я попытался немного поменять его местами, выполнив:

def foo_list items
    contents = items.map {|item| content_tag(:li, item)}
    content_tag( :ul, contents )
end

В этом случае я получаю весь список, но теги LI экранируются html (даже если строкиHTML безопасно).Выполнение content_tag(:ul, contents.join("\n").html_safe ) работает, но мне кажется, что это неправильно, и я чувствую, что content_tag должен как-то работать в режиме блокировки с коллекцией.

Ответы [ 5 ]

49 голосов
/ 13 января 2011

Попробуйте это:

def foo_list items
  content_tag :ul do
      items.collect {|item| concat(content_tag(:li, item))}
  end
end
8 голосов
/ 12 января 2011

Я не мог получить эту работу лучше.

Если вы уже использовали HAML , вы могли бы написать свой помощник так:

def foo_list(items)
  haml_tag :ul do
    items.each do |item|
      haml_tag :li, item
    end
  end
end

Использованиеиз вида:

- foo_list(["item_one", link_to("item_two", "#"), ... ])

Вывод будет правильно рассчитан.

5 голосов
/ 02 июля 2013

Вы можете использовать content_tag_for, который работает с коллекциями:

def foo_list(items)
  content_tag(:ul) { content_tag_for :li, items }
end

Обновление: В Rails 5 content_tag_fordiv_for)были перемещены в отдельный драгоценный камень.Вы должны установить гем record_tag_helper, чтобы использовать их.

3 голосов
/ 09 июня 2015

Наряду с ответами выше, это сработало для меня хорошо:

(1..14).to_a.each do |age|
  concat content_tag :li, "#{link_to age, '#'}".html_safe
end
2 голосов
/ 29 ноября 2011

Большая проблема в том, что content_tag не делает ничего умного, когда получает массивы, вам нужно отправить ему уже обработанный контент.Я обнаружил, что хороший способ сделать это состоит в том, чтобы сложить / уменьшить ваш массив, чтобы объединить его все вместе.

Например, ваш первый и третий пример может использовать следующее вместо вашего items.map/collectстрока:

items.reduce(''.html_safe) { |x, item| x << content_tag(:li, item) }

Для справки, вот определение concat, с которым вы сталкиваетесь при выполнении этого кода (из actionpack / lib / action_view / helpers / tag_helper.rb).

def concat(value)
  if dirty? || value.html_safe?
    super(value)
  else
    super(ERB::Util.h(value))
  end
end
alias << concat
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...