Podlove Publisher Templates mit Twig (11): Contributoren noch schicker anzeigen mit FlexBoxen

Wie wichtig eine gute Darstellung der Mitwirkenden in Podcasts sind, habe ich hier schon ein bis zwei Mal erwähnt. Und auch wie man die Default-Ansicht, die Podlove bietet, aufhübschen kann, war hier schon Thema. Damals schrieb ich aber auch: „Ich bin mit meinen Twig-Fähigkeiten selbst noch nicht so weit, dass ich die Funktion dieses Shortcodes nachbauen könnte“ und heute ist es so weit, wir bauen nicht nur die Funktion eines Shortcodes nach, wir geben direkt Vollgas und machen das Ding besser. (Tim Taylor „Mehr Power“-Grunzen hier einfügen!)

Der Schlüssel dazu heißt „Flexbox“ oder „Flexdesign“. Das ist eine Anzeigemethode mit CSS-Styles und tatsächlich etwas, in das man sich ein wenig hineinfuchsen muss. Aber wir gucken uns das alles Schritt für Schritt an, das wird ganz einfach. Das Schöne daran: Wenn Du die Nummer einmal verstanden hast, kannst Du das Prinzip auch auf viele andere Arten anwenden und Dein Episodenarchiv oder Deine Startseite viel spannender gestalten. Los geht’s!

Was Flex genau ist und wie Du damit Elemente ausrichten kannst, wird in einem Artikel auf mediaevent.de sehr gut und ausführlich erklärt, diesen Teil spare ich hier mal aus und erkläre nur meinen Twig-Code. Der besteht aus dem Nektar, den ich aus diesem Artikel saugen konnte. Am Beispiel des Haialarm-Podcasts siehst Du, wie ich seit einiger Zeit die Mitwirkenden meiner Podcastproduktionen darstelle:

Dafür habe ich ein Subtemplate namens „Contributoren“ angelegt, das ich am Ende der Shownotes einbinde. Ich rate sehr dazu, das zu machen, denn wir haben es hier mit einer Menge Code zu tun, der schnell unübersichtlich wird. Weil diese Darstellung in den allermeisten Podcastapps so gar nicht funktioniert, beginnen wir mit einer if-Abfrage:

{% if not is_feed() %}
    <h3>Moderation:</h3>
    <div class="container">

Wenn wir uns nicht im Feed befinden, wird also zunächst eine Überschrift eingefügt und dann eine div-Box eröffnet, die die CSS-Klasse „container“ hat. Die CSS-Styles findest Du der Übersicht halber nachher am Ende dieses Artikels. Was diese Klasse macht, ist eine Art Rahmen aufzuspannen, in dem wir nun weitere Elemente platzieren können. Und das geht so:

{% for contributor in episode.contributors({group: 'cast', groupby: 'role'}) %}
  <div class="mod">
    <div class="item">
      {{ contributor.image.html({height: 100, alt: contributor.name, title:
      contributor.name}) }}
    </div>

Für jede Mitwirkende wird also eine neue div-Box angelegt, die die CSS-Klasse „mod“ hat und – so viel kann ich vorweg nehmen – weitere div-Boxen der Klasse „item“ beinhaltet. Wir können uns das also ungefähr so vorstellen:

Das Bild zeigt mehrere ineinander verschachtelte Blöcke, die von außen nach innen mit "container", "mod" und "item" beschriftet sind.
Meine Grafikskills sind ungefähr so gut, wie meine handwerklichen Fähigkeiten: Alles schief und krumm.

Innerhalb des Containers haben wir also eine beliebig große Anzahl von Boxen der Klasse „mod“, die wir hier waagerecht nebeneinander anordnen. Innerhalb von „mod“ stehen senkrecht untereinander Boxen der Klasse „item“. Die erste haben wir im Code-Schnipsel schon kennengelernt: Dort wird das Profilbild der Contributorin angezeigt. Als nächstes fügen wir nun den Namen ein:

<div class="item" style="font-weight:bold">
  {{ contributor.name }}
</div>

Und dann folgen die Icons der Social- und Spendendienste:

<div class="item">
  {% for service in contributor.services({category: "social"}) %}
    <a target="_blank" title="{{ service.title }}" href="{{ service.profileUrl }}"
    style="color:white">{{ service.image.html({width: 20, heigth: 20, alt: 
    service.name}) }}</a>
  {% endfor %}
  {% for service in contributor.services({category: "donation"}) %}
    <a target="_blank" title="{{ service.title }}" href="{{ service.profileUrl }}" 
    style="color:white">{{ service.image.html({width: 20, heigth: 20, alt: 
    service.name}) }}</a>
  {% endfor %}               
</div>

Damit auch unsere Freunde in den angeschlossenen Apps und Podcastverzeichnissen wissen, wer in dieser Episode dabei war, folgt noch eine weitere If-Abfrage:

{% if is_feed() %}
    <p>Durch die Episode führen {% for contributor in episode.contributors({role:
    'host'}) %}{{ contributor.name }}{% if not loop.last %}, {% endif %}{% endfor 
    %}{% if episode.contributors({role: 'guest'})|length > 0 %} sowie {% for 
    contributor in episode.contributors({role: 'guest'}) %}{{ contributor.name }}{% 
    if not loop.last %}, {% else %}.{% endif %}{% endfor %}{% else %}. {% endif %} 
    Für ihre Unterstützung möchten wir uns außerdem bei {% for contributor in 
    podcast.contributors({scope: "podcast"}) %}{{ contributor.name }}{% if not 
    loop.last %} und {% endif %}{% endfor %} bedanken.</p>
{% endif %}

Für eine Archiv- oder Startseite wäre nun natürlich denkbar, dieses Prinzip ebenfalls anzuwenden: Du könntest das jeweilige Episodencover anzeigen, darunter in 20×20 Pixeln die Fotos der Mitwirkenden und gegebenenfalls darunter noch den Titel der Episode. Die Möglichkeiten sind einigermaßen endlos, Deiner gestalterischen Fantasie sind kaum Grenzen gesetzt. 🙂 Wie immer hier noch der Code zum kopieren, beachte bitte, dass ich zur besseren Lesbarkeit Absätze und Leerzeichen eingefügt habe, wo im echten Leben keine wären.

{% if not is_feed() %}
  <h3>Moderation:</h3>
  <div class="container">
    {% for contributor in episode.contributors({group: 'cast', groupby: 'role'}) %}
      <div class="mod">
         <div class="item">
           {{ contributor.image.html({height: 100, alt: contributor.name, title: 
           contributor.name}) }}
         </div>
         <div class="item" style="font-weight:bold">
           {{ contributor.name }}
         </div>
         <div class="item">
           {% for service in contributor.services({category: "social"}) %}
             <a target="_blank" title="{{ service.title }}" href="{{ 
             service.profileUrl }}" style="color:white">{{ service.image.html({width: 
             20, heigth: 20, alt: service.name}) }}</a>
           {% endfor %}
           {% for service in contributor.services({category: "donation"}) %}
             <a target="_blank" title="{{ service.title }}" href="{{ 
             service.profileUrl }}" style="color:white">{{ service.image.html({width: 
             20, heigth: 20, alt: service.name}) }}</a>
           {% endfor %}                
         </div>
       </div>
     {% endfor %}
    </div>
{% endif %}

{% if is_feed() %}
    <p>Durch die Episode führen {% for contributor in episode.contributors({role: 
    'host'}) %}{{ contributor.name }}{% if not loop.last %}, {% endif %}{% endfor 
    %}{% if episode.contributors({role: 'guest'})|length > 0 %} sowie {% for 
    contributor in episode.contributors({role: 'guest'}) %}{{ contributor.name }}{% 
    if not loop.last %}, {% else %}.{% endif %}{% endfor %}{% else %}. {% endif %} 
    Für ihre Unterstützung möchten wir uns außerdem bei {% for contributor in 
    podcast.contributors({scope: "podcast"}) %}{{ contributor.name }}{% if not 
    loop.last %} und {% endif %}{% endfor %} bedanken.</p>
{% endif %}

<style>
   .container {
       display: flex;
       justify-content: flex-start;
       align-items: flex-start;
       gap: 1em 2em;
       flex-flow: row wrap;
   }
   .mod {
       display: flex;
       justify-content: flex-start;
       align-items: center;
       flex-flow: column wrap;
   }
   .item {
       display: flex;
       justify-content: center;
       align-items: center;
       gap: 3px;
       flex-flow: row wrap;
   }
</style>

Kommentar hinterlassen

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