如果你有菜单数组,如何设置wordpress菜单


How to set wordpress menu if you have menu arrays

假设我有一个通过输出wp_get_nav_menus()(和一些修改)得到的数组,我想将它导入到新安装的wordpress中。数组看起来像这样(我们称之为$menu_array):

Array
(
    [0] => Array
        (
            [term_id] => 5
            [name] => my second menu
            [slug] => my-second-menu
            [term_group] => 0
            [term_taxonomy_id] => 5
            [taxonomy] => nav_menu
            [description] => 
            [parent] => 0
            [count] => 2
            [items] => Array
                (
                    [0] => Array
                        (
                            [ID] => 14
                            [post_author] => 1
                            [post_date] => 2015-10-06 07:32:03
                            [post_date_gmt] => 2015-10-06 07:32:03
                            [post_content] => 
                            [post_title] => This is my menu
                            [post_excerpt] => 
                            [post_status] => publish
                            [comment_status] => closed
                            [ping_status] => closed
                            [post_password] => 
                            [post_name] => this-is-my-menu
                            [to_ping] => 
                            [pinged] => 
                            [post_modified] => 2015-10-12 10:31:23
                            [post_modified_gmt] => 2015-10-12 10:31:23
                            [post_content_filtered] => 
                            [post_parent] => 0
                            [guid] => http://www.example.com/?p=14
                            [menu_order] => 1
                            [post_type] => nav_menu_item
                            [post_mime_type] => 
                            [comment_count] => 0
                            [filter] => raw
                            [db_id] => 14
                            [menu_item_parent] => 0
                            [object_id] => 14
                            [object] => custom
                            [type] => custom
                            [type_label] => Custom Link
                            [title] => This is my menu
                            [url] => #
                            [target] => 
                            [attr_title] => 
                            [description] => 
                            [classes] => Array
                                (
                                    [0] => 
                                )
                            [xfn] => 
                        )
                    [1] => Array
                        (
                            [ID] => 15
                            [post_author] => 1
                            [post_date] => 2015-10-06 07:32:03
                            [post_date_gmt] => 2015-10-06 07:32:03
                            [post_content] => 
                            [post_title] => second menu
                            [post_excerpt] => 
                            [post_status] => publish
                            [comment_status] => closed
                            [ping_status] => closed
                            [post_password] => 
                            [post_name] => second-menu
                            [to_ping] => 
                            [pinged] => 
                            [post_modified] => 2015-10-12 10:31:23
                            [post_modified_gmt] => 2015-10-12 10:31:23
                            [post_content_filtered] => 
                            [post_parent] => 0
                            [guid] => http://www.example.com/?p=15
                            [menu_order] => 2
                            [post_type] => nav_menu_item
                            [post_mime_type] => 
                            [comment_count] => 0
                            [filter] => raw
                            [db_id] => 15
                            [menu_item_parent] => 0
                            [object_id] => 15
                            [object] => custom
                            [type] => custom
                            [type_label] => Custom Link
                            [title] => second menu
                            [url] => #
                            [target] => 
                            [attr_title] => 
                            [description] => 
                            [classes] => Array
                                (
                                    [0] => 
                                )
                            [xfn] => 
                        )
                )
        )
    [1] => Array
        (
            [term_id] => 2
            [name] => My Menu
            [slug] => my-menu
            [term_group] => 0
            [term_taxonomy_id] => 2
            [taxonomy] => nav_menu
            [description] => 
            [parent] => 0
            [count] => 3
            [items] => Array
                (
                    [0] => Array
                        (
                            [ID] => 1104
                            [post_author] => 1
                            [post_date] => 2015-10-19 13:31:48
                            [post_date_gmt] => 2015-10-19 13:31:48
                            [post_content] =>  
                            [post_title] => 
                            [post_excerpt] => 
                            [post_status] => publish
                            [comment_status] => closed
                            [ping_status] => closed
                            [post_password] => 
                            [post_name] => 1104
                            [to_ping] => 
                            [pinged] => 
                            [post_modified] => 2015-10-19 13:31:48
                            [post_modified_gmt] => 2015-10-19 13:31:48
                            [post_content_filtered] => 
                            [post_parent] => 0
                            [guid] => http://www.example.com/?p=1104
                            [menu_order] => 1
                            [post_type] => nav_menu_item
                            [post_mime_type] => 
                            [comment_count] => 0
                            [filter] => raw
                            [db_id] => 1104
                            [menu_item_parent] => 0
                            [object_id] => 1016
                            [object] => page
                            [type] => post_type
                            [type_label] => Page
                            [url] => http://www.example.com/Test-page
                            [title] => Test page
                            [target] => 
                            [attr_title] => 
                            [description] =>  
                            [classes] => Array
                                (
                                    [0] => 
                                )
                            [xfn] => 
                        )
                    [1] => Array
                        (
                            [ID] => 12
                            [post_author] => 1
                            [post_date] => 2015-10-05 13:52:35
                            [post_date_gmt] => 2015-10-05 13:52:35
                            [post_content] => 
                            [post_title] => Google
                            [post_excerpt] => 
                            [post_status] => publish
                            [comment_status] => closed
                            [ping_status] => closed
                            [post_password] => 
                            [post_name] => google
                            [to_ping] => 
                            [pinged] => 
                            [post_modified] => 2015-10-19 13:31:48
                            [post_modified_gmt] => 2015-10-19 13:31:48
                            [post_content_filtered] => 
                            [post_parent] => 0
                            [guid] => http://www.example.com/?p=12
                            [menu_order] => 2
                            [post_type] => nav_menu_item
                            [post_mime_type] => 
                            [comment_count] => 0
                            [filter] => raw
                            [db_id] => 12
                            [menu_item_parent] => 0
                            [object_id] => 12
                            [object] => custom
                            [type] => custom
                            [type_label] => Custom Link
                            [title] => Google
                            [url] => http://google.com
                            [target] => 
                            [attr_title] => 
                            [description] => 
                            [classes] => Array
                                (
                                    [0] => 
                                )
                            [xfn] => 
                        )
                    [2] => Array
                        (
                            [ID] => 13
                            [post_author] => 1
                            [post_date] => 2015-10-06 07:22:39
                            [post_date_gmt] => 2015-10-06 07:22:39
                            [post_content] => 
                            [post_title] => Gmail
                            [post_excerpt] => 
                            [post_status] => publish
                            [comment_status] => closed
                            [ping_status] => closed
                            [post_password] => 
                            [post_name] => gmail
                            [to_ping] => 
                            [pinged] => 
                            [post_modified] => 2015-10-19 13:31:48
                            [post_modified_gmt] => 2015-10-19 13:31:48
                            [post_content_filtered] => 
                            [post_parent] => 0
                            [guid] => http://www.example.com/?p=13
                            [menu_order] => 3
                            [post_type] => nav_menu_item
                            [post_mime_type] => 
                            [comment_count] => 0
                            [filter] => raw
                            [db_id] => 13
                            [menu_item_parent] => 12
                            [object_id] => 13
                            [object] => custom
                            [type] => custom
                            [type_label] => Custom Link
                            [title] => Gmail
                            [url] => #
                            [target] => 
                            [attr_title] => 
                            [description] => 
                            [classes] => Array
                                (
                                    [0] => 
                                )
                            [xfn] => 
                        )
                )
        )
)

这是一个名为"我的菜单"的菜单,它有2个页面,我可以为多个菜单创建多个数组,层次结构遵循菜单。

我看了一下wordpress如何处理导入它,它使用wp_update_nav_menu_item()wp_nav_menu_update_menu_items()

我试过了,但到目前为止,我没有任何运气。

但是因为wordpress菜单是post类型nav_menu_item自定义分类法nav_menu,我可以使用wp_insert_post来导入我的菜单,或者有一些复杂的方法来做到这一点(比如我需要为每个菜单设置对象术语)?

我只是需要一些关于如何以正确的方式插入菜单的指导。

部分解决方案

所以我找到了这个链接,我接近实现我需要的。我是这样做的

foreach ($menu_array as $menu => $menu_val) {
    // Check if the menu exists
    $old_menu_id = $menu_val['term_id'];
    $menu_location = '';
    foreach (get_theme_mod('nav_menu_locations') as $old_menu_loc => $loc_id) {
        if ($old_menu_id == $loc_id) {
            $menu_location .= $old_menu_loc;
        }
    }
    $menu_name = $menu_val['name'];
    $menu_exists = wp_get_nav_menu_object( $menu_name );
    // If it doesn't exist, let's create it.
    if( !$menu_exists){
        $menu_id = wp_create_nav_menu($menu_name);
        $old_object_id = array();
        // Set up default menu items
        foreach ($menu_val['items'] as $item => $item_value) {
            $old_url = $item_value['url'];
            $old_object_id[] .= $item_value['object_id'];
            $new_url = (isset($url_relation_table[$old_url]) && $url_relation_table[$old_url]>0) ? $url_relation_table[$old_url] : $old_url;
            $menu_data = array(
                'menu-item-db-id' => 0,
                'menu-item-object-id' => '',
                'menu-item-object' => $item_value['object'],
                'menu-item-parent-id' => 0,
                'menu-item-position' => $item_value['menu_order'],
                'menu-item-title' => $item_value['title'],
                'menu-item-type' =>  $item_value['type'], //when removed no error but also no menu type!
                'menu-item-url' => ($new_url != '') ? $new_url : '#',
                'menu-item-description' => $item_value['description'],
                'menu-item-attr-title' => $item_value['attr_title'],
                'menu-item-target' => $item_value['target'],
                'menu-item-classes' => implode(' ', $item_value['classes']),
                'menu-item-xfn' => $item_value['xfn'],
                'menu-item-status' => $item_value['post_status'],
                );
            wp_update_nav_menu_item($menu_id, 0, $menu_data);
        }
        $new_menu_item = wp_get_nav_menu_items($menu_id);
        $new_object_id = array();
        foreach ($new_menu_item as $new_item => $new_item_value) {
            $new_object_id[] .= $new_item_value->ID;
        }
        $object_id_relation_array = array_combine($old_object_id, $new_object_id);
        $menu_obj_data = array(
            'description' => $menu_val['description'],
            'menu-name' => $menu_val['name'],
            'parent' => $menu_val['parent'],
            );
        wp_update_nav_menu_object($menu_id, $menu_obj_data);
    }
    $locations = array();
    if ($menu_location != '') {
        $locations[$menu_location] = $menu_id;
        set_theme_mod( 'nav_menu_locations', $locations );
    }
}

EDIT:这最后一段代码将把我的菜单设置为其中一个位置(我不认为这是正确的)。$menu_location数组只是位置名称作为键和名称作为值(它们在主题中定义,因此它们存在)。

此代码创建菜单,并将第一个菜单分配给一个位置,但没有链接页面。

EDIT2:我已经编辑了foreach一点,包括实际工作的菜单位置。但有些事情行不通。我无法让url显示在我的菜单上,并且菜单层次结构不起作用(父->子关系)。

困扰我的是数组$menu_data。我把这些我都不确定是否有效的钥匙。例如urlparent-id。所有的开发人员页面说,它是一个数组的菜单项的数据(好吧,duduuh)。如果我能知道我需要什么钥匙,可以放在里面,那就太好了。

EDIT3:所以我摆脱了我的错误(类需要是一个由空格分隔的字符串),但我不知道为什么我的层次结构不起作用,以及为什么我没有得到url字段。我需要更详细地浏览nav-menus.php,看看我错过了什么。

EDIT4:好吧,所以它几乎工作!由于某些原因,我收到通知:

注意:试图获得非对象的属性在C:'xampp'htdocs'test'wp-includes'nav-menu.php行404

注意:试图在C:'xampp'htdocs'test'wp-includes'nav-menu.php中获得非对象的属性

注意:试图在C:'xampp'htdocs'test'wp-includes'nav-menu.php中获得非对象的属性

当我删除$item_value['type']一切工作,但我没有得到我的菜单的帖子类型,所以都是自定义的,没有链接,所以简而言之,它不工作xD

另一件真正困扰我的事情是,我不能让层次结构工作。因此,当我导入菜单时,我将得到menu_item_parent是菜单项对象的ID(如果是的话)。在我的例子中,最后一个具有object id 13的菜单是具有object id 12的菜单项的子菜单,所以他的menu_item_parent是12。在创建新菜单时,情况会发生变化。因此,我创建了一个关系表,将旧菜单id与新菜单id联系起来。但我一直纠结于如何更新它。当我再次尝试更新菜单时,我把所有东西都搞砸了。我设法取代url(我有url关系表,其中有旧的和新的url),这是有效的,但由于菜单项是从无到有创建的,我不能只是去检查他们现在有什么id,除非他们完成了它。

好了,经过一番折腾,我解决了这个问题。

<?php
foreach ($menu_array as $menu => $menu_val) {
    // Check if the menu exists
    $old_menu_id = $menu_val['term_id'];
    $menu_location = '';
    foreach (get_theme_mod('nav_menu_locations') as $old_menu_loc => $loc_id) {
        if ($old_menu_id == $loc_id) {
            $menu_location .= $old_menu_loc;
        }
    }
    $menu_name = $menu_val['name'];
    $menu_exists = wp_get_nav_menu_object( $menu_name );
    // If it doesn't exist, let's create it.
    if( !$menu_exists){
        $menu_id = wp_create_nav_menu($menu_name);
        $old_object_id = array();
        //Set up default menu items
        foreach ($menu_val['items'] as $item => $item_value) {
            $old_url = $item_value['url'];
            $old_object_id[] .= $item_value['object_id'];
            $new_url = (isset($url_relation_table[$old_url])) ? $url_relation_table[$old_url] : $old_url;
            $obj_ID = url_to_postid($new_url);
            $menu_data = array(
                'menu-item-db-id' => '',
                'menu-item-object-id' => ( $obj_ID != 0 ) ? $obj_ID : '',
                'menu-item-object' => $item_value['object'],
                'menu-item-parent-id' => $item_value['menu_item_parent'],
                'menu-item-position' => $item_value['menu_order'],
                'menu-item-title' => $item_value['title'],
                'menu-item-type' =>  $item_value['type'],
                'menu-item-url' => ($new_url != '') ? $new_url : '#',
                'menu-item-description' => $item_value['description'],
                'menu-item-attr-title' => $item_value['attr_title'],
                'menu-item-target' => $item_value['target'],
                'menu-item-classes' => implode(' ', $item_value['classes']),
                'menu-item-xfn' => $item_value['xfn'],
                'menu-item-status' => $item_value['post_status'],
                );
            wp_update_nav_menu_item($menu_id, 0, $menu_data);
        }
        $new_menu_item = wp_get_nav_menu_items($menu_id);
        $new_object_id = array();
        $parent_id = array();
        foreach ($new_menu_item as $new_item => $new_item_value) {
            $new_object_id[] .= $new_item_value->ID;
            $parent_id[] .= $new_item_value->menu_item_parent;
        }
        $object_id_relation_array = array_combine($old_object_id, $new_object_id);
        $parent_relation_array = array_combine($new_object_id, $parent_id);
        foreach ($object_id_relation_array as $object_id_relation_key => $object_id_relation_value) {
            foreach ($parent_id as $parent_id_key => $parent_id_value) {
                if ($object_id_relation_key == $parent_id_value) {
                    $new_parent_id = $object_id_relation_value;
                    $item_id = array_search($parent_id_value, $parent_relation_array);
                    foreach ($new_menu_item as $single_item => $single_item_value) {
                        if ($single_item_value->ID == $item_id) {
                            $object = $single_item_value->object;
                            $object_ID = $single_item_value->object_id;
                            $position = $single_item_value->menu_order;
                            $title = $single_item_value->title;
                            $type = $single_item_value->type;
                            $url = $single_item_value->url;
                            $description = $single_item_value->description;
                            $attr_title = $single_item_value->attr_title;
                            $target = $single_item_value->target;
                            $classes = implode(' ', $single_item_value->classes);
                            $xfn = $single_item_value->xfn;
                            $status = $single_item_value->post_status;
                            $update_parent_id = array(
                                    'menu-item-db-id' => $item_id,
                                    'menu-item-object-id' => $object_ID,
                                    'menu-item-object' => $object,
                                    'menu-item-parent-id' => $new_parent_id,
                                    'menu-item-position' => $position ,
                                    'menu-item-title' => $title ,
                                    'menu-item-type' =>  $type ,
                                    'menu-item-url' => $url ,
                                    'menu-item-description' => $description ,
                                    'menu-item-attr-title' => $attr_title ,
                                    'menu-item-target' => $target ,
                                    'menu-item-classes' => $classes ,
                                    'menu-item-xfn' => $xfn ,
                                    'menu-item-status' => $status ,
                                );
                            wp_update_nav_menu_item($menu_id, $item_id, $update_parent_id);
                        }
                    }

                }
            }
        }
        $menu_obj_data = array(
            'description' => $menu_val['description'],
            'menu-name' => $menu_val['name'],
            'parent' => $menu_val['parent'],
            );
        wp_update_nav_menu_object($menu_id, $menu_obj_data);
    }
    $locations = array();
    if ($menu_location != '') {
        $locations[$menu_location] = $menu_id;
        set_theme_mod( 'nav_menu_locations', $locations );
    }
}

我来解释一下。

首先你需要获得菜单位置(可以从主题mod中获得,也可以放入数组中),然后你创建一个菜单。创建一个菜单,即使从已有的名称将创建一个全新的菜单与新的ID。更重要的是,菜单项也将有新的ID。这就有点复杂了。

之后,列出现有的项,并开始在foreach循环中逐个更新新项。但你还需要某种关系表来保存旧url和新url之间的关系。这是非常重要的,因为你以前导出的帖子没有和新地方相同的url。

但是如果你有它,那么你只需要拉出这些关系,并在一个菜单项中放置新的url。此外,如果你的菜单项是一个页面,那么你需要把它的ID, menu-item-object-id是。这很重要,因为如果你不这样做,你会得到一个提示不能从wordpress nav-menu。php中获取非对象的属性。这就是url_to_postid()函数派上用场的地方。把你的url放在那里,你会得到文章的id,否则你会得到0。

现在你已经建立了你的菜单,你很高兴。但是等等!那么等级制度呢?

您在新菜单中放入的是菜单之间的旧关系。用旧身份证。这显然行不通,因为当你更新菜单项时,你会得到新的ID。因此,您需要一个新的关系表来连接旧ID和新ID,并且您还需要一种方法来查看哪些菜单项中有这些parent-id,以便您可以重新提取所有信息。

问题是,你已经创建了你的菜单,所以你需要再次检查这些关系,并替换它们,最好的事情就是看看哪些菜单有这样的关系,并且只更新那些菜单(这就是为什么你有2个wp_update_nav_menu_item()调用)。

之后,你可以更新导航菜单对象(虽然我不确定这是不是真的需要,但我没有看到错误,所以为什么不呢),并设置菜单到正确的位置。

我只需要检查多个子菜单和一些细节。但现在这工作:)