Class: Jekyll::Plugins::PaginateV3::Query::Sorter
- Inherits:
-
Object
- Object
- Jekyll::Plugins::PaginateV3::Query::Sorter
- Defined in:
- lib/jekyll-paginate-v3/query/sorter.rb
Overview
Multi-level sorter for v3 sort definitions.
Example definitions:
sort: date descsort: owner.name, date desc empty:first(delimiter is configurable)sort: ["featured desc", "date desc"]
Used by Pagination::Model to apply deterministic item ordering.
Class Method Summary collapse
-
.apply(items, raw_sort, nested_separator:, equivalents:, split_delimiter: ',') ⇒ Object
Applies parsed sort instructions while preserving input order as a final deterministic tiebreak.
-
.parse(raw_sort, split_delimiter: ',') ⇒ Object
Parses
sortconfig entries into normalised field instructions.
Class Method Details
.apply(items, raw_sort, nested_separator:, equivalents:, split_delimiter: ',') ⇒ Object
Applies parsed sort instructions while preserving input order as a final deterministic tiebreak.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/jekyll-paginate-v3/query/sorter.rb', line 20 def self.apply(items, raw_sort, nested_separator:, equivalents:, split_delimiter: ',') instructions = parse(raw_sort, split_delimiter: split_delimiter) return items if instructions.empty? frontmatter_path = Jekyll::Plugins::PaginateV3::Support::FrontmatterPath.new( separator: nested_separator, arrays: :expand, equivalents: equivalents ) # Keep original index as final tiebreak so ordering remains predictable. indexed_items = items.each_with_index.to_a indexed_items.sort! do |(left_item, left_index), (right_item, right_index)| comparison = compare_items(left_item, right_item, instructions, frontmatter_path) comparison.zero? ? left_index <=> right_index : comparison end indexed_items.map(&:first) end |
.parse(raw_sort, split_delimiter: ',') ⇒ Object
Parses sort config entries into normalised field instructions.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/jekyll-paginate-v3/query/sorter.rb', line 41 def self.parse(raw_sort, split_delimiter: ',') entries = Utils.arrayify(raw_sort, split_delimiter: split_delimiter).map { |entry| entry.to_s.strip }.reject(&:empty?) entries.map do |entry| fragments = entry.split(/\s+/) field = fragments.shift.to_s.strip next nil if field.empty? direction = 'asc' empty = 'last' fragments.each do |fragment| token = fragment.to_s.strip.downcase case token when 'asc', 'ascending' direction = 'asc' when 'desc', 'descending' direction = 'desc' else if token.start_with?('empty:') empty_value = token.split(':', 2).last empty = %w[first last].include?(empty_value) ? empty_value : empty end end end { 'field' => field, 'direction' => direction, 'empty' => empty } end.compact end |