public
Created

Filter to apply a div before menu output

  • Download Gist
finished.php
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
Here is what I ended up going with. Not the way I wanted to do it, but hell it works...
<?
function tumble_menu( $args = array() ) {
/* Default arguments */
$defaults = array(
'container' => 'ul',
'menu_class' => 'nav',
'menu_id' => 'main_menu',
'theme_location' => 'main-menu',
'echo' => true,
'before' => '',
'after' => '',
'link_before' => '',
'link_after' => '',
'depth' => 1,
'sort_column' => 'menu_order',
'show_container' => false,
'walker' => '',
);
$defaults = apply_filters( 'tumble_nav_default_args', $defaults);
$args = wp_parse_args( $args, $defaults );
echo '<div class="menu-button">Menu</div>';
$main_menu = wp_nav_menu( $args );
}
pippins-vs.php
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
<?php
function pippin_sample_html() {
ob_start(); ?>
<ul>
<li>List Item <em>One</em></li>
<li>List <strong>Item</strong> Two</li>
<li>List Item <a href="#">Three</a></li>
</ul>
<?php
return ob_get_clean();
}
 
 
function pippin_add_html_wrapper($html, $begin, $end) {
// wrap our original HTML with the new tags
$html = $begin . $html . $end;
return $html;
}
add_filter('pippin_html_wrap', 'pippin_add_html_wrapper', 10, 3);
 
function pippin_print_html() {
$html = pippin_sample_html();
echo apply_filters('pippin_html_wrap', $html, '<div id="sample_wrapper">hello world</div>', '');
?>
wrapper.php
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
<?php
function tumble_menu( $args = array() ) {
/* Default arguments */
$defaults = array(
'container' => 'ul',
'menu_class' => 'nav',
'menu_id' => 'top_nav',
'theme_location' => 'top-menu',
'echo' => true,
'before' => '',
'after' => '',
'link_before' => '',
'link_after' => '',
'depth' => 1,
'sort_column' => 'menu_order',
'walker' => ''
);
$defaults = apply_filters( 'tumble_nav_default_args', $defaults);
$args = wp_parse_args( $args, $defaults );
 
$main_menu = wp_nav_menu( $args );
}
function tumble_add_menu_wrapper($html, $begin, $end) {
// wrap our original HTML with the new tags
$html = $begin . $html . $end;
return $html;
}
add_filter( 'tumble_menu_wrap', 'tumble_add_menu_wrapper', 10, 3 );
 
function tumble_do_menu_wrapper() {
$html = tumble_menu();
echo apply_filters( 'tumble_menu_wrap', $html, '<div class="menu-button">Menu</div>','' );
}
?>

The problem is that my

Menu
is being inserted after the menu
    instead of before it.....

    I've tried moving it to the before and after, but always I end up with the same, it's placed after the menu instead of before

Can you show me the complete markup of the rendered menu?

Sure. http://bit.ly/KrXcGp
The menu output is the center (main) menu just below the site description.

View source and you can see how the menu div (

Menu
) is placed below the menu ul

To see why this is a big problem, resize your browser window to a bit smaller and you will see the menu collapse for mobile. If you click the new 'menu' button you can see how the menu collapses 'up' instead of down.

*http://jsfiddle.net/wphotline/DqZgb/13/ shows the menu operating properly if the 'menu' is placed above the ul.

thanks so much for taking a peek. This has been driving me nuts all night as it makes no sense why my wrapper is placing it below when it is explicitly set as $above....

  • I should mention... this is a 1/2 finished theme, so kind of embarassing looking. This is my first attempt at building a theme that is 100% based on actions and filters, and it has been awesome to learn. Actually it is inspired by your articles I read a few weeks ago and has been a challenge to build. Now that I kinda get the idea, I can only imagine the possibilities. There is a whole lot going on behind the scenes. Everything can be changed via an action or filter :)

Same output, no change. very strange as when I use the snippet but replace wp_nav_menu with some static html instead, then the wrap function works perfectly just like the tutorial.

Ok, in an effort to make it as easy to setup as possible, I added the exact same logic to the second gist.

The only thing that changes is the initial function
pippins_sample_html() works
tumble_menu() does not.

That is where I am getting totally screwed up. Why one function has no problem being 'wrapped' but another doesn't like it and instead inserts the wrapper div below instead of above the output...

actually that is not outputting anything.
I tried the echo false earlier as a guess.

I got a message from chip saying it may not actually be possible to do this without writing a custom walker. He did not explain why and I am hoping to find that out someday.

My 'guess' is that WordPress is doing something during the wp_nav_menu() process which kills the ability to insert anything prior to it doing it this way.

I know it has to be something to do with the function because your tutorial snippet, referenced above works perfectly. The only change is the original function I am trying to 'wrap'.

Who knows.. maybe this is one of those hidden WP easter eggs just to drive us nuts LOL. I can say that it is things that WordPress does like this that makes it incredibly frustrating and hard to learn. I'm not a quitter though :)

After 20 hrs of trying every combination, I think I may just write a walker anyhow.

I wonder if there is a bug with wp_nav_menu() that prevents it from being returned properly. . .

LOL that would be just my luck. I pick a bad function to try to learn about using apply_filters LOL

Do you think this issue is worth my posting a trac ticket?

*It's easy for anyone to replicate even on their own theme as the logic is quite simple.

I just explored the core source and it turns out that there is actually a filter already applied to the menu that you could use:

$nav_menu = apply_filters( 'wp_nav_menu', $nav_menu, $args );

Line 232: http://core.trac.wordpress.org/browser/tags/3.4.1/wp-includes/nav-menu-template.php#L0

Thanks Pippin. That should do what I need it to do.

I'm going to make it a point to try and learn why the wrapper function didn't work as I had it. Basically I don't understand is why it matters.

I mean I am using a 'wrapper' function to insert stuff before and after (should I choose to) an object. Why the type of object makes a difference is rather confusing.

Your example snippet uses an unordered list and it can be 'wrapped'

My example snippet uses an unordered list and it can't be wrapped.

Something is going on either with WP, or php that I just don't yet grasp. My little brain says it should just work.

Would make a good follow up article someday on your tutorial as it's targeted at people trying to learn more about php and add_filter, add_action, etc... I can guarantee that other people are going to run into this issue and have the same questions.

Thanks so much for digging through this with me today.

The things that's strange is that your example should work. There really isn't anything wrong with it that I can see. I think it's a WP core issue with wp_nav_menu.

I posted a new gist on top of what I ended up going with. Not the 'right' way, but oh well. I need to learn more about apply_filters() to be able to do it the right way.

Sometime I'll post a trac ticket about the possible issue with wp_nav_menu().

Suppose it's kinda cool that I actually found a core issue... first time for me. Usually I'm just swatted down and told I'm doing it wrong. Nice to hear the opposite for a change.

If you end up posting a trac ticket, let me know as I'd like to follow it.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.