Artikkelilistaus shortcodena arkistosivulle

Relevanssin tietämyskannassa on kokoelma ohjeita, ideoita ja sekalaista tietämystä Relevanssin toiminnasta. Aikaisemmin kaikki artikkelit ovat olleet yhdessä kategoriassa (Knowledge base) ja arkistosivulla on ollut käsin ylläpidetty luokiteltu listaus artikkeleista. Tässä listassa artikkeleita on jaettu eri alaryhmiin aiheen mukaan.

Listan ylläpitäminen on vaivalloista ja tulin siihen tulokseen, että asiaan on oltava parempikin ratkaisu. Halusin automatisoida listan, koska käsin ylläpidettävä lista on riesa, jonka kanssa on mahdollista lisäksi tehdä virheitä.

Päädyin luokittelemaan artikkelit uusiin alakategorioihin aiheen mukaan.

Osoiterakenteen säilyttäminen

Halusin pitää vanhat /knowledge-base/artikkelin-nimi-tyyppiset osoitteet, ilman että osoitteeseen tunkee mukaan alakategoria. Käytän permalinkeissä %category%-elementtiä, joka lisää alakategorian mukaan automaattisesti, eikä WordPressissä ole valmiiksi tähän ratkaisua.

Tämä tehtävä osoittautui kuitenkin helpoksi: apuun löytyi post_link_category-suodatin.

add_filter( 'post_link_category', 'rlvcom_remove_subcategory', 99 );
function rlvcom_remove_subcategory( $cat ) {
	if ( $cat->parent > 0 ) {
		$cat = get_term( $cat->parent, $cat->taxonomy );
	}
	return $cat;
}

Tämä funktio saa parametrinä artikkelin kategorian, jonka perusteella %category% osoitteen muodostaa. Funktio tarkistaa, onko kategorialla yläkategoriaa ($cat->parent > 0) ja jos on, kategoria korvataan yläkategoriallaan. Siinäpä se.

Artikkelilistaus kategoriasivulle

Automaattisen kategorialistauksen päätin toteuttaa shortcodena, koska se antaa joustavuutta sivupohjien muokkaamisen sijasta, ja shortcode on helppo lykätä kategorian kuvaukseen. Oletuksena shortcodet eivät toimi kategorioiden kuvauksissa, mutta olin mahdollistanut tämän jo aikaisemmin saadakseni kuvaukseen hakulomakkeen Relevanssin searchform-shortcodella.

add_filter( 'get_the_archive_description', 'shortcode_unautop');
add_filter( 'get_the_archive_description', 'do_shortcode' );

Itse shortcode on melko suoraviivainen. Se näyttää tältä:

[rlv_list_categories cats="features,debugging,indexing,search-results-pages,filter-hooks,languages-and-characters,query-variables,performance,shortcodes,plugin-compatibility,theme-compatibility"]

Parametrissä listataan kaikki alakategoriat halutussa järjestyksessä. Käytin slugia, koska se on ihan eri tavalla luettava kuin ID-numero, joten järjestystä on helppo pohtia ja tarvittaessa muuttaa.

Katsoin, että shortcoden ajaminen tällaisenaan tuottaa reilut 70 tietokantakyselyä (katsothan aina, älä tee sokkona jotain tällaista tarkistamatta millaisen tietokantakuorman saat aikaan), joten vaikka se olikin nopea, välimuistitin sen silti transientiin päivän ajaksi. Säästö se on pienikin säästö!

add_shortcode( 'rlv_list_categories', 'rlv_list_categories' );
function rlv_list_categories( $atts ) {
	$atts = shortcode_atts( array( 'cats' => '' ), $atts );
	$html = get_transient( 'rlv_list_categories_' . hash( 'md2', $atts['cats'] ) );
	if ( $html ) {
		return $html;
	}
	$cats = explode( ',', $atts['cats'] );
	$html = '<div>';
	foreach ( $cats as $cat_slug ) {
		$cat_term  = get_term_by( 'slug', $cat_slug, 'category' );
		$cat_posts = get_posts(
			array(
				'category_name'  => $cat_slug,
				'posts_per_page' => -1,
				'post_status'    => 'publish',
				'orderby'        => array( 'post_title' => 'asc' ),
			)
		);

		if ( $cat_posts ) {
			$html .= '<h2>' . $cat_term->name . '</h2><ul>';
			$posts = array_map(
				function( $_post ) {
					$link = get_permalink( $_post->ID );
					return '<li><a href="' . $link . '">' . $_post->post_title . '</a></li>';
				},
				$cat_posts
			);
			$html .= implode( "\n", $posts ) . '</ul>';
		}
	}
	$html .= '</div>';
	set_transient( 'rlv_list_categories_' . hash( 'md2', $atts['cats'] ), $html, DAY_IN_SECONDS );
	return $html;
}

Muutoin funktio on aika suoraviivainen. Kategoriat kelataan läpi foreach-silmukalla, jokaiselle kategorialle haetaan kaikki julkaistut artikkelit aakkosjärjestyksessä otsikon mukaan get_posts()-funktiolla. Artikkelien array muutetaan array_map()-funktiolla html-koodiksi, jossa on linkki artikkeliin.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *

This site uses Akismet to reduce spam. Learn how your comment data is processed.