0

在基于木材的 Wordpress 项目中,我需要在 TimberMenu 中以编程方式添加自定义分类法(受害者组)的所有术语(带链接)作为菜单点受害者的子项(自定义帖子类型)。

有没有(优雅的)方法可以做到这一点?

Wordpress 版本:4.4.2 木材版本:0.22.5

=======更新========

例如:在我的分类术语(受害者组)中,我有术语 a、b、c、d、e

现在我想添加一个名为受害者组的菜单项,其中包含子项 a、b、c、d 和 e

这样我就可以单击 a、b、c、d 或 e 中的任何一个来获取与该术语相关的所有帖子的页面。

不允许客户设置菜单项,因此我必须以编程方式设置它们并自动向其中添加此分类法(受害者组)的所有新术语。提前欢呼和感谢

4

1 回答 1

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();
    }
}

过滤器

我们获取所有现有的菜单项并遍历它们。当找到菜单项“Victims”时,我们获取所有 Victim Group 术语并将它们添加为子菜单项。为了能够找到正确的菜单项,您将创建一个“受害者”页面,然后手动将其添加到您的菜单中。在以下过滤器中,您必须设置页面“受害者”的页面 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);
于 2016-04-24T21:28:32.227 回答