在基于Timber的Wordpress项目中,我需要以编程方式在TimberMenu中添加自定义分类(受害者组)的所有条款(带链接)作为菜单点受害者(自定义帖子类型)的子项。
有(优雅的)方法吗?
Wordpress版本:4.4.2 木材版本:0.22.5
======= UPDATE ======
例如: 在我的分类学术语(受害者群体)中,我有术语a,b,c,d,e
现在我想添加一个名为victim groups的菜单项,其子项为a,b,c,d和e
这样我就可以点击a,b,c,d或e中的任何一个来获取包含与此术语相关的所有帖子的页面。
客户不允许设置菜单项,因此我必须以编程方式设置它们并自动将此分类法(受害者组)的所有新术语添加到其中。 欢呼并提前感谢 bambamboole
答案 0 :(得分:1)
我通常通过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();
}
}
我们采用所有现有的菜单项并循环遍历它们。当找到菜单项“受害者”时,我们将获得所有受害者组的条款并将其添加为子菜单项。为了能够找到正确的菜单项,您将创建一个页面“受害者”,然后您可以手动将其添加到菜单中。在以下过滤器中,您必须设置页面“受害者”的页面ID以及您注册自定义分类的名称。
/**
* 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);