Wordpress Timber将自定义分类添加到菜单

时间:2016-03-31 14:28:27

标签: php wordpress menu custom-post-type timber

在基于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

1 个答案:

答案 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);