В проекте WordPress, основанном на Timber, мне нужно программно добавить все термины (со ссылкой) настраиваемой таксономии (группы жертв) в TimberMenu в качестве дочерних элементов пункта меню жертвы (настраиваемый тип записи).
Есть ли (элегантный) способ сделать это?
Версия WordPress: 4.4.2
Timber Version: 0.22.5
======= ======== UPDATE
Например:
в моем термине таксономии (группы жертв) у меня есть термины a, b, c, d, e
теперь я хочу добавить пункт меню под названием группы жертв с дочерними пунктами a, b, c, d и e
Так что я могу нажать на любой из a, b, c, d или e, чтобы получить страницу со всеми сообщениями, связанными с этим термином.
Клиенту не разрешено устанавливать пункты меню, поэтому я должен устанавливать их программно и автоматически добавлять в него все новые термины этой таксономии (группы жертв).
ура и заранее спасибо
bambamboole
Я обычно делаю такие вещи через wp_get_nav_menu_items
фильтр. Когда я впервые попробовал это, мне потребовалось довольно много времени, чтобы понять, как я могу смоделировать существующий WP_Post или WP_Term для использования в качестве элемента меню навигации. Вы не можете просто добавить сам элемент, но вам нужно немного изменить его, чтобы элемент навигации по-прежнему связывался с нужным местом назначения.
Кроме того, если вы просто добавляете пункты меню, это может испортить ваш порядок меню. Поэтому мы должны перестроить массив меню с нашим собственным счетчиком порядка меню.
Я использовал следующую комбинацию вспомогательной функции и вариаций wp_get_nav_menu_items
Отфильтруйте несколько проектов, чтобы быстро добавлять новые элементы в мои меню, будь то пользовательские типы записей или таксономии. До сих пор отлично работало. Этот подход должен работать независимо от того, используете ли вы стандартный WP Nav Menu Walker или TimberMenu для отображения своих меню в своей теме.
/**
* Prepare a post or term object to be used as a WP nav menu item.
*
* @param string $type The type of the object added to the menu. Can be 'page',
* 'category', 'taxonomy' or empty, assuming a custom post type
* @param WP_Post|WP_Term $menu_post The object you want to add that is converted
* to a menu item
* @param int $menu_parent The parent menu item you want to add the object to
* @param int $menu_order_counter The current menu order counter
* @param bool $set_new_id Whether to overwrite the current menu id. You normally want to
* do this, if you don’t want menu items to disappear randomly.
* @return void
*/
function pre_setup_nav_menu_item( $type = '', &$menu_post, $menu_parent, $menu_order_counter, $set_new_id = true ) {
$menu_post->menu_item_parent = $menu_parent;
$menu_post->menu_order = $menu_order_counter;
$menu_post->post_type = 'nav_menu_item';
if ( 'page' == $type ) {
$menu_post->object_id = $menu_post->ID;
$menu_post->object = 'page';
$menu_post->type = 'post_type';
} else if ( 'category' == $type ) {
$menu_post->object_id = $menu_post->term_id;
$menu_post->object = 'category';
$menu_post->type = 'taxonomy';
} else if ( 'taxonomy' == $type ) {
$menu_post->object_id = $menu_post->term_id;
$menu_post->object = $menu_post->taxonomy;
$menu_post->type = 'taxonomy';
// Assuming a custom post type
} else {
// Use TimberPost if Timber exists
if ( class_exists( 'Timber' ) ) {
$menu_post = new TimberPost( $menu_post );
}
$menu_post->object_id = $menu_post->ID;
$menu_post->object = $type;
$menu_post->type = 'post_type';
}
/**
* Create unique ID because in some cases the ID
* will act as an array key. This way, no menu objects
* should be overwritten.
*/
if ( $set_new_id ) {
$menu_post->ID = uniqid();
}
}
Мы берем все существующие пункты меню и зацикливаем их. Когда пункт меню «Жертвы» найден, мы получаем все термины группы «Жертва» и добавляем их в качестве пунктов подменю. Чтобы найти нужный пункт меню, вы должны создать страницу «Жертвы», которую затем добавляете вручную в свое меню. В следующем фильтре вам нужно будет указать идентификатор страницы «Жертва», а также имя, под которым вы зарегистрировали свою пользовательскую таксономию.
/**
* Filter through nav menu items and add child items and anchor links accordingly
*/
add_filter( 'wp_get_nav_menu_items', function( $items, $menu, $args ) {
/**
* The page id of the page that was added manually to the menu
* and should hold the custom taxonomy menu items.
*/
$victim_page_id = 22;
// Name of the custom taxonomy victim groups
$victim_groups_tax_name = 'victimgroup';
/**
* Menus in Admin would also be affected if we wouldn’t
* check if we’re on the frontend
*/
if ( ! is_admin() ) {
// Array to hold the newly built nav menu items array
$new_items = array();
// Integer to store custom menu order as we build up the new array
$menu_order_counter = 1;
/**
* Loop through existing menu items and add them to custom menu
*/
foreach ( $items as $item ) {
// Add items in normal order
$item->menu_order = $menu_order_counter;
$new_items[] = $item;
$menu_order_counter++;
// Check for the menu item we want to add our submenu items to
if ( (int) $item->object_id == $victim_page_id ) {
// Victim Groups take the current menu item as a parent
$menu_parent = $item->ID;
// Get victim groups taxonomy terms
$terms = Timber::get_terms( $victim_groups_tax_name, array(
// You probably want to hide empty taxonomies
'hide_empty' => true,
) );
// Loop through terms found and add them as menu items
foreach ( $terms as $term ) {
$term->post_title = $term->name;
$term->post_parent = $term->parent;
pre_setup_nav_menu_item( 'taxonomy', $term, $menu_parent, $menu_order_counter );
$term = new TimberTerm( $term );
$new_items[] = wp_setup_nav_menu_item( $term );
$menu_order_counter++;
unset( $term );
}
}
}
return $new_items;
}
return $items;
}, 10, 3);
Других решений пока нет …