Podlove-Templates mit Twig (5): Episodenarchiv

Viele Podcasterinnen legen Wert darauf, ihre Episoden noch einmal gesammelt auf einer Seite als übersichtliche Liste anzuzeigen. Die Podlove-Entwickler haben dafür einen Shortcode bereitgestellt, den Du mit [podlove-episode-list] aufrufen und in eine Seite einfügen kannst. Das Ergebnis ist eher so naja was die Optik angeht: Eine Tabelle in der zwingend das Episodencover angezeigt wird und die insgesamt nicht besonders hübsch aussieht. Das wollen wir heute anders machen und legen ein neues Template an mit dem hochkreativen Namen „Archiv“.

Ich persönlich mag es, zunächst ein paar einleitende Worte zu lesen. Wenn Du einen feststehenden Text einbauen möchtest, muss der nicht hier eingetragen werden. Ich beginne in der Regel mit

 <p>{{ podcast.summary }}</p> 

Damit wird der Text eingefügt, den Du in den Podcasteinstellungen für Deinen Podcast als Beschreibung festgelegt hast. Praktisch: Sobald Du dort eine Änderung vornimmst, taucht die automatisch auch hier auf. Deswegen sind Templates so geil: Du musst jede Änderung nur einmal vornehmen und sie findet sich überall wieder.

Eine kleine Spielerei, die ich bei den Produktionen mit meiner Beteiligung gern einbaue, sind die Downloadzahlen der einzelnen Episoden. Viele Podcasterinnen gehen damit ähnlich konservativ um, wie Deutsche mit ihrem Gehalt: Da spricht man nicht drüber. Ich sehe persönlich keinen Grund die Zahlen nicht zu veröffentlichen, wenn Du das nicht nutzen möchtest, lass den entsprechenden Code einfach weg. Wir beginnen mit einem Durchschnittswert über alle Episoden und dazu brauchen wir erstmal eine Variable:

{% set Downloadsumme = 0 %} 

Die Downloadsumme soll zunächst den Wert Null haben. Für jede Episode des Podcasts soll zu dem Wert nun die Zahl der Downloads addiert werden. Das erledigt die for-Schleife für uns, die die folgende Anweisung für jede Episode neu ausführt:

{% for episode in podcast.episodes %}
    {% set Downloadsumme = Downloadsumme + episode.total_downloads %} 
{% endfor %}

Am Ende der Operation enthält die Variable Downloadsumme also eine Zahl, die aus den addierten Werten aller episode.total_downloads unseres Podcasts besteht. Und damit können wir nun einen Durchschnitt berechnen:

{% set Durchschnitt = Downloadsumme / podcast.episodes|length  %}
 
<p style="margin-bottom:30px">Der {{ podcast.title }} besteht aus {{  podcast.episodes|length }} Episoden. Jede davon wurde im Durchschnitt {{ Durchschnitt|round }} mal heruntergeladen.</p>

Wir machen uns hier zwei Filter zu Nutze, nämlich zum einen |length, der die Anzahl der Elemente eines Arrays zurückgibt, und |round, der mathematisch auf- oder abrundet sodass keine Kommastellen übrig bleiben. Eine vollständige Liste aller Filter, die twig bietet, findest Du in der Dokumentation. Jetzt aber zur eigentlichen Episodenliste: Um die zu strukturieren, nutze ich gern das HTML-Element <ul> für „unordered list“. Wobei ich aber die Listenelemente nicht anzeigen lasse:

 <ul style="list-style-type:none"> 

Dann brauchen wir wieder eine for-Schleife:

{% for episode in podcast.episodes %}

Und jedes Element muss nun auch als HTML-Listenelement ausgewiesen werden, sprich in <li> ... </li> eingeschlossen sein. Wir eröffnen also ein neues Listenelement und legen fest, dass danach ein Leerraum von 20 Pixeln eingefügt werden soll (margin-bottom:20px). Danach folgt die Anweisung, dass alles innerhalb von <span> und </span> fett und auf 1,5-facher Größe dargestellt werden soll.

<li style="margin-bottom:20px"><span style="font-weight:bold;font-size:1.5em"> <a href="{{ episode.url }}">{{ episode.post.post_title }}</a></span><br />

Zwischen den beiden Tags finden wir also einen Link zum post_title der Episode. Wir greifen mit dieser Variable auf das WordPress-Objekt WP_Post zu und geben im Prinzip das aus, was Du beim Erstellen Deiner Episode ganz oben als Titel des Blogposts einträgst, in diesem Beispiel „JSFP244: Wie lang ist ein Podcast?“:

Wir nutzen an dieser Stelle episode.post.post_title, weil uns episode.title an dieser Stelle nicht wirklich weiterbringt. Der ist für diese Episode nämlich nur „Wie lang ist ein Podcast?“, weil Apple in seinem ehemals itunes genannten Verzeichnis die Podcastkürzel und Episodennummern nicht mehr haben will. In den Titel des begleitenden Blogposts können wir aber zum Glück eintragen was wir wollen und so können wir ohne viel Heckmeck den Episodentitel und den Slug der Episode zusammen ausgeben.

Nachtrag vom 09.09.2020: Mit der Version 3.0 des Podlove Publishers wurde dieser Aufruf geändert: Wenn Du auf Version 3.0 oder höher unterwegs bist, solltest Du statt episode.post.post_title lieber episode.post_title verwenden. Das Ergebnis bleibt gleich.

In einer neuen Zeile geht es weiter:

<span>{{ episode.subtitle }}</span> <br /> 

Die <span>-Tags brauchst Du an der Stelle nur, wenn Du dem Untertitel noch ein Format zuweisen möchtest, das ginge an der Stellen mit style="...". episode.subtitle ist die Kurzzusammenfassung der Episode mit maximal 255 Zeichen und sie soll kursiv angezeigt werden. In einer neuen Zeile füge ich einige Icons ein, die ich bei iconfinder.com gefunden und auf meinem Webspace gespeichert habe. Es gibt jeweils Bilder für die Dauer (episode.duration), das Erscheinungsdatum (episode.publicationdate.format('d.m.Y')) und die Zahl der Downloads (episode.total_downloads | number_format(0, ',', '.')).

<small><span style="margin-right:20px"><img src="http://icons.joernschaar.de/dauer.png" alt="Die Dauer der Episode" title="Die Dauer der Episode" width="20px"> {{ episode.duration }}</span><span style="margin-right:20px"><img src="http://icons.joernschaar.de/kalender.png" alt="Diese Episode erschien am" title="Diese Episode erschien am" width="20px"> {{ episode.publicationdate.format('d.m.Y') }}</span><span style="margin-right:20px" ><img src="http://icons.joernschaar.de/downloads.png" alt="Downloads seit Veröffentlichung" title="Downloads seit Veröffentlichung" width="20px"> {{ episode.total_downloads | number_format(0, ',', '.') }} Downloads</span> </small>      <br />

Wenn Du ('d.m.Y') an das Datum anhängst, wird es nach PHP-Vorgaben formatiert. Wenn Du diese Formatangabe weglässt, nutzt WordPress die Einstellungen, die generell für Datumsangaben gelten.

Die Angabe number_format(0, ',', '.') legt fest, wie die Zahl der Downloads ausgegeben werden soll. Die 0 steht hier für die Zahl der Nachkommastellen, ',' gibt an, wie die Nachkommstellen von der restlichen Zahl getrennt werden und '.' definiert das Trennzeichen für Tausenderschritte.

Bei der Dauer kannst Du natürlich noch ein bisschen eskalieren und von der eher mathematischen Angabe 1:06:37 hin zu etwas mehr Semantischem wie „1 Stunde 6 Minuten und 37 Sekunden“ arbeiten. Wie das geht, habe ich in Lektion 2 ausführlich erklärt, das Ergebnis sieht dann so aus:

Beim Haialarm möchte ich zusätzlich noch die Moderatoren sowie Unterstützer und die Studios benennen, ohne die der Podcast nicht zu realisieren wäre. In einer neuen Zeile beginnen wir wieder mit einer for-Schleife, die uns alle Mitwirkenden aus der Gruppe „Macher“ auflistet und sie aufsteigend nach Name sortiert:

<b>Moderation:</b> 
{% for contributor in episode.contributors({group:"macher",order: "ASC", orderby: "name"}) %}

Wenn der Mitwirkende in den Contributor-Einstellungen als sichtbar markiert wurde, soll nun sein Name angezeigt werden. Ist er der letzte in der Reihe folgt ein Punkt, andernfalls ein Komma:

  {% if contributor.visible %}
     <span class="name">{{ contributor.name }}</span>
       {% if not loop.last %},
       {% else %}.
       {% endif %}
  {% endif %} 
{% endfor %} 

Das Ganze wiederholen wir für die Unterstützer und die Studios. Wenn in der Gruppe „Unterstützer“ bzw. „Studios“ für diese Episode mehr als 0 Entitäten eingetragen sind, läuft wieder unsere for-Schleife los und funktioniert im Prinzip wie oben auch. Einziger Unterschied: Hier wird auch noch einmal der Kommentar zur Beteiligung an der Episode ausgegeben, damit klar wird, wofür wir uns an der Stelle bedanken:

{% if episode.contributors({group:"unterstuetzer"})|length > 0 %}     <strong>Danke an:</strong> 
  {% for contributor in episode.contributors({group:"unterstuetzer",order: "ASC", orderby: "name"}) %}     
    {% if contributor.visible %}
     <span class="name">{{ contributor.name }} für {{ contributor.comment }}</span>
      {% if not loop.last %},
      {% else %}. 
      {% endif %}
    {% endif %}
  {% endfor %}
{% endif %}     
{% if episode.contributors({group:"studios"})|length > 0 %}
 Sowie  
  {% for contributor in episode.contributors({group:"studios"}) %}    
    {% if contributor.visible %}  
      <span class="name">{{ contributor.name }} ({{ contributor.comment }})</span>   
      {% if not loop.last %}, 
      {% else %}. 
      {% endif %}
    {% endif %}  
  {% endfor %}    
{% endif %}</li>
{% endfor %}</ul>   

Um in contributor.comment einen Wert zu haben, muss ich in jeder Episode für jede MItwirkende dort auch etwas eintragen:

Das Ergebnis im Episodenarchiv sieht dann so aus:

Hier noch einmal der gesamte Code:

{% set Downloadsumme = 0 %}
{% for episode in podcast.episodes %}
  {% set Downloadsumme = Downloadsumme + episode.total_downloads %}
{% endfor %}

{% set Durchschnitt = Downloadsumme /  podcast.episodes|length  %} 

<p style="margin-bottom:30px">Der {{ podcast.title }} besteht aus {{  podcast.episodes|length  }} Episoden. Jede davon wurde im Durchschnitt {{ Durchschnitt|round }} mal heruntergeladen.</p>

<ul style="list-style-type:none"> 
{% for episode in podcast.episodes %}
 <li style="margin-bottom:20px"><span style="font-weight:bold;font-size:1.5em"><a href="{{ episode.url }}">{{ episode.post.post_title }}</a></span><br /><span>{{ episode.subtitle }}</span><br /><small><span class="podlove-duration" style="margin-right:20px"><img src="http://icons.joernschaar.de/dauer.png" alt="Die Dauer der Episode" title="Die Dauer der Episode" width="20px"> {{ episode.duration }}</span><span class="podlove-duration" style="margin-right:20px"><img src="http://icons.joernschaar.de/kalender.png" alt="Diese Episode erschien am" title="Diese Episode erschien am" width="20px"> {{ episode.publicationdate.format('d.m.Y') }}</span><span class="podlove-duration"><img src="http://icons.joernschaar.de/downloads.png" alt="Downloads seit Veröffentlichung" title="Downloads seit Veröffentlichung" width="20px"> {{ episode.total_downloads | number_format(0, ',', '.') }} Downloads</span> </small>
<br /><b>Moderation:</b>
 {% for contributor in episode.contributors({group:"macher",order: "ASC", orderby: "name"}) %} 
  {% if contributor.visible %}
 <span class="name">{{ contributor.name }}</span></span>{% if not loop.last %}, {% else %}. {% endif %}
 {% endif %}
 {% endfor %}
 {% if episode.contributors({group:"unterstuetzer"})|length > 0 %}
     <strong>Danke an:</strong> 
     {% for contributor in episode.contributors({group:"unterstuetzer",order: "ASC", orderby: "name"}) %}
     {% if contributor.visible %}
     <span class="name">{{ contributor.name }} für {{ contributor.comment }}</span></span>{% if not loop.last %}, {% else %}. {% endif %}
     {% endif %} 
     {% endfor %}
    {% endif %}
     {% if episode.contributors({group:"studios"})|length > 0 %}
     Sowie  
     {% for contributor in episode.contributors({group:"studios"}) %}
     {% if contributor.visible %}
     <span class="name">{{ contributor.name }} ({{ contributor.comment }})</span></span>{% if not loop.last %}, {% else %}. {% endif %}
     {% endif %} 
     {% endfor %}
    {% endif %}</li>
    {% endfor %}
</ul> 

Wenn Du Deinen Podcast in verschiedene Staffeln aufteilst, wird es nur wenig kniffliger. Bei What’s in your pants? lösen wir das mit einer vorgeschalteten for-Schleife:

{% for season in podcast.seasons %}

Da jede Staffel einen eigenen Titel, Untertitel und eine eigene Beschreibung hat, zeigen wir auch diese der staunenden Weltöffentlichkeit:

<h2 id="{{ season.number }}">{{ season.title }} - {{ season.subtitle }}</h2>
<p>{{ season.summary }}</p>
<p>Die Staffel ist am {{ season.startDate.format('d.m.Y') }} gestartet{% if season.running %} und sie läuft gerade{% endif %}. Die erste Episode hieß "{{ season.firstEpisode.title }}" und wir haben sie am {{ season.firstEpisode.recordingDate.format('d.m.Y') }} aufgenommen. Staffel {{ season.number }} hat{% if season.running %} bisher{% endif %} {{ season.episodes|length }} Episoden.</p>
<h3>Episodenliste:</h3>  

Außerdem können wir hier noch Angaben zum Startdatum der Staffel season.startDate.format('d.m.Y') machen und einen Hinweis darauf geben, dass gerade die aktuelle Staffel angezeigt wird, indem wir eine kurze if-Abfrage in den Absatz einfügen: ({% if season.running %} und sie läuft gerade{% endif %}) wir benennen die erste Episode und deren Aufnahmedatum und wir geben einen Hinweis auf die Zahl der Episoden in dieser Staffel. Das Ergebnis kannst Du Dir im WIYP-Episodenarchiv ansehen.

Jetzt musst Du Dein Archiv nur noch sichtbar machen. Dazu legst Du in WordPress eine neue Seite an, die meinetwegen „Episodenarchiv“ heißen könnte. Und dort fügst Du gegebenenfalls einleitende Worte und den Template-Aufruf ein:

 [podlove-template template="Archiv"] 

Wobei „Archiv“ der Titel Deines Templates sein muss. Wenn Du das Ding eingangs „Würxenglönk“ genannt hast, solltest Du diesen Titel einsetzen.

Alle Lektionen in dieser Reihe:

6 Kommentare

  1. Hallo Jörn,

    vielen Dank für Deine Anleitungen und den Beispielcode.
    Ich habe versucht das beim Bildungstaxi nachzubauen, aber ich bekomme den letzten Schritt mit den Staffeln nicht umgesetzt und finde den Fehler nicht.
    Vielleicht kannst Du mir einen Tipp geben wo der Fehler liegt!?

    HG Ralf

    Hier der Code:

    {% set Downloadsumme = 0 %}
    {% for episode in podcast.episodes %}
    {% set Downloadsumme = Downloadsumme + episode.total_downloads %}
    {% endfor %}

    {% set Durchschnitt = Downloadsumme / podcast.episodes|length %}

    Der {{ podcast.title }} besteht aus {{ podcast.episodes|length }} Episoden.

    {% for season in podcast.seasons %}

    {{ season.title }} - {{ season.subtitle }}
    {{ season.summary }}
    Die Staffel ist am {{ season.startDate.format('d.m.Y') }} gestartet{% if season.running %} und sie läuft gerade{% endif %}. Die erste Episode hieß "{{ season.firstEpisode.title }}" und wir haben sie am {{ season.firstEpisode.recordingDate.format('d.m.Y') }} aufgenommen. Staffel {{ season.number }} hat{% if season.running %} bisher{% endif %} {{ season.episodes|length }} Episoden.
    Episodenliste:

    {% for episode in podcast.episodes %}
    {{ episode.post.post_title }}{{ episode.subtitle }}Dauer {{ episode.duration }}Erschienen am: {{ episode.publicationdate.format('d.m.Y') }}
    Moderation:
    {% for contributor in episode.contributors({group:"macher",order: "ASC", orderby: "name"}) %}
    {% if contributor.visible %}
    {{ contributor.name }}{% if not loop.last %}, {% else %}. {% endif %}
    {% endif %}
    {% endfor %}
    {% if episode.contributors({group:"unterstuetzer"})|length > 0 %}
    Danke an:
    {% for contributor in episode.contributors({group:"unterstuetzer",order: "ASC", orderby: "name"}) %}
    {% if contributor.visible %}
    {{ contributor.name }} für {{ contributor.comment }}{% if not loop.last %}, {% else %}. {% endif %}
    {% endif %}
    {% endfor %}
    {% endif %}
    {% if episode.contributors({group:"studios"})|length > 0 %}
    Sowie
    {% for contributor in episode.contributors({group:"studios"}) %}
    {% if contributor.visible %}
    {{ contributor.name }} ({{ contributor.comment }}){% if not loop.last %}, {% else %}. {% endif %}
    {% endif %}
    {% endfor %}
    {% endif %}
    {% endfor %}

    1. Moin.

      Schön, dass Dir meine kleine Serie gefällt und dass sie Dir offenbar schon weitergeholfen hat. Das ist super! Auf den ersten Blick kann ich keine Fehler im Code entdecken. Es muss also an etwas anderem liegen. Oben fragst Du ja auch die Staffeln ab. Hast Du beim Bildungstaxi denn auch Staffeln definiert? Möglicherweise soll das Template an dieser Stelle etwas abfragen, das es gar nicht finden kann und setzt dann aus. Ein ähnliches „Problem“ hast Du unten bei den verschiedenen Gruppen der Contributors: Wenn Dein Podcast keine Contributor-Gruppe „studios“ kennt, wird das Template dort nichts anzeigen. Hier gibt es aber zum Glück den Workaround der if-Abfrage: Wenn es keine Contributors in der Gruppe gibt, wird die Abfrage gar nicht weiter bearbeitet. Ebenso muss natülich die Gruppe „macher“ mit Deinen Einstellungen im Blog übereinstimmen.

      Zwei Anmerkungen noch: Den Link zur Episode mit „nofollow ugc“ zu kennzeichnen, ist verwirrend für mich. Denn damit sagst Du Google & Co. im Prinzip „Guck Dir den Link mal besser nicht weiter an, das ist User Generated Content und wenn das Spam ist, will ich damit nichts zu tun haben.“ Außerdem: Ganz oben, bildest Du den Durchschnitt aller Downloads, fragst die aber nirgendwo ab. Dieser Teil des Templates könnte also verschwinden.

  2. Zwei Anmerkungen noch: Den Link zur Episode mit „nofollow ugc“ zu kennzeichnen, ist verwirrend für mich. Denn damit sagst Du Google & Co. im Prinzip „Guck Dir den Link mal besser nicht weiter an, das ist User Generated Content und wenn das Spam ist, will ich damit nichts zu tun haben.“
    Ja, ähh, aber das habe ich auch nicht drin, oder übersehe ich was?

    1. Ah, ich sehe es gerade: WordPress hat einen Link in Deinem Code-Beispiel tatsächlich zu einem Link umgewandelt und den dann entsprechend markiert. Sorry für die Verwirrung.

  3. Ich habe zwei Staffeln definiert. Die hat er an anderer stelle auch schon mal ausgegeben, aber eben nicht im Archiv.
    Würdest Du noch einmal den gesamten Code für das Archiv-Template von WIP posten, also mit Season-Abfrage?

Kommentar hinterlassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert