Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup Nav Filters #136

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open

Conversation

bryanwillis
Copy link
Contributor

This gives us a lot more freedom to edit/remove the menus individually.

This gives us a lot more freedom to edit/remove the menus individually.
@bryanwillis
Copy link
Contributor Author

Any thought on this?

Here's an even more advanced example... I can honestly say that this has made things so much easier when editing the menu as each menu is completely customizable individually?

/**
 * Bootstrap Nav Markup
 */
add_filter('genesis_do_nav', 'genesis_child_nav', 10, 3);
add_filter('genesis_do_subnav', 'genesis_child_nav', 10, 3);
function genesis_child_nav($nav_output, $nav, $args)
{
    $args['depth'] = 2;
    $args['menu_class'] = 'nav navbar-nav';
    $args['fallback_cb'] = 'wp_bootstrap_navwalker::fallback';
    $args['walker'] = new wp_bootstrap_navwalker();

    $nav = wp_nav_menu($args);
    $sanitized_location = sanitize_key($args['theme_location']);
    $data_target = 'nav-collapse-' . $sanitized_location;

    $nav_markup = <<<EOT
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#{$data_target}">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
EOT;
    $nav_markup.= apply_filters("bsg_navbar_brand_{$sanitized_location}", $navbar_brand);
    $nav_markup.= '</div>'; // .navbar-header

    $nav_markup.= '<div class="collapse navbar-collapse" id="' . $data_target . '">';

    ob_start();
    do_action('before_nav_' . $sanitized_location);
    $before_nav = ob_get_clean();

    ob_start();
    do_action('after_nav_' . $sanitized_location);
    $after_nav = ob_get_clean();

    $nav_markup.= $before_nav . $nav . $after_nav;

    $nav_markup.= '</div>'; // .collapse .navbar-collapse

    $nav_markup_open = sprintf('<nav %s>', genesis_attr('nav-' . $sanitized_location));
    $nav_markup_open.= genesis_structural_wrap('menu-' . $sanitized_location, 'open', 0);
    $nav_markup_close = genesis_structural_wrap('menu-' . $sanitized_location, 'close', 0) . '</nav>';

    $nav_output = $nav_markup_open . $nav_markup . $nav_markup_close;
    return $nav_output;
}

Then I also have these helper functions:

/**
 * Filter genesis_attr_structural-wrap to use BS .container-fluid classes
 */
add_filter( 'genesis_attr_structural-wrap', 'bsg_attributes_structural_wrap' );
function bsg_attributes_structural_wrap( $attributes ) {
    $attributes['class'] = 'container';
    return $attributes;
}
/**
 * Add structural-wrap replacement utility function to use 
 * Bootstrap responsive .container class
 *
 * Useage: add_filter( 'genesis_structural_wrap-{$context}', 'bsg_wrap_container_fluid');
 */
function bsg_wrap_container_fluid( $output, $original_output ) {
    if ( $original_output == 'open' ) {
        $output = sprintf( '<div %s>', genesis_attr( 'container-fluid' ) );
    }
    return $output;
}
/**
 * Helper function to easily change the nav menu location 
 */
function child_bsg_navbar_right( $nav_output, $nav ) {
    $nav_output = str_replace( 'nav navbar-nav', 'nav navbar-nav navbar-right', $nav_output );
    return $nav_output;
}

@bryanwillis
Copy link
Contributor Author

Here's some examples possible with all this:

Change primary menu container to container-fluid:

add_filter( 'genesis_structural_wrap-menu-primary', 'tbg3_wrap_container_fluid', 99, 2);

Move submenu to the right side:

add_filter( 'genesis_do_subnav', 'child_bsg_navbar_right', 10, 2 );

Add the search form after the primary menu:

add_action('after_nav_menu-primary', function() { get_search_form(); });

Add to secondary brand area

add_filter('bsg_navbar_brand_menu-secondary', function() {

}

@salcode
Copy link
Owner

salcode commented Mar 7, 2016

I'm still wrapping my head around this code but a couple of quick notes so I don't need to remember them for later.

PHP Warning

I'm getting the warning

call_user_func_array() expects parameter 1 to be a valid callback, function 'bsg_nav_menu' not found or invalid function name

Menus are Disappearing

When I switch to this branch, my menus disappear.

@salcode
Copy link
Owner

salcode commented Mar 7, 2016

Looking at the Genesis code in lib/functions/menu.php, it looks like the filters genesis_do_nav and genesis_do_subnav are still in place for backwards compatibility. So instead it looks like we should be using the filter hooks that come from 'genesis_' . $sanitized_location . '_nav'.

@salcode
Copy link
Owner

salcode commented Mar 22, 2016

I believe the Bootstrap nav only supports a depth of 2.

So, I think we should change this value from 3 to 2.

$args['depth'] = 3;

salcode added a commit that referenced this pull request Mar 22, 2016
The Bootstrap nav has a maximum depth of 2.

See #136, #137
@bryanwillis
Copy link
Contributor Author

Sorry about that Sal. I added a third level to my menus a while back, but didn't include that code since it wasn't part of bootstrap core and I forgot to change it back when I proposed that change.

Anyway, for reference and for anyone who would like to use three level menus with this all you need to do is change the 2 to 3 and then drop this in your functions.php (technically these should be included using wp_enqueue_scripts so compiling within theme scripts/styles is preferred since the code is dependent on bs nav javascript and jquery).

add_action('wp_head', 'bsg_multilevel_dropdown_menu_css', 999);
function bsg_multilevel_dropdown_menu_css() {
    echo '<style>ul.dropdown-menu .caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-left:4px solid;border-right:4px solid transparent;border-top:4px solid transparent;border-bottom:4px solid transparent}@media (max-width:767px){ul.dropdown-menu .caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}}ul.dropdown-menu ul.dropdown-menu{top:0;left:100%}</style>';
}

add_action('wp_footer', 'bsg_multilevel_dropdown_menu_js', 999);
function bsg_multilevel_dropdown_menu(){
    echo '<script>!function(n){"use strict";n(function(){n("ul.dropdown-menu .dropdown>a").on("click",function(o){o.preventDefault(),o.stopPropagation();var t=n(this).parent();t.parent().find("li.dropdown").not(n(this).parent()).removeClass("open"),t.toggleClass("open")}),n("ul.navbar-nav a.dropdown-toggle").on("click",function(o){var t=n(this).parent();t.parent().find("li.dropdown").not(n(this).parent()).removeClass("open")})})}(jQuery);</script>'; 
}

And here's link to uncompressed js/css for those who want to include it other ways.
https://gist.github.com/bryanwillis/f4b5c25c4be8bd78d742

@salcode
Copy link
Owner

salcode commented Mar 22, 2016

@bryanwillis

Cool, thanks for sharing this.

@salcode
Copy link
Owner

salcode commented Apr 7, 2016

With this code change I am seeing some differences in the output nav code.

For Example

Old Output

<ul id="menu-testing-menu" class="nav navbar-nav"><li id="menu-item-1355" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1355"><a title="About" href="http://genesis.dev/about/" itemprop="url"><span itemprop="name">About</span></a></li>

New Output

<ul id="menu-testing-menu-1" class="nav navbar-nav"><li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1355"><a title="About" href="http://genesis.dev/about/" itemprop="url"><span itemprop="name">About</span></a></li>

Is this a problem?

I don't think these changes are a problem but I wanted to make note and look at them more deeply before merging. You can see the work I'm doing with this PR on the branch https://github.com/salcode/bootstrap-genesis/tree/nav-filters-to-genesis-hooks-137

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants