Skip to content

Instantly share code, notes, and snippets.

@parkr
Created October 20, 2017 15:37
Show Gist options
  • Save parkr/a9ee3d3a4eceb74a99bfc4957c52a446 to your computer and use it in GitHub Desktop.
Save parkr/a9ee3d3a4eceb74a99bfc4957c52a446 to your computer and use it in GitHub Desktop.

Revisions

  1. parkr created this gist Oct 20, 2017.
    84 changes: 84 additions & 0 deletions jekyll_6364.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,84 @@
    # This is a possible alternate solution to Jekyll #6364.
    # All of these procs are translations of methods from Jekyll::Filters.
    # Only item_property has been modified.

    require "liquid"

    input = { "government" => ["one post", "two post"], "tech" => ["three post"], "lol" => [1,2,3] }

    as_liquid = -> (item) {
    case item
    when Hash
    pairs = item.map { |k, v| as_liquid.([k, v]) }
    Hash[pairs]
    when Array
    item.map { |i| as_liquid.(i) }
    else
    if item.respond_to?(:to_liquid)
    liquidated = item.to_liquid
    # prevent infinite recursion for simple types (which return `self`)
    if liquidated == item
    item
    else
    as_liquid.(liquidated)
    end
    else
    item
    end
    end
    }

    item_property = -> (item, property) {
    if item.respond_to?(:to_liquid)
    property.to_s.split(".").reduce(item.to_liquid) do |subvalue, attribute|
    p attribute
    liquid = as_liquid.(subvalue)
    liquid.respond_to?(attribute) ? liquid.public_send(attribute) : liquid[attribute]
    end
    elsif item.respond_to?(:data)
    item.data[property.to_s]
    else
    item[property.to_s]
    end
    }

    sort_input = -> (input, property, order) {
    interim = input.map { |item| [item_property.(item, property), item] }
    p interim
    interim.sort! do |apple_info, orange_info|
    apple_property = apple_info.first
    orange_property = orange_info.first

    if !apple_property.nil? && orange_property.nil?
    - order
    elsif apple_property.nil? && !orange_property.nil?
    + order
    else
    apple_property <=> orange_property
    end
    end
    .map!(&:last)
    }

    sort = -> (input, property = nil, nils = "first") {
    if input.nil?
    raise ArgumentError, "Cannot sort a null object."
    end
    if property.nil?
    input.sort
    else
    if nils == "first"
    order = - 1
    elsif nils == "last"
    order = + 1
    else
    raise ArgumentError, "Invalid nils order: " \
    "'#{nils}' is not a valid nils order. It must be 'first' or 'last'."
    end

    sort_input.(input, property, order)
    end
    }

    p input
    p sort.(input, "last.length")