Beiträge pro Kategorie

Eine Funktion für die Navigation, die die Beiträge pro Kategorie ausgibt - eine Alternative für statische Seiten.

Beispiel der Ausgabe
WordPress ist in erster Linie ein Blog-Plattform. Nicht selten wird es aber als CMS eingesetzt und dabei spielen nicht nur Seiten eine Rolle, sondern auch Beiträge, da sie mehr Möglichkeiten geben, performanter laufen und im Standard im Feed zu finden sind. Daher nutze ich auch im Rahmen von WP als CMS oft lieber die Beiträge als die statischen Seiten. Ab und an sind die Wünsche im Rahmen von Navigationen dabei recht ausgefallen und so war bei einem letzten Projekt die Anforderung, liste die Beiträge pro Kategorie zur Kategorie in der Navigation.
Dies ist insofern unüblich, da man auf lange Sicht viele Beiträge hat und die Navigation dann recht unübersichtlich wird - trotzdem hat in dem Fall der Wunsch Sinn gemacht und eine Lösung für die Navi musste her.

Die kleine Funktion listet die Kategorie und darunter die Beiträge. Es gibt einen Parameter, der die Ausgabe der Beiträge einschränkt, so dass es im Extremfall nicht zu viele werden und die letzten Beiträge gelistet werden - $mylimit. Die Übergabe des Wertes -1 für diesen Parameter sorgt für das Ausgeben aller Beiträge, alternativ nutzt einen Wert, der die Anzahl bestimmt. Die Funktion selber gehört in die functions.php des Themes oder ein Plugin ausgelagert. Eine beispielhafte Verwendung findet ihr im Anschluss an die Funktion.


function fb_posts_by_category() {
	global $wpdb, $post;
	
	$mylimit = '-1'; // limit for posts, -1 for all
	$sort_code = 'ORDER BY name ASC, post_date DESC';
	$the_output = '';

	$last_posts = (array)$wpdb->get_results("
		SELECT $wpdb->terms.name, $wpdb->terms.term_id
		FROM $wpdb->terms, $wpdb->term_taxonomy
		WHERE $wpdb->terms.term_id = $wpdb->term_taxonomy.term_id
		AND $wpdb->term_taxonomy.taxonomy = 'category'
		{$hide_check} 
	");

	if ( empty($last_posts) )
		return NULL;

	$used_cats = array();
	$i = 0;
	foreach ($last_posts as $posts) {
		if ( in_array($posts->name, $used_cats) ) {
			unset($last_posts[$i]);
		} else {
			$used_cats[] = $posts->name;
		}
		$i++;
	}
	$last_posts = array_values($last_posts);

	//$the_output .= '<ul>';
	foreach ($last_posts as $posts) {
		$class = 'cat-item cat-item-' . $posts->term_id;
		$catsy = get_the_category();
		$current_category = $catsy[0]->cat_ID;
		if ( isset($current_category) && $current_category && ($posts->term_id == $current_category) )
		$class .=  ' current-cat';
		elseif ( isset($_current_category) && $_current_category && ($posts->term_id == $_current_category->parent) )
		$class .=  ' current-cat-parent';
		
		$the_output .= '<li class="' . $class . '"><a class="category" href="' . get_category_link($posts->term_id) . '">' . apply_filters('list_cats', $posts->name, $posts) . '</a>';
		$where = apply_filters('getarchives_where', "WHERE post_type = 'post' AND post_status = 'publish'" , $r );
		
		if ('-1' !== $mylimit)
			$limit = ' LIMIT ' . (int) $mylimit;
		else
			$limit = '';
		
		$arcresults = $wpdb->get_results("SELECT ID, post_title  FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish' AND ID IN (Select object_id FROM $wpdb->term_relationships, $wpdb->terms WHERE $wpdb->term_relationships.term_taxonomy_id =" . $posts->term_id . ") ORDER BY post_date DESC$limit");
		if (isset($arcresults) && $arcresults) {
			$the_output .= '<ul>';
			foreach ( $arcresults as $arcresult ) {
				$class = 'post-item post-item-' . $arcresult->ID;
				$current_post = get_the_ID();
				if ( isset($current_post) && $current_post && is_singular() && ($arcresult->ID == $current_post) )
				$class .=  ' current-post';
				
				$the_output .= '<li class="' . $class . '"><a class="post" href="' . get_permalink($arcresult->ID) . '">' . apply_filters('the_title', $arcresult->post_title) . '</a></li>';
			}
			$the_output .= '</ul>';
		}
		
		$the_output .= '</li>';
	}
	//$the_output .= '</ul>';
	
	echo $the_output;
}

Nur bestimmte Kategorien einbeziehen

Dazu genügt im einfachsten Fall die Ergänzung des SQL-Query, wo man die IDs mitteilt, die durchsucht werden dürfen.


AND $wpdb->term_taxonomy.term_id IN (3,8,9)

Alternativ kann man auch Kategorien ausschließen


AND $wpdb->term_taxonomy.term_id NOT IN (3,8,9)

Beispielhafte Verwendung

Beispielhafte Verwendung in der sidebar.php, die hier mit Markup HTML5 auskommt.
Screenshot des Beispiels


<div id="sidebar">
	<nav>
		<h3>Navigation</h3>
		<ul>
			<li><a title="Startseite aufsuchen" href="<?php bloginfo('url'); ?>">Home</a></li>
			<?php
			fb_posts_by_category();
			
			wp_list_pages( 'title_li=&sort_column=menu_order&exclude=2,14,49' );
			?>
		</ul>
	</nav>
</div>

Accordion Menu ergänzen

Mit Hilfe von ein wenig JavaScript und dem Framework jQuery kann man dann jeweils nur den Bereich zeigen, der aktiv ist, eine kleines Beispiel dazu, welches die Klassen anspricht und entsprechend die Animation auslößt.


jQuery(document).ready(function($) {
	$(".cat-item ul").hide();
	$(".current-cat ul").show();
 
	$(".page_item ul").hide();
	$(".current_page_parent ul, .current_page_item ul").show();
 
	return false;
});