Vlastní Walker pro vaše šablony

WordPress Funkce na procházení více položek, wp_nav_menu, wp_list_categories, wp_list_pages, wp_list_comments a další, mají mezi svými parametry také jeden, který je, a často i zůstává, pro uživatele tak trochu zahalen tajemstvím. Jde o parametr “walker”.

Jako modelovou, pro tento článek, jsem si vybral funkci wp_list_categories(), která prochází kategorie a ty posléze, dle v parametrech předaných pravidel, vypisuje, ale také třeba jen vrací (pomocí parametru echo). Skrce parametry této funkce můžeme změnit kde co. Můžeme nechat vypsat i prázdné kategorie, můžeme ovlivnit pořadí výpisu, to, jestli se kategorie vypíší jako seznam nebo ne, jestli zobrazíme počet příspěvků v kategorii a tak dále a tak dále.

Tvůrci WordPressu se nám snažili případnou editaci co možná nejvíc zpříjemnit. Ovšem někdy ani tato široká škála možností nestačí a tvůrce si s parametry nevystačí. V tom případě přichází na řadu vytváření vlastního Walkeru.

Jaké Walkery jsou ve WordPressu dostupné

Walker je třída, jenž zajišťuje procházení více položek a jejich výpis či vracení do proměnné. Všechny WordPress Walkery (Walker_Comment, Walker_CategoryDropdown, Walker_PageDropdown, Walker_Page, Walker_Category, Walker_nav_menu) jsou odvozené od původní třídy Walker, kterou rozšiřují (extends) o nové funkce.
Walkery Walker_Category, Walker_Page, Walker_PageDropdown a Walker_CategoryDropdown jsou umístěny v souboru wp-includes/classes.php. Walker_Comment je v souboru wp-includes/comment-template.php a Walker_nav_menu je v souboru wp-includes/nav-menu-template.php.

Poznámka: Pro potřeby administrace existují ještě další Walkery a jsou definované v souborech wp-admin/includes/template.php (Walker_Category_Checklist) a wp-admin/includes/nav-menu.php (Walker_Nav_Menu_Edit, Walker_Nav_Menu_Checklist). Z nich můžete čerpat inspiraci pro vaše úpravy walkerů.

Vytváříme vlastní Walker

Pakliže chceme takový Walker modifikovat, musíme si vytvořit nový, který bude rozšiřovat (extend) již nějaký existující. A to buď původní Walker, nebo již nějaký, který jej rozšiřuje (extends). Jak na to.

V souboru functions.php naší šablony (pakliže jej vaše šablona ještě nemá, klidně jej vytvořte) vytvoříme novou třídu (class), která bude rozšiřovat (extends) nějaký Walker. Jak jsem psal, budeme se zde modelově zabývat rošiřováním Walkeru funkce wp_list_categories(). Tento Walker je definován v souboru wp-includes/classes.php na řádku 1283

Tato třída definuje 4 funkce, a sice: start_lvl, end_lvl, start_el a end_el. Funkce start_lvl se volá, když některá kategorie má subkategorie a tyto se mají vypsat hierarchicky, end_lvl se zas vykoná když se dojde za poslední položku hierarchicky vypsané subkategorie, start_el se volá vždy, když se zpracovává nová položka, a end_el, když se ukončilo zpracování každé položky.

Když budeme chtít například upravit způsob výpisu jednotlivých položek bude nám stačit, když námi nově vytvořená třída bude definovat jen funkci start_el. Nic víc není třeba. Samozřejmě je možné, upravovat více, nebo dokonce všechny funkce.

Čili v souboru functions.php si nadefinujeme novou třídu rozšiřující Walker_Category.

class Vlastni_Walker extends Walker_Category {
...
}

A do této třídy si můžeme nakopírovat funkce, které chceme upravit.

class Vlastni_Walker extends Walker_Category {
function start_el(&$output, $page, $depth, $args, $current_page) {
		if ( $depth )
			$indent = str_repeat("\t", $depth);
		else
			$indent = '';
 
		extract($args, EXTR_SKIP);
		$css_class = array('page_item', 'page-item-'.$page->ID);
		if ( !empty($current_page) ) {
			$_current_page = get_page( $current_page );
			if ( isset($_current_page->ancestors) && in_array($page->ID, (array) $_current_page->ancestors) )
				$css_class[] = 'current_page_ancestor';
			if ( $page->ID == $current_page )
				$css_class[] = 'current_page_item';
			elseif ( $_current_page && $page->ID == $_current_page->post_parent )
				$css_class[] = 'current_page_parent';
		} elseif ( $page->ID == get_option('page_for_posts') ) {
			$css_class[] = 'current_page_parent';
		}
 
		$css_class = implode(' ', apply_filters('page_css_class', $css_class, $page));
 
		$output .= $indent . '
 
	<li class="' . $css_class . '"><a title="' . esc_attr( wp_strip_all_tags( apply_filters( 'the_title', $page-&gt;post_title, $page-&gt;ID ) ) ) . '" href="' . get_page_link($page-&gt;ID) . '">' . $link_before . apply_filters( 'the_title', $page-&gt;post_title, $page-&gt;ID ) . $link_after . '</a>';
 
		if ( !empty($show_date) ) {
			if ( 'modified' == $show_date )
				$time = $page-&gt;post_modified;
			else
				$time = $page-&gt;post_date;
 
			$output .= " " . mysql2date($date_format, $time);
		}
	}
}</li>

A můžeme se pustit do upravování. Provádět si můžeme prakticky cokoli. Když budeme s úpravami hotovi a spokojeni, stačí již jen zavolat funkci wp_list_categories() s patřičným parametrem.

1
wp_list_categories( array( 'walker' => new Vlastni_Walker() ) );

Samozřejmě můžeme redefinovat také všechny funkce, která třída Walker_Category dědí od původní třídy Walker. Tato třída je definována opět v souboru wp-include/classes.php, tentokráte na řádku 742. Jde o funkce, kromě těch čtyrech již zmíněných, display_element(), walk(), paged_walk(), get_number_of_root_elements() a unset_children().