Rails 文本助手 - A、B、C 和 D
Rails text helpers - A, B, C and D
我觉得这应该存在,但我正在寻找一个 Rails 助手来处理列出项目集合。
# Input and expected output
[1,2,3,4] # 1, 2, and 2 others.
[1,2,3] # 1, 2, and 3.
[1,2] # 1 and 2.
[1] # 1.
有这样的东西吗?
也许是这个?
[1,2,3].to_sentence
=> "1, 2 and 3"
Archer 回答了这个问题,但是我的用例需要更多的定制,所以我最终(无论好坏)重新发明了轮子。
sig do
params(
items: T::Array[T.untyped],
count: Integer,
renderer: T.nilable(T.proc.params(arg0: T.untyped).returns(String)),
final_renderer:
T.nilable(T.proc.params(arg0: T.untyped).returns(String)),
)
.returns(T.untyped)
end
def listicle(items, count: 3, renderer: nil, final_renderer: nil)
SolidAssert.assert(items.size > 0, 'Must provide at least 1 item.')
buffer = ''
rendered_items =
items.first(count).map { |item| renderer ? renderer.call(item) : item }
if items.size <= count
# Case: All items can be inlined.
if rendered_items.size == 1
buffer = rendered_items.join
else
items_before_and = rendered_items.first(rendered_items.size - 1)
last_item = rendered_items.last
buffer = items_before_and.join(', ')
buffer << " and #{last_item}"
end
else
# Case: There are too many items so we render an "and 1 other..." item.
remaining_count = items.size - count
final_item =
if final_renderer
final_renderer.call(remaining_count)
else
"#{ApplicationController.helpers.pluralize(remaining_count, 'other')}"
end
buffer = rendered_items.join(', ')
buffer << " and #{final_item}"
end
buffer.html_safe
end
我觉得这应该存在,但我正在寻找一个 Rails 助手来处理列出项目集合。
# Input and expected output
[1,2,3,4] # 1, 2, and 2 others.
[1,2,3] # 1, 2, and 3.
[1,2] # 1 and 2.
[1] # 1.
有这样的东西吗?
也许是这个?
[1,2,3].to_sentence
=> "1, 2 and 3"
Archer 回答了这个问题,但是我的用例需要更多的定制,所以我最终(无论好坏)重新发明了轮子。
sig do
params(
items: T::Array[T.untyped],
count: Integer,
renderer: T.nilable(T.proc.params(arg0: T.untyped).returns(String)),
final_renderer:
T.nilable(T.proc.params(arg0: T.untyped).returns(String)),
)
.returns(T.untyped)
end
def listicle(items, count: 3, renderer: nil, final_renderer: nil)
SolidAssert.assert(items.size > 0, 'Must provide at least 1 item.')
buffer = ''
rendered_items =
items.first(count).map { |item| renderer ? renderer.call(item) : item }
if items.size <= count
# Case: All items can be inlined.
if rendered_items.size == 1
buffer = rendered_items.join
else
items_before_and = rendered_items.first(rendered_items.size - 1)
last_item = rendered_items.last
buffer = items_before_and.join(', ')
buffer << " and #{last_item}"
end
else
# Case: There are too many items so we render an "and 1 other..." item.
remaining_count = items.size - count
final_item =
if final_renderer
final_renderer.call(remaining_count)
else
"#{ApplicationController.helpers.pluralize(remaining_count, 'other')}"
end
buffer = rendered_items.join(', ')
buffer << " and #{final_item}"
end
buffer.html_safe
end