I had to copy a whole wordpress-installation to another server. I simply installed a new WordPress there and imported all the data from an xml-file previous WordPress “exported” for me. Anyway, custom menus were not included. Do you know where in the database are they located, so I could grab them from there?
Leave a Reply
You must be logged in to post a comment.
I’ve got a site with a Magento install and WordPress install sitting next to each other, and cross-linking.
I recently spent several hours writing a class to drop into the Magento installation so that I could render the WordPress menu as the navigation menu in the Magento site.
Posts here have been helpful, but none of them have completely explained the structure of how WordPress menus are stored. Like many WP things, it is stored in a series of relationships. Here’s the structure:
(note that this example presumes a table prefix if of “wp_”)
Sample SQL statements to perform the above described operation:
(looks for a menu item with the name of ‘Top’, and gets the term id)
(loads the data for the menu, based on the term_id of 3)
Note that this sql statement will work for pages and custom menus (I don’t have any categories, so didn’t include that). The data loaded will allow you to build the permalink using the siteurl from the wp_options table, and appending the post_name to the end (technically, it’s not getting the parent structure, but WP finds the page/post properly without it)
Update
A commenter asked about assembling the child menu items with the parent menu items. That will need to be done with PHP. Something like below will do that for you:
For people still arriving at this question, I’ll put it in simple phpMyAdmin terms.
There are 6 tables involved.
1. wp_term_taxonomy
WordPress keeps each nav menu location as a record in the ‘wp_term_taxonomy’ table, but the only unique identifier there is a number ID; 1, 2, 3, etc.
You can also see the ‘count’ figures that show the number of items in each menu location.
This is what’s created when you type
You will not find the name ‘Your Navmenu’ anywhere in the database â that is just used for labelling it in the interface.
However, you will find ‘your-navmenu’ elsewhere.
2. wp_terms
Your actual menus get stored in ‘wp_terms’.
WordPress is confusing with this terminology. In the interface, it has ‘display locations’ and ‘menus’. The location is what’s created by
register_nav_menu()
. It’s best to consider the ‘menus’ in the interface as lists of pages.I’ve given them the name ‘navlist’ here.
The menus also get their own IDs, which are often the same as the location IDs (because people often create one menu for one location at the same time), which can get confusing.
This item is created by the ‘Menus’ page in the admin interface:
3. wp_options
You will see the ‘your-navmenu’ slug in ‘wp_options’. Here, WordPress stores your current settings for the nav menus. It stores it in a serialised array (using PHP’s
serialize()
function).The original array (obtained using
unserialize()
) looks like this.This changes according to which menu (by its ID; ‘2’, ‘3’) you set to which location (by its slug; ‘your-navmenu’, ‘another-navmenu’).
4. wp_posts
The menu entries themselves are stored in a different table, ‘wp_posts’.
You can find these by searching for ‘nav_menu_item’:
I’ve cut out most of the columns for brevity and kept the relevant ones.
Here, you can see the ‘menu_order’ column, which stores their order in the menu they are in.
The menu entries are stored like actual posts, with a post ID and URL (but it will bring a 404 if you visit it, and they have no ‘post_content’).
All menu items stored as a sub-item will have a ‘post_parent’ ID. This is the ID of the actual page that their parent links to, not its menu item ID.
5. wp_postmeta
Menu items are linked to their respective pages in the ‘wp_postmeta’ table.
The menu item ID (‘post_id’) is stored in relation to the post ID (‘meta_value’) in the ‘_menu_item_object_id’ rows, while sub-items are linked to their parent items in the ‘_menu_item_menu_item_parent’ rows.
It’s easy to get confused here.
‘post_id’ is the ID of the menu item, not the post. ‘meta_value’ is the ID of the post, not the menu item, in ‘_menu_item_object_id’ rows, but it’s the ID of the parent menu item, not a post, in ‘_menu_item_menu_item_parent’ rows.
6. wp_term_relationships
The links between each menu item and each menu location are stored in ‘wp_term_relationships’.
Here, ‘object_ID’ is the post ID of the menu item (as seen in ‘wp_posts’), and ‘term_taxonomy_id’ is the ID of the menu location (as seen in ‘wp_term_taxonomy’).
Hope this cleared it up for some people. I know I was very confused at the start.
I found this just because I was looking for the answer myself.
I see your post is quite old, but the answer is in wp_postmeta, run this query:
You’ll find many entries.
This setting happens in the wp_posts table.
Look in the table for records where the menu_order greater than zero.
It will also give you the name of the option in the wp_options table where the menu option is configured.
Also be aware that that wordpress import/export tool will not import media (images,video etc) from the media library which are not being used in posts. If you’ve got stuff that you directly linked to, its not going to be moved either.
I have been searching high and low for the entire structure and I finally cracked the code:
To simplify/complexify @random_user_name’s two queries, you can condense them into 1 query so that the only input parameter needed is the menu name. Like this:
This SQL statement gets the job done a little more thoroughly and legibly than the rest, I think. All you need to do is put your menu name into
t.name = 'main nav'
on the first join. It outputs every tidbit of menu info except the XFN field.I added additional column on cale_b’s query. The column
lvl
has depth for indentation.Assume that:
Query:
Result: