Es gibt unterschiedliche Wege, wie man das Archiv eines selbst definierten Inhaltstyps in WordPress auf den Screen bringt. Je nach Anwendungsfall mag es gute Gründe geben, dafür ein Seiten-Template vorzusehen, und ein Custom Query zu schreiben (oder ihn in eine Funktion packen, um ggf. in einem Shortcode wiederzugeben).
Post Type Archiv
Eigentlich benötigt es kein Template, um ein Post Type Archiv anzuzeigen. Allerdings werden dann (je nach Verfügbarkeitarchive.php
oder index.php
) nur die Standardelemente angezeigt, in der Anordnung wie sie auch für Beiträge gilt.
Der native und einfachste Weg ist ein Post Type Archiv. Gibt es eigene Felder oder sonstige spezielle Elemente, die der Inhaltstyp wiedergeben soll, wird dies im Inhaltstemplate festgelegt (z.B. template-parts/post/content-news.php
), unabhängig davon, ob das Archiv nativ ist, in einem Template definiert wird, oder einer Funktion.
Die index.php
ist eine gute Vorlage für das Post Type Archiv. Für den Inhaltstypen news
eine Kopie als archive-news.php
speichern und ggf. auch den Page-Header modifizieren.
Beispiel-Modifikation archive-news.php
<?php
/**
*
* archive for post type "news"
*
*/
get_header(); ?>
<div class="wrap">
<header class="page-header">
<h2 class="page-title"><?php _e( 'News (Archive) main-query', 'twentyseventeen' ); ?></h2>
</header>
<div id="primary" class="content-area">
<main id="main" class="site-main" role="main">
<?php
if ( have_posts() ) :
while ( have_posts() ) : the_post();
/* unter template-parts post muss es ein template content-news.php geben */
get_template_part( 'template-parts/post/content', 'news' );
endwhile;
the_posts_pagination( array(
'prev_text' => twentyseventeen_get_svg( array( 'icon' => 'arrow-left' ) ) . '<span class="screen-reader-text">' . __( 'Previous page', 'twentyseventeen' ) . '</span>',
'next_text' => '<span class="screen-reader-text">' . __( 'Next page', 'twentyseventeen' ) . '</span>' . twentyseventeen_get_svg( array( 'icon' => 'arrow-right' ) ),
'before_page_number' => '<span class="meta-nav screen-reader-text">' . __( 'Page', 'twentyseventeen' ) . ' </span>',
) );
else :
get_template_part( 'template-parts/post/content', 'none' );
endif;
?>
</main><!-- #main -->
</div><!-- #primary -->
<?php get_sidebar(); ?>
</div><!-- .wrap -->
<?php get_footer();
Soll sich die Anzahl angezeigter Elemente von der Standardeinstellung in WordPress unterscheiden, muss folgendes in die functions.php
des Childthemes:
function custom_number_of_news($query) {
if ( ! is_admin() && $query->is_post_type_archive( 'news' ) && $query->is_main_query() ) {
$query->set( 'posts_per_page', 3 ); /* 3 Elemente pro Seite */
}
}
add_filter( 'pre_get_posts', 'custom_number_of_news' );
Custom Post Type Query Template
Soll das Archiv über ein Template in eine Seite geholt werden, ist ein eigener Query erforderlich, und das sieht aus wie folgt.
Beispiel page-news.php
Um als Template in einer Seite wählbar zu sein, muss die Vorlage einen einzigartigen Namen haben, und im Theme oder ggf. Childtheme untergebracht sein.
<?php
/**
* Template Name: News
*
* a custom post type page template
*
*/
get_header(); ?>
<div class="wrap">
<header class="page-header">
<h1 class="page-title"><?php single_post_title(); ?></h1>
</header>
<div id="primary" class="content-area">
<main id="main" class="site-main" role="main">
<?php
$args = array(
'post_type' => array( 'news' ),
'post_status' => array( 'publish' ),
'posts_per_page' => '3',
'paged' => ( get_query_var('paged') ? get_query_var('paged') : ( get_query_var('page') ? get_query_var('page') : 1 ) ),
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) :
while ( $loop->have_posts() ) : $loop->the_post();
/* unter template-parts post muss es ein template content-news.php geben */
get_template_part( 'template-parts/post/content', 'news' );
endwhile;
wp_reset_postdata();
$total_pages = $loop->max_num_pages;
if ( $total_pages > 1 ) :
$current_page = max(1, get_query_var('paged'));
$pagination = '<div class="posts-navigation clearfix">';
$pagination .= paginate_links( array(
'base' => get_pagenum_link(1) . '%_%',
'format' => '/page/%#%',
'current' => max(1, get_query_var('paged')),
'total' => $total_pages,
'prev_text' => __('« prev'),
'next_text' => __('next »'),
) );
$pagination .= '</div>';
echo $pagination;
endif;
else :
get_template_part( 'template-parts/post/content', 'none' );
endif;
?>
</main><!-- #main -->
</div><!-- #primary -->
</div><!-- .wrap -->
<?php get_footer();
Pagination in Custom Queries außerhalb von Archiven
Hier wird die Funktion the_posts_pagination()
nichts anzeigen.
The posts pagination function outputs a set of page numbers with links to the previous and next pages of posts. These functions are used for post listings (like index.php) or archives (like archives.php).
Würde also jemand vorsehen, die News mit einem Custom Query in einem Seiten-Template abzubilden (das dann auf einer beliebigen Seite in den Page-Attributen zur Auswahl steht), muss der Loop anders aussehen (die Beispieldatei wird unter page-templates/page-news.php
des Childthemes abgelegt).
Die Pagination kann mit paginate_links()
eingefügt werden (man findet unterschiedliche Snippets dazu im Netz, auch benutzerdefinierte Funktionen). Eine pre_get_posts
-Action für eine abweichende Anzahl von Elementen pro Seite gilt bereits über die Definition in den Query-Argumenten, da der main_query
schon durch ist, bevor Templates an die Reihe kommen.
Wesentliche Unterschiede zwischen Post Type Archiv und Custom Query Template
- Im Page-Template muss ein neuer Query angelegt werden, im Post Type Archiv „weiß“ WordPress, um welchen Inhaltstypen es geht.
- Die Paginierung mit
the_posts_pagination
funktioniert im Page-Template nicht, stattdessenpaginate_links
verwenden - Das Page-Template muss einer Seite zugewiesen werden, eine korrekt benannte Post Type Archiv-Datei erkennt WordPress automatisch
- Eine von den WordPress-Einstellungen abweichende Anzahl von Elementen pro Seite muss für das Archiv über
pre_get_posts
modifiziert werden, im Page-Template gilt das Argumentposts_per_page
Auch bei einem Custom Query auf einer Archivseite ist ein Filter erforderlich wenn die Anzahl angezeigter Posts niedriger ist als in den Blog-Einstellungen definiert. Die Anzahl der Seiten wird zwar richtig berechnet, und die Pagination sieht korrekt aus, übersteigt die Seitenanzahl jedoch jene die mit den Blogeinstellungen erreicht würde, zeigt jede darüber hinausgehende Seite 404 an. Sind Custom Taxonomies im Spiel, gilt das auch für sie. Es funktioniert bei einem Archiv-Custom Query sowohl the_posts_pagination
als auch paginate_links
function custom_number_of_news($query) {
if ( $query->is_main_query() && !is_admin() ) {
if ( $query->is_tax('news_tags') || $query->is_tax('news_category') || $query->is_post_type_archive('news') ) {
$query->set( 'posts_per_page', 3 );
}
}
}
add_filter( 'pre_get_posts', 'custom_number_of_news' );
Schreibe einen Kommentar