Использование жидкости для сортировки сообщений в алфавитном порядке
Есть ли способ отсортировать ряд сообщений в алфавитном порядке, используя Jekyll?
Теперь у меня есть что-то вроде этого:
{% for post in site.categories.threat %}
<li><a href="{{ post.url }}">{{ post.title }}</a></li>
{% endfor %}
Это работает,но столбы перемешаны. Было бы гораздо лучше, если бы они были отсортированы по алфавиту, я думаю.
Спасибо
7 ответов:
Это можно сделать без плагина, что означает, что он работает с страницами Github.
Однако вам придется использовать некоторые уродливые трюки манипулирования строками.
Я использовал аналогичный подход для реализации страницы тегов (в которой перечислены все сообщения для каждого тега).Тот же подход, слегка модифицированный:
{% capture posts %} {% for post in site.posts %} |{{ post.title }}#{{ post.url }} {% endfor %} {% endcapture %} {% assign sortedposts = posts | split: '|' | sort %} {% for post in sortedposts %} {% assign postitems = post | split: '#' %} <a href={{ postitems[1] }}">{{ postitems[0] }}</a><br> {% endfor %}
Берегись:
Вам нужно два различных символа разделителя внутри первого цикла (и, конечно, снова в вызовах
split
позже) .
для того, чтобы это сработало, оба символа не должны встречаться ни в одном из заголовков сообщений или URL!!Я использую
|
и#
в этом примере, который работает для меня (я только что протестировал его с моим блогом). Но вам может потребоваться использовать разные символы, в зависимости от названия вашей публикации и того, как построены ваши URL-адреса.
Бонус:
Если вы хотите отобразить только сообщения в определенном теге / категории (а не все сообщения) , Вы можно изменить первый цикл
for
(тот, что внутриcapture
) к одному из них:{% for post in site.tags['whatever'] %} {% for post in site.categories['whatever'] %}
Согласно документации, для фильтрации массива по одному из его полей можно использовать :
{% assign sortedPosts = site.posts | sort: 'title' %}
Тогда переменная
sortedPosts
будет содержать отсортированный массив.Документацию можно найти здесь: https://docs.shopify.com/themes/liquid/filters/array-filters#sort
Я адаптировал плагин Jekyll из https://gist.github.com/3812259 для достижения этой цели. Я не мог использовать плагин как есть, потому что он не работал при наличии нулевых значений. Я начинающий программист ruby, и закодировал обработку null с помощью https://stackoverflow.com/a/808721/1135052
Sort_for пример реверсирования сортировки и выполнения сравнения строк с учетом регистра (игнорируется, если свойство sorted не является строкой):
{% sorted_for node in site.pages reversed sort_by:title case_sensitive:true %} {{ node.title }} {% endsorted_for %}
Sorted_keys_for пример:
{% sorted_keys_for tag in site.tags %} <a href="/tags/{{ tag | downcase | replace:" ","-"}}.html">{{ tag }}</a><br /> Num posts: {{ site.tags[tag].size }} {% endsorted_keys_for %}
Для использования в Jekyll, поместите этот код в _plugins / sort_for.rb
module Jekyll module SortedForImpl def render(context) sorted_collection = collection_to_sort context return if sorted_collection.empty? sort_attr = @attributes['sort_by'] case_sensitive = @attributes['case_sensitive'] == 'true' i = sorted_collection.first if sort_attr != nil if i.to_liquid[sort_attr].instance_of? String and not case_sensitive sorted_collection.sort_by! { |i| k = i.to_liquid[sort_attr] k ? k.downcase : '' } else sorted_collection.sort_by! { |i| k = i.to_liquid[sort_attr] [k ? 1 : 0,k || 1] } end else if i.instance_of? String and not case_sensitive sorted_collection.sort_by! { |i| i.downcase } else sorted_collection.sort! end end original_name = @collection_name result = nil context.stack do sorted_collection_name = "#{@collection_name}_sorted".sub('.', '_') context[sorted_collection_name] = sorted_collection @collection_name = sorted_collection_name result = super @collection_name = original_name end result end end class SortedForTag < Liquid::For include SortedForImpl def collection_to_sort(context) return context[@collection_name].dup end def end_tag 'endsorted_for' end end class SortedKeysForTag < Liquid::For include SortedForImpl def collection_to_sort(context) return context[@collection_name].keys end def end_tag 'endsorted_keys_for' end end end Liquid::Template.register_tag('sorted_for', Jekyll::SortedForTag) Liquid::Template.register_tag('sorted_keys_for', Jekyll::SortedKeysForTag)
Это и чисто, и элегантно сортировать в Jekyll в GitHub страницы без плагина. Используй свой .файл данных yml в каталоге _data. Я использую здесь файл данных под названием
team-members.yml
:Этот шаблон будет обрабатывать то, что вам нужно сделать здесь.
{% assign sorted_team = site.data.team-members | sort:'title' %} {% for member in sorted_team %} <span class="title">{{ member.title }}</span> {% endfor %}
Я хотел бы добавить следующее для дальнейшего использования.
Для сортировки постов по названию, вы можете использовать
sort
фильтра. См. http://jekyllrb.com/docs/templates/#filtersИтак, это работает:
{% assign sorted_threat_posts = site.categories.threat | sort: 'title', 'last' %} {% for post in sorted_threat_posts %} <li><a href="{{ post.url }}">{{ post.title }}</a></li> {% endfor %}
Это невозможно сделать без плагина или пользовательской функции. Хотя, есть постоянные усилия, чтобы реализовать это в следующих выпусках: https://github.com/Shopify/liquid/pull/101 и тогда это будет выглядеть так:
{% for tag in site.tags order:ascending %} ... {% endfor %}
Смотрите также: закажите массив с шаблоном Jekyll / liquid
Я протестировал отличное решение Кристиана на своем локальном сайте: перед первой строкой есть пустая ссылка (я не знаю, почему) в выводе, поэтому первая ссылка не работает,поэтому я изменил его код, вставив
{% if postitems[1] %}
перед строкой<a href={{ postitems[1] }}">{{ postitems[0] }}</a><br>
и{% endif %}
после. предложилкомментарий Тэнки Ву .