Простая альтернатива wp_list_pages()
Для вывода подстраниц авторы тем очень часто используют такой код:
$children = wp_list_pages('title_li=&child_of='.$post->ID.'&echo=0');
if ($children) { ?>
<ul>
<?php echo $children; ?>
</ul>
?>
У wp_list_pages()
, на мой взгляд, есть два серьёзных недостатка:
- Хотя для вывода информации нужны всего два поля (
ID
иpost_title
),wp_list_pages()
выбирает всю информацию, что ведёт к увеличению трафика между PHP и MySQL (и, в конечном итоге, сказывается на производительности); - При использовании
wp_list_pages()
не получается вывести дополнительную информацию о странице (например, её описание, рейтинг и т.п.).
С первым недостатком разбираются разработчики (если я не ошибаюсь, уже готов патч), а со вторым не всё так просто: функциональность “зашита” в класс Walker_Page
, не предоставляющий фильтров, с помощью которых можно “повлиять” на результат (the_title
не в счёт, в нашем случае с ним будет больше проблем, чем пользы). Так что если нужна дополнительная функциональность, придётся писать свою функцию (или класс).
Пример функции, выводящей список страниц с описаниями (как здесь; своеобразная интеграция с All in One SEO Pack):
{
print '<ul>';
foreach ($pages as $x) {
print "<li class='page_item page-item-{$x->ID}'>";
print '<a href="' . get_page_link($x->ID) . '" title="' . attribute_escape(apply_filters('the_title', $x->post_title)) . '">' . apply_filters('the_title', $x->post_title) . '</a> ';
print '<span class="description">' . get_post_meta($x->ID, 'description', true) . '</span>';
if (false == empty($x->children)) {
render_items_recursive($x->children);
}
print '</li>';
}
print '</ul>';
}
function list_pages_with_description($parent)
{
$p = &get_pages('sort_column=menu_order,post_title&child_of=' . $parent);
if (true == empty($p)) {
return;
}
$pages = array();
$map = array();
$item = null;
foreach ($p as $x) {
unset($x->post_content);
if ($parent == $x->post_parent) {
$pages[$x->ID] = $x;
$map[$x->ID] = &$pages[$x->ID];
}
else {
$item = &$map[$x->post_parent];
$item->children[] = $x;
$map[$x->ID] = &$item->children[count($item->children)-1];
}
}
unset($map, $item);
ob_start();
render_items_recursive($pages);
$s = ob_get_contents();
ob_end_clean();
return $s;
}
Вызывается так:
<?php if ($children) : ?>
<?php print $children; ?>
<?php endif; ?>
А выглядеть всё будет так, как по ссылке выше. Поддерживается неограниченный уровень вложенности. В PHP4 из-за проблем с организацией ссылок работать, скорее всего, не будет.