Skip to content

Timber Custom Post Type Templates

Mark Howells-Mead edited this page Oct 9, 2019 · 1 revision

Ein sehr hilfreiche Erklärung von Lukas Gächter.


Wie so oft hast du bei Timber auch in diesem Fall mehrere Möglichkeiten. Die nahliegendste ist es wohl, auch mit Actions zu arbeiten. Das wäre dann aber wirklich kein Vorteil von Timber gegenüber normalen Templates.

Eine einfache Möglichkeit bei kleinen Abweichungen wäre, eine Context-Variable für Posts zu setzen, die du dann im Template abfragst.

single.php

$context = Timber::get_context();

$post = new Timber\Post();
$context['post'] = $post;

if ( 'other' === $post->post_type ) {
  $context['related'] = new PostQuery( array(
    // Your args
  ) );
}

Timber::render(
  array( 'single-' . $post->post_type . '.twig', 'single.twig' ),
  $context
);

single.twig

{% extends 'base.twig' %}

{% block content %}
  {% include 'post/header.twig' %}
  {% include 'post/content.twig' %}
  
  {% if related %}
    {% include related %}
  {% endif %}
{% endblock %}

Du könntest auch z.B. der render()-Funktion eine Auswahl an Twig-Files mitgeben.

single.php

$context = Timber::get_context();

$post = new Timber\Post();
$context['post'] = $post;

Timber::render(
  array( 'single-' . $post->post_type . '.twig', 'single.twig' ),
  $context
);

Nun gibt kannst du beliebig Templates erstellen, die vom Standard-Template für Posts in single.twig abweichen. Timber sucht erst nach einem Twig-File, das den Post Type im Namen enthält und nutzt als Fallback single.twig, falls er kein File findet.

single-other.twig

{% extends 'base.twig' %}

{% block content %}
  <div>
    My custom block that would normally be added
    through a sht_before_content hook.
  </div>

  {% include 'post/header.twig' %}
  {% include 'post/content.twig' %}

  <div>
    My custom block that would normally be added
    through a sht_after_content hook.
  </div>
{% endblock %}

Wir erstellen separate Twig-Files für Blöcke, die sich wiederholen. Im Beispiel könnte man theoretisch auch post/header.twig und post/content.twig in ein File packen, damit man nur einen Include hat.

Der main-Block (zum Beispiel ein <article>-Element) ist bei uns bereits im base.twig drin. Das liesse sich aber auch über ein Embed lösen.

Eine weitere Möglichkeit, wäre innerhalb von Twig dynamische Templates zu nutzen:

<article class="page-section page-section--content" id="content" role="main">
  {% include 'partials/post-' ~ post.post_type ~ '-before.twig' ignore missing %}
  
  {% include 'post/header.twig' %}
  {% include 'post/content.twig' %}

  {% include 'partials/post-' ~ post.post_type ~ '-after.twig' ignore missing %}
</article>

Du kannst dann, solltest du Zusatzinhalte benötigen, einzelne Twig-Files hinzufügen, z.B. partials/post-other-after.twig. Durch ignore missing kannst du die Fehlermeldung verhindern, wenn ein Template nicht gefunden wird.

Natürlich ist dann wieder die Frage, wie du Post-Type-spezifische Funktionalitäten in den partiellen Includes ausführst. Du willst ja sicher nicht wieder PHP-Funktionen in Twig schreiben. Hier arbeiten wir oft mit eigenen Post-Klassen, die Timber\Post extenden, damit man einfach darauf zugreifen kann. Beispielsweise hier mit einer get_related()-Funktion, die im Twig-File dann über post.related abgerufen werden kann.

single-other.php

$context = Timber::get_context();
$context['post'] = $new Post_Other();
  
Timber::render( 'single-other.twig' $context );

Post_Other.php

class Post_Other extends Timber\Post {
  public function get_related() {
    // Pull in some related posts
    return $related;
  }
}
partials/post-other-before.twig
{% for related in post.get_related %}
  {% include 'partials/related.twig' %}
{% endfor %}

Es lässt sich natürlich darüber streiten, ob man nun mehrere single.php-Files für verschiedene Post-Types haben will. Eigentlich kann man das auch in ein File reinpacken. Persönlich finde ich es manchmal angenehmer, wenn ich gleich anhand der Dateistruktur sehe, welche Custom Post Types eine eigene Logik beinhalten. Wie du selber sagst, vielleicht macht das nur Sinn wenn es komplexer wird.

Clone this wiki locally