0

I am adding a #section as a custom link to my menu, because I want to scroll to that section when I click on that link. When I'm on the home page, this works fine (the section is on the home page), but when I'm not, and I click on it nothing happens, because it treats the link as just #section.

That is, when I'm on second page:

http://127.0.0.1/second-page

and I click on the #section link in the menu, it tries to do

http://127.0.0.1/second-page/#section

instead of

http://127.0.0.1/#section

Now, the site is still in development, so it's set via IP address. But that shouldn't matter. The issue is that I've tried to set the custom link in the wordpress backend as

http://127.0.0.1/#section

and while in the backend this looks like that, on my menu on the front end I only see

<a href="#section">Section</a>

The menu walker that controls the menu output looks like this:

<?php


// Allow HTML descriptions in WordPress Menu
remove_filter( 'nav_menu_description', 'strip_tags' );
function my_plugin_wp_setup_nav_menu_item( $menu_item ) {
    if ( isset( $menu_item->post_type ) ) {
        if ( 'nav_menu_item' == $menu_item->post_type ) {
            $menu_item->description = apply_filters( 'nav_menu_description', $menu_item->post_content );
        }
    }

    return $menu_item;
}

add_filter( 'wp_setup_nav_menu_item', 'my_plugin_wp_setup_nav_menu_item' );

// Menu without icons
class my_walker_nav_menu extends Walker_Nav_Menu {

    public function display_element($el, &$children, $max_depth, $depth = 0, $args, &$output){
        $id = $this->db_fields['id'];

        if(isset($children[$el->$id])){
            $el->classes[] = 'has_children';
        }

        parent::display_element($el, $children, $max_depth, $depth, $args, $output);
    }

    // add classes to ul sub-menus
    function start_lvl( &$output, $depth = 0, $args = array() ) {
        // depth dependent classes
        $indent = ( $depth > 0  ? str_repeat( "\t", $depth ) : '' ); // code indent
        $display_depth = ( $depth + 1); // because it counts the first submenu as 0
        $classes = array(
            'navi',
            ( $display_depth ==1 ? 'first' : '' ),
            ( $display_depth >=2 ? 'navi' : '' ),
            'menu-depth-' . $display_depth
            );
        $class_names = implode( ' ', $classes );

        // build html
        $output .= "\n" . $indent . '<ul class="' . esc_attr($class_names) . '">' . "\n";
    }

    // add main/sub classes to li's and links
     function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
        global $wp_query;
        $indent = ( $depth > 0 ? str_repeat( "\t", $depth ) : '' ); // code indent

        static $is_first;
        $is_first++;
        // depth dependent classes
        $depth_classes = array(
            ( $depth == 0 ? 'main-menu-item' : '' ),
            ( $depth >=2 ? 'navi' : '' ),
            ( $is_first ==1 ? 'menu-first' : '' ),
            'menu-item-depth-' . $depth
        );
        $depth_class_names = esc_attr( implode( ' ', $depth_classes ) );
        // passed classes
        $classes = empty( $item->classes ) ? array() : (array) $item->classes;
        $class_names = esc_attr( implode( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) ) );

        $is_mega_menu = (strpos($class_names,'mega') !== false) ? true : false;
        $use_desc = (strpos($class_names,'use_desc') !== false) ? true : false;
        $no_title = (strpos($class_names,'no_title') !== false) ? true : false;

        if(!$is_mega_menu){
            $class_names .= ' normal_menu_item';
        }

        // build html
        $output      .= $indent . '<li id="nav-menu-item-'. esc_attr($item->ID) . '" class="' . esc_attr($depth_class_names) . ' ' . esc_attr($class_names) . '">';
        // link attributes
        $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
        $attributes  .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
        $attributes  .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
        $attributes  .= ! empty( $item->url )        ? ' href="' . (($item->url[0] == "#" && !is_front_page()) ? home_url('/') : '') . esc_attr($item->url) .'"' : '';

        $attributes  .= ' class="menu-link '.((strpos($item->url,'#') === false) ? '' : 'scroll').' ' . ( $depth > 0 ? 'sub-menu-link' : 'main-menu-link' ) . '"';

        $html_output = ($use_desc) ? '<div class="description_menu_item">'.$item->description.'</div>' : '';
        $item_output = (!$no_title) ? '<a ' . $attributes . '><span>' . apply_filters( 'the_title', $item->title, $item->ID ) . '</span></a>'.$html_output : $html_output;
        // build html
        $output      .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args ).(($is_mega_menu)?'<div class="sf-mega"><div class="sf-mega-inner clearfix">':'');
    }

    function end_el( &$output, $item, $depth = 0, $args = array() ) {

        $classes      = empty( $item->classes ) ? array() : (array) $item->classes;
        $class_names  = esc_attr( implode( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) ) );

        $is_mega_menu = (strpos($class_names,'mega') !== false) ? true : false;

        $output       .= (($is_mega_menu)?'</div></div>':'') . "</li>\n";
    }

}

The anchor is controlled with this line:

$attributes  .= ! empty( $item->url )        ? ' href="' . (($item->url[0] == "#" && !is_front_page()) ? home_url('/') : '') . esc_attr($item->url) .'"' : '';

It even says that if the url has # in it, and if it's not front page, that it should add a home_url() to it.

Without this I cannot scroll to the section on the first page from other pages.

Why is it doing this? Because the address is IP instead of www?

ANSWER

Apparently I didn't call the walker instance in my wp_nav_menu(). feels dumb

It works now. Sorry for not checking this sooner.

0

This is what you have to do:

Change the <a href="#section"></a> to <a href="http://127.0.0.1/#section"></a>

From what i understand home is http://127.0.0.1 and on home #section is located not on http://127.0.0.1/second-page

so from http://127.0.0.1/second-page you have to go back to http://127.0.0.1 that goes straight to #section that is located on http://127.0.0.1

That should do the trick

| improve this answer | |
  • I know I need to add that, but it's not happening, that's my issue. I don't know why it doesn't output <a href="http://127.0.0.1/#section"></a> when it should. – dingo_d Mar 2 '16 at 11:31
  • Than it's this problem: you have to get a domain name. buy that and link the ip adress to that domain. that should solve the problem. – Dionoh Mar 2 '16 at 12:27
0

I can't comment yet so I'm sorry if this is not valid as an answer but from what I'm understanding your $item->url is in this case "#section"

You're checking if $item->url[0] equals # but $item->url is not an array so [0] isn't valid here.

Can you pleae try to replace this line

$attributes  .= ! empty( $item->url )        ? ' href="' . (($item->url[0] == "#" && !is_front_page()) ? home_url('/') : '') . esc_attr($item->url) .'"' : '';

to

$attributes  .= ! empty( $item->url )        ? ' href="' . ((strpos($item->url, '#') != false && !is_front_page()) ? home_url('/') : '') . esc_attr($item->url) .'"' : '';
| improve this answer | |
  • Sadly this didn't do it :\ – dingo_d Mar 2 '16 at 11:30
  • It's a bit difficult to test working code because I don't have a similar piece of code running somewhere. Ignore the fact that these if/else statements aren't shorthand but it's much easier to look where stuff might be going wrong this way. Could you try the following statement instead of that line of code? if ( ! empty( $item->url ) ) { if ( strpos( $item->url, '#' ) && ! is_front_page() ) { $attributes .= ' href="' . esc_url( home_url( '/' ) . esc_attr( $item->url ) ) . '"'; } else { $attributes .= ' href="' . esc_url( esc_attr( $item->url ) ) . '"'; } $url = 'href="#section"'; } – Jeffrey von Grumbkow Mar 2 '16 at 11:44
  • I've found out the issue. I didn't initialize my walker in the first place xD But thanks for helping :) – dingo_d Mar 2 '16 at 11:47
  • That's funny :P – Jeffrey von Grumbkow Mar 2 '16 at 12:06
0

When on the same page the link should be relative: #section

When on a different page, the link should be absolute: http://127.0.0.1/#section

You just need to add an if statement in your menu walker to accomplish that behavior.

| improve this answer | |
  • I know that it doesn't do that, and there is an if statement that should do that, but doesn't do that... – dingo_d Mar 2 '16 at 11:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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