2016-07-10 11 views
2

Ich mache eine Glossarvorlage für eine Jekyll-Site, die auf Github Pages bereitgestellt wird.
Einträge werden aus einer _data/glossary.yml Datei gezogen.
Ich möchte die Vorlage die Einträge alphabetisch anordnen, unabhängig von der Reihenfolge der Daten in glossary.yml.Holen, Bearbeiten und Sortieren von Hash-Objektwerten mit Liquid

Die Verwendung von {% assign glossary = site.data.glossary | sort 'term' %} gibt ein alphabetisch sortiertes Objekt zurück, das ich mit einer for-Schleife durchlaufen kann.
Allerdings ist der sort Filter Groß-und Kleinschreibung - Kleinbuchstaben Einträge werden nach allen Groß-oder Großbuchstaben sortiert.

Liquid 4.0.0 fügt einen sort_natural Filter, der tut was ich will, aber Github Pages läuft derzeit 3.0.6, also brauche ich eine Abhilfe.

Meine Frage ist, wie kann ich:

  1. in einer Flüssig-Vorlage site.data.glossary holen?
  2. manipulieren Sie die String-Werte der ersten Karte jedes Eintrags?
    • (d verwenden, um die capitalize String-Filter, um loszuwerden, der Groß-/Klein Diskrepanzen)
  3. Art die ganze Karte, welche die lokal String gefilterten Werte mit?
  4. Bonus: Wenn ich noch die Source-String-Werte mit ihren ursprünglichen Fall für die endgültige Anzeige in der generierten HTML-Datei beibehalten können.

Zum Beispiel gegeben folgende data/glossary.yml:

- term: apricot 
    loc: plastic 

- term: Apple 
    loc: basket 

- term: Banana 
    loc: basket 

- term: bowtie 
    loc: closet 

- term: Cat 
    loc: outside 

Wie kann ich eine lokale Flüssigkeit Objektvariable erstellen, die sortiert und zeigt das folgende?:

  • Apple-
    • Korb
  • Aprikose
    • Kunststoff
  • Banana
    • Korb
  • Bowtie
    • Schrank
  • Cat
    • außerhalb

Antwort

2

Der einzige Weg ist, ein Filter-Plugin zu verwenden, das wird implementieren Sie Flüssigkeit 4 natural_sort.

Einige Schnitt und Vergangenheit später haben Sie _plugins/natural_sort_filter.rb:

module Jekyll 
    module SortNatural 
    # Sort elements of an array ignoring case if strings 
    # provide optional property with which to sort an array of hashes or drops 
    def sort_natural(input, property = nil) 
     ary = InputIterator.new(input) 

     if property.nil? 
     ary.sort { |a, b| a.casecmp(b) } 
     elsif ary.empty? # The next two cases assume a non-empty array. 
     [] 
     elsif ary.first.respond_to?(:[]) && !ary.first[property].nil? 
     ary.sort { |a, b| a[property].casecmp(b[property]) } 
     end 
    end 

    class InputIterator 
     include Enumerable 

     def initialize(input) 
     @input = if input.is_a?(Array) 
      input.flatten 
     elsif input.is_a?(Hash) 
      [input] 
     elsif input.is_a?(Enumerable) 
      input 
     else 
      Array(input) 
     end 
     end 

     def join(glue) 
     to_a.join(glue) 
     end 

     def concat(args) 
     to_a.concat(args) 
     end 

     def reverse 
     reverse_each.to_a 
     end 

     def uniq(&block) 
     to_a.uniq(&block) 
     end 

     def compact 
     to_a.compact 
     end 

     def empty? 
     @input.each { return false } 
     true 
     end 

     def each 
     @input.each do |e| 
      yield(e.respond_to?(:to_liquid) ? e.to_liquid : e) 
     end 
     end 
    end 
    end 
end 
Liquid::Template.register_filter(Jekyll::SortNatural) 

Dieser neue Filter kann wie folgt verwendet werden:

{% assign glossary = site.data.glossary | sort_natural: 'term' %} 
<ul> 
{% for item in glossary %} 
    <li>{{ item.term }} - {{ item.loc }}</li> 
{% endfor %} 
</ul> 
+0

die Antwort schätzen, aber benutzerdefinierte Plug-Ins nicht arbeite für meinen Anwendungsfall (Bereitstellen und Generieren auf Github Pages). –

+0

Ich bin mir sicher, dass du das nicht mit Flüssigkeit machen kannst. Du wirst auf Flüssigkeit 4 warten müssen ;-) –