Menu’s, sidebars en widgets: WP 2.9 vs 3.0

 

De nieuwe focaldesign.be werd gemaakt in WordPress 2.9. Zonet werd versie 3.0 gelanceerd. Een van de grootste upgrades, voor mij althans, is de mogelijkheid om menu’s aan te maken via het CMS.
Na elke uurtjes zoeken, is het uiteindelijk gelukt zowel het hoofdmenu als alle zijmenu’s nu dynamisch via het WP-admin CMS te generen ipv semi-hardcoded zaken te moeten plaatsen in de custom theme.

Hieronder een vergelijking van wat voor deze website gewijzigd is op vlak van menus/sidebars.

Hoofdnavigatie

Naast m’n logo staat rechts het hoofdmenu home-portfolio-klanten-blog-over. In de vorige versie was dit semi-hardcoded in de header.php van m’n custom theme door middel van de wp_list_pages functie.

[codesyntax lang=”php” title=”wp-content/themes/focaldesign/header.php WP2.9″]

<div id="navigation">
	<?php
		print '<ul>';
		wp_list_pages('depth=1&title_li=&sort_column=menu_order');
		print '</ul>';
	?>
</div>

[/codesyntax]

In het CMS van v3.0 is er onder de tab ‘Weergave’ een nieuw item verschenen, namelijk ‘Menus’. Daar kan je nu zelf oneindig veel menu’s aanmaken waarin je pagina’s, tags, categoriën en zelfs custom links kan aan toevoegen.

Op die manier kan bovenstaande code vervangen worden door volgende snippet:

[codesyntax lang=”php” title=”wp-content/themes/focaldesign/header.php WP3.0″]

<?php wp_nav_menu( array(
	'menu' => 'Main nav',
	'container' => 'div',
	'container_id' => 'navigation'
 )); ?>

[/codesyntax]

Sidebars

Veel interessanter is de combinatie van menu’s en widgets om m’n custom zijmenu’s via het CMS te kunnen beheren. WordPress voorziet standaard maar 1 widget-container (sidebar) waar je allerlei zaken kan insteken. Ik wou echter andere widgets in de sidebar afhankelijk van de pagina waar het zijmenu wordt opgevraagd. Zo zie je dat het rechtermenu van de blog andere zaken bevat dan dat van m’n portfolio bvb.
Een optie om in WP2.9 verschillende sidebars te verkrijgen, is via je functions.php met gebruik van de register_sidebar-functie.

[codesyntax lang=”php” title=”wp-content/themes/focaldesign/functions.php WP2.9″]

if ( function_exists('register_sidebar') ){
    register_sidebar(array(
    'name' => 'sidebar1',
    'before_title' => '<h3>',
    'after_title' => '</h3>',
    'before_widget' => '<li>',
    'after_widget' => '</li>',
	));
	register_sidebar(array(
    'name' => 'sidebar2',
    'before_title' => '',
    'after_title' => '',
    'before_widget' => '',
    'after_widget' => '',
	));
}

[/codesyntax]

De widgets voldeden echter niet, waardoor ik de widgets niet gebruikte. Een andere optie was het gebruik van meerdere sidebar-bestanden en die oproepen in de desbetreffende pagina-templates of via php-conditions door middel va de get_sidebar-functie.

Zo had ik voor elk zijmenu een apart bestand. Een deel bevat hardcoded zaken (zoals m’n adres, de links naar m’n Linkedin/Facebook etc). Een ander deel maakt gebruik van WordPress-functies zoals wp_list_categories, wp_tag_cloud, wp_get_archives en get_search_form. Nog een ander deel zijn 2 externe javascripts om m’n Flickr- en Twitter-stream binnen te halen.

[codesyntax lang=”php” title=”Sidebar obv pagina”]

if ( is_page('contact') ) { get_sidebar('contact');  }
elseif ( is_page('over') ) { get_sidebar('over');  }
elseif ( is_page('portfolio') ) { get_sidebar('portfolio');  }
elseif ( is_front_page() ) { // toon niets  }
else  { get_sidebar('blog');  }

[/codesyntax]

Nieuw in WordPress 3.0 is dat je menu’s kan toevoegen in je sidebars. Zo maak ik een combinatie van multiple sidebars, menu’s en widgets.

In het CMS maak ik via “Menus” de nodige menu’s aan met pagina’s (subsecties van portfolio), custom links (linkedin, facebook etc. & alles ivm klanten-onderdeel).

In de functions.php registreer ik voor elk van de nodige types een sidebar:

[codesyntax lang=”php” title=”wp-content/themes/focaldesign/functions.php WP3.0″]

if ( function_exists('register_sidebar') ){
    register_sidebar(array(
    'name' => 'Portfolio',
    'before_title' => '<h3>',
    'after_title' => '</h3>',
    'before_widget' => '',
    'after_widget' => '',
	));
	register_sidebar(array(
    'name' => 'Klanten',
    'before_title' => '<h3>',
    'after_title' => '</h3>',
    'before_widget' => '',
    'after_widget' => '',
	));
	register_sidebar(array(
    'name' => 'Blog',
    'before_title' => '<h3>',
    'after_title' => '</h3>',
    'before_widget' => '',
    'after_widget' => '',
	));
	register_sidebar(array(
    'name' => 'Over',
    'before_title' => '<h3>',
    'after_title' => '</h3>',
    'before_widget' => '',
    'after_widget' => '',
	));
	register_sidebar(array(
    'name' => 'Contact',
    'before_title' => '<h3>',
    'after_title' => '</h3>',
    'before_widget' => '',
    'after_widget' => '',
	));
}

[/codesyntax]

Zo kan ik per sidebar de nodige widgets toevoegen. Sommige zijn dynamisch (categorieën, recente berichten, zoeken), andere zijn menu’s (zie screenshot in sidebar ‘portfolio’) en nog andere zijn tekst/html (zie screenshot in sidebar ‘over’).

Dan rest ons enkel nog om de ene sidebar.php van condities te voorzien zodat de dynamische sidebars op de juiste pagina’s terecht komen.

Daar doet zich nog één probleempje voor. Ik wil namelijk het ‘portfolio’ zijmenu op de portfolio-pagina maar ook op de subpagina’s. WordPress voorziet helaas nog steeds geen functie die kan checken of de pagina’s children zijn van een door u bepaalde pagina.
Hiervoor schreef ik een kleine extra functie in de functions.php die nadien wordt gebruikt in de sidebar.php:

[codesyntax lang=”php” title=”wp-content/themes/focaldesign/functions.php”]

function is_subpage_of($checkID) {
	global $post;
	if ( is_page() && $post->post_parent ) {
		$parentID = $post->post_parent;
		if ($checkID=$parentID) {
			return true;
			}
		else {
			return false;
			}
		}
	else {
		return false;
		}
	}

[/codesyntax]

[codesyntax lang=”php” title=”wp-content/themes/focaldesign/sidebar.php”]

// Homepage
if (is_front_page() )
	{
	//toon niets
	}

//Portfolio & subpages
elseif ( is_page('portfolio') ||  is_subpage_of(9) ) // 9 = id van page portfolio
	{
	if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('portfolio') ) { } else {  }
	}

// Klanten
elseif ( is_page('klanten') )
	{
	if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('klanten') ) { } else {  }
	}

// Over
elseif ( is_page('over') )
	{
	if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('over') ) { } else {  }
	}

// Contact
elseif ( is_page('contact') )
	{
	if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('contact') ) { } else {  }
	}

// Overige
else
	{
	if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('Blog') ) { } else {  }
	}
?>

[/codesyntax]

Resultaat

Nu heb ik 99% van de menu’s via het CMS kunnen aanmaken.  Daarnaast heb ik nu nog maar 1 sidebar.php bestand in plaats van een per type.

Enkel de tagcloud geeft een klein probleem. In m’n custom code in sidebar-blog.php gaf ik de div een id mee zodat ik die kon bewerken. Als ik echter de WordPress-widget gebruik, worden de links van de tagcloud gewoon na de h3 gezet. Gezien die niet in een div zitten, kan ik er ook geen class of id aan meegeven, wat er op zijn beurt toe leidt dat ik dat niet proper kan themen. De widget voorziet op CMS-niveau ook geen opties om id’s of classes toe te voegen (wat bvb wel kan bij custom links in menu’s).

Als iemand hiervoor een oplossing heeft, hoor ik het graag!