Manchmal ist es notwendig Dinge mehr als einmal zu tun. Vielleicht möchte man im HTML eine Anzahl von Sternen ausgeben die einer Bewertung entspricht? Oder man möchte endlich mal verstehen wie auf der Hauptseite die ganzen Blogbeiträge aufgezählt werden? Die Antwort auf all diese Anforderung und fragen lautet “Schleife”.

Die Zählschleife

Der Bereich einer Zählschleife wird eine ganzzahlige Anzahl von Malen wiederholt. Die grundlegende Schreibweise dabei lautet for zähler in (minimum..maximum). Dabei bezeichnet zähler den Namen einer Variable, die im Bereich der Schleife verwendet werden kann. minimum und maximum können wahlweise konkrete Ganzzahlen sein (1, 2, 3, ganz viele) oder mit Werten aus dem Frontmatter gesetzt werden. Wenn Werte aus dem Frontmatter benutzt werden sollen, müssen Sie nicht zwischen geschweiften Klammern stehen. Zur Erinnerung: Anweisungen wie {{ page.bewertung.aktuell }} dienen nur dazu die Werte in den HTML Quelltext zu schreiben, es findet keine weitere Verarbeitung statt.

Wir werden als erstes Beispiel eine einfache Sterne Bewertung implementieren. Dabei gelten die folgenden Eckpunkte:

Quelltext

---
bewertung:
  maximal: 5
  aktuell: 3
---

{% for i in (1..page.bewertung.aktuell) %}
  ☆
{% endfor %}
({{ page.bewertung.aktuell }} von {{ page.bewertung.maximal }})

Ergebnis

☆ ☆ ☆ (3 von 5)

Soweit zu den Basics, jetzt wollen wir einen wesentlichen Aspekt der Anzeige nochmal überdenken: Es sollten immer so viele Sterne angezeigt werden wie theoretisch erreicht werden könnten. Wir müssen also zwischen dem ausgefüllten Stern ★ (★) und dem nicht ausgefüllten Stern ☆ (☆) unterscheiden. Glücklicherweise können wir im Bereich der Schleifen auch komplexe Operationen wie weitere Fallunterscheidungen auftauchen.

Quelltext

---
bewertung:
  maximal: 5
  aktuell: 3
---

{% for i in (1..page.bewertung.aktuell) %}
  {% if i > page.bewertung.maximal %}
    ☆
  {% else %}
    ★
  {% endif %}
{% endfor %}
({{ page.bewertung.aktuell }} von {{ page.bewertung.maximal }})

Ergebnis

★ ★ ★ ☆ ☆ (3 von 5)

Schleifen über Listen

Manchmal möchte man im YAML Frontmatter aber mehr definieren als einfache Zahlen, wir nehmen mal an es sollen Meinungen von Kunden ausgegeben werden. Jede Meinung eines Kunden besteht aus den folgenden Daten:

----
kunde:
  name: Hans
  text: Das Produkt ist toll.
  bewertung:
    maximal: 5
    aktuell: 1
---

Wie man diese Daten für nur einen Kunden ausgeben würde ist für euch vermutlich kein Problem mehr, es stellt sich jedoch die Frage wie wir mehrere Meinungen statt nur einer Meinung ausgeben könnte. Hierfür können wir Listen aus YAML verwenden: Statt nur einer Meinung wollen wir dem Schlüssel meinungen eine ganze Liste von Meinungen verpassen. Dafür schreiben wir einen Bindestrich vor jedes Element, dass in der Liste enthalten sein soll.

----
meinungen:
- kunde:
    name: Hans
    text: Das Produkt ist toll.
    bewertung:
      maximal: 5
      aktuell: 1
- kunde:
    name: Franz
    text: Das Produkt ist eher nicht so toll.
    bewertung:
      maximal: 5
      aktuell: 5
---

Dankenswerterweise können wir dem komplizierter gewordenen YAML Frontmatter nun eine im Gegensatz zur Zählschleife leicht vereinfachte Struktur entgegensetzen: for elementName in liste. Die sonstigen Änderungen am Quelltext bleiben dann erfreulich überschaubar: Im Bereich der Schleife muss die Kategorie page einfach durch den gewählten elementName ersetzt werden. Damit greifen wir innerhalb der Schleife nacheinander auf alle Elemente der Liste zu.

Quelltext

{% for kunde in page.meinungen %}
  <div>
  {% for i in (1..kunde.bewertung.maximal) %}
    {% if i > kunde.bewertung.aktuell %}
      &#9734;
    {% else %}
      &#9733;
    {% endif %}
  {% endfor %}
  ({{ kunde.bewertung.aktuell }} von {{ kunde.bewertung.maximal }})
  </div>
{% endfor %}

Ergebnis

★ ☆ ☆ ☆ ☆ (1 von 5)
★ ★ ★ ★ ★ (5 von 5)

Aufgabe: Sehen ist gut, Selber machen ist besser
  • Legt einen neuen Beitrag an und testet den hier vorgestellten Code selber.
  • Erweitert die Ausgabe der Meinungen um den Namen des Kunden und den hinterlegten Text.
  • Es ist eigentlich ziemlicher Quatsch, dass die maximale Bewertung erneut mit jeder aktuellen Bewertung angegeben werden muss. Erstellt einen globalen Schlüssel bewertung.maximal (in der _config.yml) und verwendet diesen Wert anstatt den Wert für jede Bewertung im Frontmatter wiederholen zu müssen.
  • Bonusaufgabe für CSS-Erfahrene: Verpasst der Leiste mit den Sternen einen farbigen Hintergrund und verwendet nur den ausgefüllten Stern als HTML Entity. Färbt die Sterne allerdings in gelb oder grau ein um zu verdeutlichen ob die Bewertung vergeben worden ist oder nicht.
  • Bonusaufgabe: Verwendet statt der HTML Entities für die Sterne einfach Bilder von Sternen.