Wordpress在哪里存储自定义菜单?

Mar*_*ine 14 wordpress

我不得不将整个wordpress-installation复制到另一台服务器上.我只是在那里安装了一个新的Wordpress,并导入了以前Wordpress"导出"的xml文件中的所有数据.无论如何,自定义菜单不包括在内.你知道他们在数据库中的位置,所以我可以从那里抓住它们吗?

ran*_*ame 20

我有一个Magento安装和WordPress安装的网站彼此相邻,并且交叉链接.

我最近花了几个小时编写一个类来放入Magento安装,这样我就可以将WordPress菜单渲染为Magento站点中的导航菜单.

这里的帖子很有帮助,但没有一个完整地解释了WordPress菜单存储方式的结构.像许多WP一样,它存储在一系列关系中.这是结构:

(请注意,此示例假设表格前缀为"wp_")

  1. 首先,重要的是要认识到菜单项可以是帖子(技术上它是页面,但页面存储在帖子表中),类别,或者它可以是自定义链接.
  2. 因为WP支持多个菜单,所以首先查看wp_term_taxonomy表,以查找具有"nav_menu"分类的任何术语.请注意该表中的term_id.
  3. 要查找菜单的名称和slug,请访问wp_terms表,找到上面步骤2中记录的id的术语.
  4. 转到wp_term_relationships表并列出term_taxonomy_id与步骤1中的term_id匹配的所有记录.object_id字段告诉您wp_post.id记录,您可以在其中找到菜单记录.
  5. 最后,转到wp_postmeta以查找描述菜单的许多元素.特别感兴趣的是:
    • _menu_item_object - 菜单项的类型(页面,自定义或类别)
    • _menu_item_object_id - 菜单项引用的实际POST(或类别,如果它是类别)的id
    • _menu_item_menu_item_parent - 菜单的层次结构父母结构(可能与父母后关系不同)
    • _menu_item_url - 菜单项的slug(如果是自定义链接菜单项)

用于执行上述操作的示例SQL语句:

SELECT t.term_id 
FROM wp_term_taxonomy as tax 
LEFT JOIN wp_terms as t ON tax.term_id = t.term_id 
WHERE taxonomy = 'nav_menu' and name like '%top%'
Run Code Online (Sandbox Code Playgroud)

(查找名称为"Top"的菜单项,并获取术语ID)

SELECT p.ID, p.post_title, p.post_name, p.menu_order, n.post_name as n_name, n.post_title as n_title, m.meta_value, pp.meta_value as menu_parent
FROM wp_term_relationships as txr 
INNER JOIN wp_posts as p ON txr.object_id = p.ID 
LEFT JOIN wp_postmeta as m ON p.ID = m.post_id 
LEFT JOIN wp_postmeta as pl ON p.ID = pl.post_id AND pl.meta_key = '_menu_item_object_id' 
LEFT JOIN wp_postmeta as pp ON p.ID = pp.post_id AND pp.meta_key = '_menu_item_menu_item_parent' 
LEFT JOIN wp_posts as n ON pl.meta_value = n.ID 
WHERE txr.term_taxonomy_id = 3 AND p.post_status='publish' 
    AND p.post_type = 'nav_menu_item' AND m.meta_key = '_menu_item_url' 
ORDER BY p.menu_order
Run Code Online (Sandbox Code Playgroud)

(根据term_id为3加载菜单的数据)

请注意,此sql语句将适用于页面和自定义菜单(我没有任何类别,因此不包括该类别).加载的数据将允许您使用wp_options表中的siteurl构建永久链接,并将post_name附加到末尾(从技术上讲,它不是获取父结构,但WP在没有它的情况下正确查找页面/帖子)

更新
评论者询问如何使用父菜单项组装子菜单项.这需要用PHP完成.像下面这样的东西会为你做到这一点:

// run the query from above
$results = $wpdb->get_results('SELECT....');

// declare new variable to store "assembled" menu
$menu = array();

// loop over the items assigning children to parents
foreach( $results AS $row ) {
    // assemble key bits for the menu item
    $item = array(
        // handles custom navigation labels
        'title' => ( $row->post_title ) ? $row->post_title : $row->n_title,
        // handles custom links
        'permalink' => ( $row->meta_value ) ? $row->meta_value : get_permalink( $row->ID ),
        // declares empty placeholder for any child items
        'children' => array()
    );

    // if the menu item has a parent, assign as child of the parent
    if ( $row->menu_parent ) {
        $menu[ $row->menu_parent ][ 'children' ][] = $item;
    } else {
        $menu[ $row->ID ] = $item;
    }
}

var_dump( $menu );

// outputs something like below:
/**
 * array (size=6)
 *  77 => 
 *     array (size=3)
 *       'title' => string 'About Us' (length=8)
 *       'permalink' => string 'http://www.example.com/about' (length=33)
 *       'children' => 
 *        array (size=7)
 *          0 => 
 *            array (size=3)
 *              'title' => string 'Welcome' (length=22)
 *              'permalink' => string 'http://www.example.com/welcome' (length=35)
 *              'children' => 
 *                array (size=0)
 *                  empty
 *          1 => 
 *            array (size=3)
 *              'title' => string 'Mission' (length=20)
 *              'permalink' => string 'http://www.example.com/mission' (length=33)
 *              'children' => 
 *                array (size=0)
 *                  empty
 *  90 => 
 *    array (size=3)
 *      'title' => string 'Contact Us' (length=10)
 *      'permalink' => string 'http://www.example.com/contact' (length=33)
 *      'children' => 
 *        array (size=5)
 *          0 => 
 *            array (size=3)
 *              'title' => string 'Why Us' (length=12)
 *              'permalink' => string 'http://www.example.com/why' (length=35)
 *              'children' => 
 *                array (size=0)
 *                  empty
 *  1258 => 
 *    array (size=3)
 *      'title' => string 'Login' (length=12)
 *      'permalink' => string 'https://customlink.example.com/some/path/login.php' (length=82)
 *      'children' => 
 *        array (size=0)
 *          empty
 */
Run Code Online (Sandbox Code Playgroud)


SUM*_*UM1 20

对于仍然提出这个问题的人,我将用简单的 phpMyAdmin 术语来表达。

\n

涉及6张表。

\n

1. wp_term_taxonomy

\n

WordPress 将每个导航菜单位置作为记录保存在“wp_term_taxonomy”表中,但唯一的唯一标识符是数字 ID;1、2、3 等

\n

在此输入图像描述

\n

您还可以看到“计数”数字,显示每个菜单位置中的项目数量。

\n

这是您键入时创建的内容

\n
register_nav_menu(\'your-navmenu\', \'Your Navmenu\');\n
Run Code Online (Sandbox Code Playgroud)\n

您不会在数据库 \xe2\x80\x93 中的任何位置找到名称“Your Navmenu”,该数据库仅用于在界面中对其进行标记。

\n

但是,您会在其他地方找到“your-navmenu”。

\n

2. wp_terms

\n

您的实际菜单存储在“wp_terms”中。

\n

WordPress 与这个术语令人困惑。在界面中,它有“显示位置”和“菜单”。该位置是由 所创建的register_nav_menu()。最好将界面中的“菜单”视为页面列表。

\n

我在这里给它们命名为“navlist”。

\n

在此输入图像描述

\n

菜单也有自己的 ID,这些 ID 通常与位置 ID 相同(因为人们经常同时为一个位置创建一个菜单),这可能会造成混乱。

\n

该项目由管理界面中的“菜单”页面创建:

\n

在此输入图像描述

\n

3.wp_选项

\n

您将在“wp_options”中看到“your-navmenu”。WordPress 在这里存储您当前的导航菜单设置。它将其存储在序列化数组中(使用 PHP 的serialize()函数)。

\n

在此输入图像描述

\n

原始数组(使用 获得unserialize())如下所示。

\n
array (\n  \'custom_css_post_id\' => 56,\n  \'nav_menu_locations\' => \n  array (\n    \'your-navmenu\' => 2,\n    \'another-navmenu\' => 3,\n  ),\n)\n
Run Code Online (Sandbox Code Playgroud)\n

这会根据您将哪个菜单(通过其 ID;\'2\'、\'3\')设置到哪个位置(通过其子句;\'your-navmenu\'、\'another-navmenu\')而改变。

\n

4.wp_帖子

\n

菜单项本身存储在不同的表“wp_posts”中。

\n

您可以通过搜索“nav_menu_item”找到这些:

\n

在此输入图像描述

\n

为了简洁起见,我删除了大部分专栏并保留了相关的专栏。

\n

在这里,您可以看到“menu_order”列,它将它们的顺序存储在它们所在的菜单中。

\n

菜单条目的存储方式与实际帖子类似,带有帖子 ID 和 URL(但如果您访问它,则会出现 404,并且它们没有“post_content”)。

\n

所有存储为子项的菜单项都将具有“post_parent”ID。这是其父链接到的实际页面的 ID,而不是其菜单项 ID。

\n

5. wp_postmeta

\n

菜单项链接到“wp_postmeta”表中各自的页面。

\n

菜单项 ID (\'post_id\') 与帖子 ID (\'meta_value\') 相关地存储在 \'_menu_item_object_id\' 行中,而子项则链接到其在 \'_menu_item_menu_item_parent 中的父项\' 行。

\n

在此输入图像描述

\n

这里很容易让人困惑。

\n

\'post_id\' 是菜单项的 ID,而不是帖子的 ID。“meta_value”是“_menu_item_object_id”行中帖子的 ID,而不是菜单项的 ID,但它是“_menu_item_menu_item_parent”行中父菜单项的 ID,而不是帖子的 ID。

\n

6. wp_term_关系

\n

每个菜单项和每个菜单位置之间的链接存储在“wp_term_relationships”中。

\n

在此输入图像描述

\n

这里,“object_ID”是菜单项的帖子 ID(如“wp_posts”中所示),“term_taxonomy_id”是菜单位置的 ID(如“wp_term_taxonomy”中所示)。

\n

希望这能为某些人澄清。我知道一开始我很困惑。

\n

  • 谢谢你的这次伟大的崩溃 (3认同)

小智 7

我发现这个只是因为我自己在寻找答案。我看到您的帖子很旧,但答案在 wp_postmeta 中,运行以下查询:

SELECT *
FROM `wp_postmeta`
WHERE meta_key LIKE '%menu%'
LIMIT 0, 30
Run Code Online (Sandbox Code Playgroud)

你会发现很多条目。


txy*_*oji 6

此设置发生在 wp_posts 表中。在表中查找 menu_order 大于零的记录。

select * from wp_posts where menu_order > 0;
Run Code Online (Sandbox Code Playgroud)

它还将为您提供 wp_options 表中配置菜单选项的选项的名称。

select * from wp_options where option_name = "nav_menu_options";
Run Code Online (Sandbox Code Playgroud)

另请注意,wordpress 导入/导出工具不会从媒体库中导入未在帖子中使用的媒体(图像、视频等)。如果你有直接链接的东西,它也不会被移动。


Bob*_*nes 5

一直在高低搜索整个结构,终于破解了密码:

SELECT
p.ID,
m.meta_value,
md.post_author,
wp_users.user_nicename,
p.post_parent,
p.menu_order,
md.post_title
FROM
wp_posts AS p
INNER JOIN wp_postmeta AS m ON m.post_id = p.ID
INNER JOIN wp_posts AS md ON md.ID = m.meta_value AND m.meta_value = md.ID
INNER JOIN wp_users ON md.post_author = wp_users.ID
WHERE
p.menu_order > 0 AND
p.post_type = 'nav_menu_item' AND
m.meta_key = '_menu_item_object_id'
ORDER BY
p.menu_order ASC
Run Code Online (Sandbox Code Playgroud)