Wordpress Timber 将自定义分类法添加到菜单
Wordpress Timber add Custom Taxonomy to Menu
在基于 Timber 的 Wordpress 项目中,我需要在 TimberMenu 中以编程方式添加自定义分类法(受害者组)的所有术语(具有 link)作为菜单点受害者(自定义 post类型)。
有没有(优雅的)方法来做到这一点?
WordPress 版本:4.4.2
木材版本:0.22.5
=======更新========
例如:
在我的分类术语(受害者群体)中,我有术语 a、b、c、d、e
现在我想添加一个名为 victim groups 的菜单项,其中包含子项 a、b、c、d 和 e
这样我就可以点击 a、b、c、d 或 e 中的任何一个来获取包含与该术语相关的所有 post 的页面。
不允许客户设置菜单项,因此我必须以编程方式设置它们并自动将此分类法(受害者组)的所有新术语添加到其中。
欢呼并提前感谢
竹子
我通常通过 wp_get_nav_menu_items
过滤器来做这种事情。当我第一次尝试这个时,我花了很长时间才弄明白如何模拟现有的 WP_Post 或 WP_Term 以用作导航菜单项。你不能只添加项目本身,但你需要稍微调整一下,以便导航项目仍然链接到正确的目的地。
此外,如果您只是添加菜单项,它可能会打乱您的菜单顺序。所以我们必须用我们自己的菜单顺序计数器重建菜单数组。
我在几个项目中使用了辅助函数和 wp_get_nav_menu_items
过滤器变体的以下组合来快速将新项目添加到我的菜单中,无论是自定义 post 类型还是分类法.到目前为止效果很好。无论您使用标准的 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();
}
}
过滤器
我们获取所有现有的菜单项并遍历它们。当找到菜单项 "Victims" 时,我们获取所有 Victim Group 术语并将它们添加为子菜单项。为了能够找到正确的菜单项,您需要创建一个页面 "Victims",然后将其手动添加到您的菜单中。在以下过滤器中,您必须设置页面的页面 ID "Victim" 以及您注册自定义分类法时使用的名称。
/**
* 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);
在基于 Timber 的 Wordpress 项目中,我需要在 TimberMenu 中以编程方式添加自定义分类法(受害者组)的所有术语(具有 link)作为菜单点受害者(自定义 post类型)。
有没有(优雅的)方法来做到这一点?
WordPress 版本:4.4.2 木材版本:0.22.5
=======更新========
例如: 在我的分类术语(受害者群体)中,我有术语 a、b、c、d、e
现在我想添加一个名为 victim groups 的菜单项,其中包含子项 a、b、c、d 和 e
这样我就可以点击 a、b、c、d 或 e 中的任何一个来获取包含与该术语相关的所有 post 的页面。
不允许客户设置菜单项,因此我必须以编程方式设置它们并自动将此分类法(受害者组)的所有新术语添加到其中。 欢呼并提前感谢 竹子
我通常通过 wp_get_nav_menu_items
过滤器来做这种事情。当我第一次尝试这个时,我花了很长时间才弄明白如何模拟现有的 WP_Post 或 WP_Term 以用作导航菜单项。你不能只添加项目本身,但你需要稍微调整一下,以便导航项目仍然链接到正确的目的地。
此外,如果您只是添加菜单项,它可能会打乱您的菜单顺序。所以我们必须用我们自己的菜单顺序计数器重建菜单数组。
我在几个项目中使用了辅助函数和 wp_get_nav_menu_items
过滤器变体的以下组合来快速将新项目添加到我的菜单中,无论是自定义 post 类型还是分类法.到目前为止效果很好。无论您使用标准的 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();
}
}
过滤器
我们获取所有现有的菜单项并遍历它们。当找到菜单项 "Victims" 时,我们获取所有 Victim Group 术语并将它们添加为子菜单项。为了能够找到正确的菜单项,您需要创建一个页面 "Victims",然后将其手动添加到您的菜单中。在以下过滤器中,您必须设置页面的页面 ID "Victim" 以及您注册自定义分类法时使用的名称。
/**
* 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);