最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

multisite - WP Nav menu append to url

programmeradmin0浏览0评论

Using wp_nav_menu() , how can I append a value at end of each URL?
For example, I have the following url: / but I have to append a language parameter at the end, so the url should be: /?lang=$language

Using wp_nav_menu() , how can I append a value at end of each URL?
For example, I have the following url: http://www.example/ but I have to append a language parameter at the end, so the url should be: http://www.example/?lang=$language

Share Improve this question edited Feb 17, 2013 at 10:54 Lea Cohen 1,6503 gold badges22 silver badges45 bronze badges asked Feb 17, 2013 at 7:40 M Khalid JunaidM Khalid Junaid 3292 silver badges13 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 3

You can either use a whole custom Walker - see codex or just a filter call to walker_nav_menu_start_el to regenerate link.

In case of filter, your code in theme's functions.php would look like this:

add_filter( 'walker_nav_menu_start_el', 'my_language_link_function', 10, 4 );

function my_language_link_function( $item_output, $item, $depth, $args ){
    $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

    $class_names = $value = '';

    $classes = empty( $item->classes ) ? array() : (array) $item->classes;
    $classes[] = 'menu-item-' . $item->ID;

    $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
    $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';

    $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
    $id = $id ? ' id="' . esc_attr( $id ) . '"' : '';

    $output .= $indent . '<li' . $id . $value . $class_names .'>';

    $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        ) .'"' : '';
    //Your code generationg lang parameter goes here:
    $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';

    $item_output = $args->before;
    $item_output .= '<a'. $attributes .'>';
    $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
    $item_output .= '</a>';
    $item_output .= $args->after;
    return $item_output;
}

This code is a copy of start_el function of Walker_Nav_Menu class, which you can find in wp-includes/nav-menu-template.php - see it's code.

I found the solution modifying the behaviour of wp_nav_menu with the wp_get_nav_menu_items-filter. Here's a somewhat complete example:

class ModifyLinkFilter {
protected $_prio = 10;
protected $_args;

public function __construct($addargs = array(), $prio = 10) {
    $this->_args = $addargs;
    $this->_prio = $prio;

    if(!empty($addargs)) {
        $this->register();
    }
}

public function register() {
    add_filter('wp_get_nav_menu_items',
        array($this, 'on_nav_items'), $this->_prio, 3);
}

public function unregister() {
    remove_filter('wp_get_nav_menu_items',
        array($this, 'on_nav_items'), $this->_prio, 3);
}

public function on_nav_items($items, $menu, $args) {
    foreach($items as $item) {
        if(!empty($item->url)) {
            $item->url = self::modifyUrlSimple($item->url, $this->_args);
        }
    }
    return $items;
}

public static function modifyUrlSimple($url, $query) {
    $url .= strchr($url, '?') === false ? '?' : '&';
    $url .= http_build_query($query);
    return $url;
}
}


// You can use the class like that
$language = "de";
$args = array('lang' => $language, 'foo' => 'bar');
$linkfilter = new ModifyLinkFilter($args); 
wp_nav_menu();
$linkfilter->unregister();    

This modifies every item in the navigation menu. So if you have an external link, it will be changed as well.

Plus, modifying the URL is not as easy as it seems. The URL of an item can be /blabla?myvalue=5#anchor which would look like /blabla?myvalue=5#anchor&lang=de&foo=bar after the modification.

Here is an example if someone needs to achieve this with javascript & jQuery:

$('.menu-item).each(function () {
    currentHref = $(this).attr('href');
    var jsUrlObj = new URL(currentHref);
    jsUrlObj.searchParams.append('lang', 'en')
    $(this).attr('href', jsUrlObj);
})

For more info: URLSearchParams.append()

发布评论

评论列表(0)

  1. 暂无评论