Problem solved.
While WordPress provides no specific function for adding items and sub-items to the nav bar, there's a workaround. The project involved an author being able to add new books to her database, and have them automatically show up in the nav bar as a sub-item under "Books" without having to go through the Dashboard to do it.
I went to header.php
in the theme dir and found the wp_nav_menu()
function. After reading this article, I was able to modify the output, using str_replace
to add some <li>
tags of my own.
This is what the default looked like:
wp_nav_menu( array( 'theme_location' => 'primary' ) );
Here's my modified version:
// First open up a database connection
$db = new MySQLi(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME)
What I did next was basically call up the links (called "guid" in the table) and post titles from "wp_posts" table in the WordPress database. I also needed to get the book names from my own "books" table. The book titles are the same as the "post_title" in "wp_posts".
// Here's the command I used to call them up
$command = 'SELECT b.book_title AS book_title, wp.guid AS guid FROM books AS b
LEFT OUTER JOIN wp_posts AS wp ON b.book_title = wp.post_title
GROUP BY b.order;';
$books_submenu = ''; // leave this empty for now
// Fetch objects from tables
$result = $db->query($command);
while ($data = $result->fetch_object()) {
$books_submenu = $books_submenu . '
<li class="menu-item">
<a href="' . $data->guid . '">' . $data->book_title . '</a>
</li>'; // Each loop will add another <li> to the variable.
Now comes the part that had me stumped. You can add arguments to the wp_nav_menu
function by adding them into the array inside. The important ones I needed were the "theme_location" and "echo". I put all of this in a variable:
$my_new_menu = wp_nav_menu( array( 'theme_location' => 'primary', 'echo' => false ) );
Setting "echo" to false makes the HTML of the function an editable PHP variable. Now we can manipulate it much more easily:
$my_new_menu = str_replace( '>Books</a></li>', // We're going to replace this...
'>Books</a><ul class="sub-menu">' . $books_submenu . '</ul></li>', // ...with this.
$my_new_menu
);
And finally:
echo $my_new_menu; // Result should be a custom dropdown
That's my end of the work. Every time she adds a new book, my plugin uses wp_post_insert()
to add the page to "wp_posts" and adds the book to my "books" table. From there, this script should add that new book to the top of her navigation page :-)