ruby on rails - rails - Bucle y salida content_tags dentro de content_tag en helper
rails routes (5)
Estoy probando un método auxiliar que generará una lista de elementos, que se llamará así:
foo_list( [''item_one'', link_to( ''item_two'', ''#'' ) ... ] )
He escrito el ayudante así después de leer Uso de ayudantes en los rieles 3 para generar html :
def foo_list items
content_tag :ul do
items.collect {|item| content_tag(:li, item)}
end
end
Sin embargo, solo obtengo un UL vacío en ese caso, si hago esto como una prueba:
def foo_list items
content_tag :ul do
content_tag(:li, ''foo'')
end
end
Obtengo el UL & LI como se esperaba.
He intentado cambiarlo un poco haciendo:
def foo_list items
contents = items.map {|item| content_tag(:li, item)}
content_tag( :ul, contents )
end
En ese caso, obtengo la lista completa, pero las etiquetas LI son html escapadas (aunque las cadenas son HTML seguras). Hacer content_tag(:ul, contents.join("/n").html_safe )
funciona pero me parece mal y creo que content_tag
debería funcionar en modo de bloque con una colección de alguna manera.
El gran problema es que content_tag no hace nada inteligente cuando recibe matrices, debe enviar contenido ya procesado. Descubrí que una buena forma de hacerlo es doblar / reducir la matriz para resolverlo todo junto.
Por ejemplo, su primer y tercer ejemplo pueden usar lo siguiente en lugar de su línea items.map/collect:
items.reduce(''''.html_safe) { |x, item| x << content_tag(:li, item) }
Para referencia, aquí está la definición de concat que está ejecutando cuando ejecuta este código (de 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
Junto con las respuestas anteriores, esto me funcionó bien:
(1..14).to_a.each do |age|
concat content_tag :li, "#{link_to age, ''#''}".html_safe
end
No pude conseguir ese trabajo mejor.
Si ya estuvieras usando HAML , podrías escribir a tu ayudante así:
def foo_list(items)
haml_tag :ul do
items.each do |item|
haml_tag :li, item
end
end
end
Uso desde la vista:
- foo_list(["item_one", link_to("item_two", "#"), ... ])
La salida se pretende correctamente.
Podría usar content_tag_for
, que funciona con colecciones:
def foo_list(items)
content_tag(:ul) { content_tag_for :li, items }
end
Actualización: En Rails 5 content_tag_for
(y div_for
) se movieron a una gema separada. Tienes que instalar la gema record_tag_helper
para poder usarlos.
Prueba esto:
def foo_list items
content_tag :ul do
items.collect {|item| concat(content_tag(:li, item))}
end
end