WordPress som CMS: En sidebar pr. kategori

Opnå mere flek­si­bilitet i bru­gen af Word­Press som CMS med én side­bar pr. kat­e­gori. Få PHP koden her.

Mange designere og udviklere væl­ger at bruge Word­Press som CMS fordi det er så enkelt og rel­a­tivt nemt at imple­mentere og udvikle til. Én af Word­Press’ store begræn­sninger i rollen som CMS er imi­dler­tid sidebar-metaforen. Som udgangspunkt er der i de fleste themes kun én eller to side­bars til rådighed sitewide, netop fordi Word­Press er skabt som blog­ging værk­tøj. I en blog er det sjældent nød­vendigt med flere.

Men har man brug for et decideret CMS, er der behov for rel­e­vant sekundært ind­hold på alle sider. Noget, der relaterer sig til sidens primære ind­hold og ikke bare en generel liste med kat­e­gorier, et arkiv og en blog roll.

Og så fik jeg den ide at man måske kunne opnå noget brug­bart, hvis man kunne oprette en side­bar pr. emnekat­e­gori. Så ville det være muligt at mål­rette widget-indhold til de enkelte emner og dermed øge rel­e­vansen af sekundært ind­hold på indlæg og kat­e­gorisider. Efter en del eksper­i­menteren, lykkedes det mig at skrue neden­stående sammen.

Neden­stående kode skal stå i dit themes functions.php fil:


<?php
# Get sidebar names from db.
global $wpdb;
$my_widget_name = $wpdb->get_col("SELECT slug
FROM $wpdb->terms, $wpdb->term_taxonomy
WHERE $wpdb->terms.term_id=term_taxonomy_id
AND taxonomy='category' AND count!=0 ORDER BY name ASC");

# Register one sidebar per category name.
foreach($my_widget_name as $my_widget) {
  register_sidebar(array(
    'name' => 'Category: ' . $my_widget,
    'before_widget' => '<div id="%1$s" class="%2$s widget">',
    'after_widget' => '</div>',
    'before_title' => '<h3 class="widget-title">',
    'after_title' => '</h3>', ));
}
?>

Først opret­ter vi en forbindelse til data­basen, hen­ter kat­e­gori­navn og id fra alle kat­e­gorier, der ikke er tomme, samt sorterer kat­e­gori­erne efter navn. Dernæst reg­istr­erer vi vores nye side­bars i Word­Press med funk­tio­nen register_sidebar samt navn­giver hver side­bar med det enkelte kategorinavn.

Ind­sæt de nye side­bars i dit themes sidebar.php fil:


<?php
# If this is a category archive page.
if (is_category()) {
	global $wp_query;
	$cat_obj = $wp_query->get_queried_object();
	$category_slug = $cat_obj->slug;
}
# If this is a post.
elseif (is_single()) {
	$category = get_the_category();
	$category_slug = $category[0]->category_nicename;
}
# The widget.
if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('category_' . $category_slug) ) : ?>
<div id="search" class="widget widget_search">
	<h3><?php _e('Search'); ?> <?php bloginfo('name'); ?></h3>
	<?php include (TEMPLATEPATH . '/searchform.php'); ?>
</div>
<?php endif; ?>

For at kalde den rigtige side­bar, skal vi have fat i det rigtige kat­e­gori­navn. Hvis siden er en kategori-side, kalder vi kat­e­goriens navn. Men hvis siden er et indlæg, kalder vi navnet på den første kat­e­gori, siden er gemt i. Nu udskrives kat­e­goriens side­bar, hvis du befinder dig på en kategori-side eller et indlæg.

Hvad så med ‘sider’?
Man kan lave noget tilsvarende med Word­Press’ side-metafor. I stedet for at tage fat i kat­e­gori­erne i data­basekaldet, skal man så bare have fat i tilsvarende for ‘sider’. I så fald vil data­basekaldet se ud som følger:


$page_sidebars = $wpdb->get_col("SELECT post_name
FROM $wpdb->posts WHERE post_type='page'
AND post_status='publish' AND post_parent='0'
ORDER BY menu_order ASC");

Bemærk!
Man skal være for­sigtig med meto­den, hvis man har mange kat­e­gorier og/eller sider, da Word­Press laver et kald til data­basen for hver side­bar, den skal loade i backend’en. Skal den lave for mange kald, får man time out og så fun­gerer meto­den naturligvis ikke.