As part of a theme for a client, I want to be able to show a custom menu (defined via the admin) in a select box that automatically changes pages after changing the selection.
Is there a plugin (or a handy code snippet) that will accomplish this?
As part of a theme for a client, I want to be able to show a custom menu (defined via the admin) in a select box that automatically changes pages after changing the selection.
Is there a plugin (or a handy code snippet) that will accomplish this?
You must be logged in to post a comment.
WordPress’ new menu system is both wondrous and infinitely frustrating, depending on what you are trying to do and what day of the week it happens to be. 🙂 It’s a great idea but far from mature so while it’s a feature I applaud I’ll be happier when v3.3 or v3.4 of WordPress rolls out and we get a lot more use-cases directly supported by the menu system’s API.
That said, not sure if there is an existing plugin to do what you are looking for, but how about the code you need to write you own plugin? Or you could just include it in your theme’s
functions.php
file; whatever your preference.What I’m providing is a fully self-contained example that you can save as
test.php
in your website’s root directory in order to test it. If your domain wereexample.com
you’d load to test at:Here’s what it look’s like in action:
(source: mikeschinkel.com)
(source: mikeschinkel.com)
From the code below it should be easy to incorporate the
get_page_selector()
function into your theme and to call it whenever you need this functionality:So you might wonder how it works?
The
wp_get_nav_menu_items()
functionWordPress 3.0 stores it’s menus in the
wp_posts
table aspost_type
type ofnav_menu_item
. Thewp_get_nav_menu_items()
indirectly just calls theget_posts()
function. The first parameter towp_get_nav_menu_items()
is either 1.) a menu name (which is what I used: “My Select Menu”), 2.) a menu item ID (i.e. the menu item’s postID
the database) or 3.) a menu slug (the slug from the menu’s taxonomy term; yes menus are implemented using taxonomy terms with a taxonomy of'nav_menu'
.)(source: mikeschinkel.com)
Beyond the first parameter it forwards on to
get_posts()
most (if not all?) of the$args
you pass towp_get_nav_menu_items()
thus you can treat it like a custom post type (even though longer term when they improve the menu API that probably won’t be such a great idea. But today? Make hay while the sun shines!)Filtering Menu Items with
meta_key
andmeta_value
WordPress’ underlying use of posts for menu items is why we can query for
meta_key
andmeta_value
; WordPress uses a series ofmeta_keys
prefixed with_menu_item
for the additional information it needs for each menu item._menu_item_object
will containpage
for every menu item that corresponds to a WordPress “Page” post type. (If you want to include items besides Pages you you’ll need to do a bit more research than I did here but at least I gave you the tools you need to do the research yourself.)Here’s a screenshot using Navicat for MySQL of a query showing the meta records for several
nav_menu_items
:(source: mikeschinkel.com)
Grabbing the Page’s URL with
get_post_link()
Next I’ll point out that get the page’s URL from the
get_post_link()
function and that I’m setting the HTML<option>
‘svalue
to be the URL…Using Javascript’s
onchange
to Navigate to our Selected Page…So that I can grab it from the
value
property of the'page-selector'
<select>
element and assign it tolocation.href
. Assigninglocation.href
causes the browser to immediately navigate to the new URL, and that, in a nutshell, is how it’s all done:An Empty
value=""
as the Default OptionYou might note that the “Select a Page” default option has an empty value; that’s not a mistake but instead by design. When it is selected and the
"onchange"
is triggered1 settinglocation.href
to an empty string will have no effect, which is exactly what we want and it doesn’t require us to write an exception code. Viola!"onchange"
can only happen on a browser back navigation to a page that doesn’t trigger a page reload where another option had previously been selected, but it can still happen so we should address it.