2

I create a single page website and use only anchors (#) on main menu items.

Now, I need to include a second page on the website and keep the same menu.

I'm using roots theme. Then, I'm building menu using:

wp_nav_menu(array('theme_location' => 'primary_navigation')); 

But how to change items url from, for example, #contact to mywebsite.com.br/#contact only on this second page?

2
  • 1
    Please show some code. How are you building your links? Manually? Using a custom function? Using wp_nav_menu?
    – gdaniel
    Mar 12, 2014 at 15:54
  • First, I'm using roots theme. Then, I'm building menu using wp_nav_menu(array('theme_location' => 'primary_navigation')); Mar 12, 2014 at 15:56

3 Answers 3

6

In your template you can check whether you're on the front-page or not and then echo out a different menu.

For example:

if(is_front_page() || is_home()){

 wp_nav_menu(array('theme_location' => 'primary_navigation'));

}else{

 wp_nav_menu(array('theme_location' => 'secondary_navigation'));

}

You would also have to register a second menu locations in the functions.php file (if it hasn't been done yet).

To register a new menu location:

function register_my_menus() {

    register_nav_menus(array( 
        'secondary-location' => __('Secondary Location'),
    ));

}

add_action( 'init', 'register_my_menus' );

The downside is that you would have to manage two menus in the backend. That could be a problem if the menu changes often, because you would have to update two menus.

Instead, you could filter the wp_nav_menu and alter the url before the menu is printed. For example, this would go in functions.php

function change_menu($items){

if(!is_front_page()){

  foreach($items as $item){


    $item->url = get_bloginfo("url") . "/" .  $item->url;


  }

}

  return $items;

}

add_filter('wp_nav_menu_objects', 'change_menu');

the code above filters the wp_nav_menu_object. It adds the full url if you're not on the front-page of the website. Otherwise it just returns the regular menu. Using this method you would not have to create a second menu in the admin.

3
  • Thanks. So, using wp_nav_menu I can't add a string to URL? Mar 12, 2014 at 16:41
  • I just updated my answer. You can use a filter to modify the url before it's printed.
    – gdaniel
    Mar 12, 2014 at 16:43
  • That is so helpful, even for my completely different needs, thank you @gdaniel!
    – physalis
    Nov 24, 2014 at 22:27
3

If your menu contains custom anchor-links AND page-links (e.g. to that second page, home, imprint or whatever) gdaniels change_menu function will break those page-links when you're not on the front page. That's the problem boywonder was experiencing as the 'change_menu' function prepends the site-url to all menu-links. But with boywonders function 'lb_menu_anchors' you'll end up with page refreshes on the front-page when switching between anchor-links. To avoid this, lb_menu_anchors must only be executed when the current page is not the front page:

function lb_menu_anchors($items, $args) {
// current page is NOT front page?
  if(!is_front_page()){
    // loop through menu-objects (the links)
    foreach ($items as $key => $item) {
        // check if link begins with '#'
        if ($item->object == 'custom' && substr($item->url, 0, 1) == '#') {
            // if so, prepend site_url to link
            $item->url = site_url() . $item->url ;
        }
    }
    // return edited links
    return $items;
  }
  else {
    // return unedited links if current page IS front page
    return $items;
  }
  }

add_filter('wp_nav_menu_objects', 'lb_menu_anchors', 10, 2);

Thanks for all your thoughts

2

I'd been using a modified version of gdaniel's solution, but recently ran into an issue where, when using custom menu links to point menu items to external links, the site URL was prepended to the external link.

The code below should work if you need to modify anchor links and not modify external links.

function lb_menu_anchors($items, $args) {
    foreach ($items as $key => $item) {
        if ($item->object == 'custom' && substr($item->url, 0, 1) == '#') {
            $item->url = site_url() . $item->url;
        }
    }

    return $items;
}
add_filter('wp_nav_menu_objects', 'lb_menu_anchors', 10, 2);

All props go to laubsterboy and faye: https://laubsterboy.com/blog/2014/09/wordpress-menu-anchor/ https://laubsterboy.com/blog/2014/09/wordpress-menu-anchor/#comment-35170

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.