I have just noticed that my menu items id are not getting generated by wordpress.
I expect it to be something like this
<li id='menu-item-2091' class='menu-item menu-item-209'>
<a href='www.mysite.com/members/<?php echo $user_info->user_login; ?>'>Profile</a></li>
but i get this without the menu item id.
<li class='menu-item menu-item-209'>
<a href='www.mysite.com/members/<?php echo $user_info->user_login; ?>'>Profile</a></li>
This error is occurring in my main menu, but my top menu seems to generate the menu item id properly.
I have looked around the menus area and can't find any clues why??
Here is a filter that hacks it out
add_filter ('wp_nav_menu_items','gfb_missing_id_fix', 10, 2);
function gfb_missing_id_fix($menu, $args) {
if($args->theme_location == "primary-menu"){
$dom = new DOMDocument;
$dom->loadHTML($menu);
foreach($dom->getElementsByTagName('li') as $element ) {
$classes = $element->getAttribute("class");
preg_match("/menu-item-\d+/", $classes, $output_array);
$element->setAttribute("id", $output_array[0]);
}
$menu = $dom->saveHTML();
}
return $menu;
}
General info
I use my navigation twice (mobile and desktop with different menu ids) and only the second menu is missing the item ids. This makes sense, because it secures that menu-item-ids are only used once.
JQuery Solution
For me the following javascript / jquery solution does the trick. It adds menu-id-ID (with ID as the actual menu-item-id) to each menu item.
var $mainMenu = $("#main-nav"); // your menu_id used in wp_nav_menu
$mainMenu.find("li").each(function(index, element) {
var $element = $(element);
var classes = $element.attr("class"),
ID = classes.match(/menu-item-(\d+)/)[1];
$element.attr("id", "menu-id-" + ID); // here 'menu-id-' is prepended to the actual ID
});
Related
I am using a wordpress registered menu to display an unordered list of product tags on my product archives page.
I would like to maintain the hierarchy of an unordered list if possible, however, I would like to grey out the list items that have no products associated with them so users are not led to a page with no products.
the unordered list looks like this after wordpress does its thing, so each anchor has a title that is equal to the tag name:
<ul id="menu-themes" class="menu">
<li>
<a href='#' title='fantasy'>Fantasy</a>
</li>
<li>
<a href='#' title='science'>Science</a>
<ul class='sub-menu'>
<li>
<a href='#' title='space'>Space</a>
</li>
</ul>
</li>
</ul>
I used a filter to change the href of each anchor to be appropriate. This is the filter I used in order to change this specific menu's anchor links:
function change_menu( $items, $args ){
if( $args->theme_location == "themes" ){
foreach($items as $item){
global $wp;
$current_url = home_url(add_query_arg(array(),$wp->request));
$item->url = $current_url . '/?product_tag=' . $item->title;
}
}
return $items;
}
add_filter('wp_nav_menu_objects', 'change_menu', 10, 2);
I have gotten a list of all the relevant tags to print out by using:
function woocommerce_product_loop_tags() {
global $post, $product;
echo $product->get_tags();
}
Now let's say for example, this above function only echo's space. Is there a way to filter the menu further to hide all the menu items that do not equal space?
I'm thinking it would be something like this:
function filter_menu_by_tags($items, $args){
//set scope of $product variable
global $product;
//this if statement makes sure only the themes menu is affected.
if( $args->theme_location == "themes"){
//loop through each menu item
foreach($items as $item){
if($item->title does not match any of the tags in $product->get_tags()){
//then add a special class to the list item or anchor tag
}
else{
//do nothing and let it print out normally.
}
}
}
}
$product->get_tags() returns an array of tags. You can use PHP in_array() function to check if your title is on the list:
function filter_menu_by_tags($items, $args){
//set scope of $product variable
global $product;
//this if statement makes sure only the themes menu is affected.
if( $args->theme_location == "themes"){
//loop through each menu item
foreach($items as $item){
if( !in_array($item->title, $product->get_tags()) ){
// Title is not in_array Tags
//then add a special class to the list item or anchor tag
}
else{
// Title is in_array Tags
//do nothing and let it print out normally.
}
}
}
}
I want to have 'Text only' in menu of my wordpress website without plugin.So how to set dynamic link to menu item in wordpress?
try this one
add_filter('wp_nav_menu_items', 'menu_link', 10, 2);
function menu_link($items, $args) {
if ($args->menu == 'footer'){
$items .= '<li class="copyright ">Text Only</li>';
$items .= '<li class="copyright ">Print Page</li>';
}
return $items;
// return $items1;
}
You will have to recreate the complete menu walker to make it text only, or remove the anchor through jquery. But if you just want a menu item that doesn't link anywhere, create a normal link menu item, and instead of an actual link use #.
I have a WordPress menu that has a few menu items I added through the standard (drag and drop) WordPress admin menu feature. Recently I had to add another item to the menu that generates a dynamic href link. I achieved that using the following code in my functions.php file:
//add my profile menu item dynmacially to the members menu (generate
user name based on current user logged in)
add_filter('wp_nav_menu_items','add_profilelink_in_menu', 10, 2);
function add_profilelink_in_menu( $items, $args ) {
if( $args->theme_location == 'secondary') {
global $current_user;
//converts user id to username
$user_info = get_userdata($current_user->ID);
$items .='<li id="menu-item-2091" class="menu-item menu-item-2091">
Profile
</li>';
}
return $items;
}
My problem is that this menu item is added to the end of the menu and the regular WordPress Menu classes such as 'current-menu-item' don't get applied to this item. Is there a way for me to control the position of where this menu item is added to (For example: add this item after the first two items?)
and how can I get WordPress to treat this dynamically generated menu item as a regular menu item and have it add all the classes that it adds the other menu items (created through the WordPress menu feature)?
Thanks for any help.
Here's the logic that you can base using jquery
//suppose your menu is this
<ul id="secondary_nav">
<li id="li_unique_id_1">menu 1</li>
<li id="li_unique_id_2">menu 2</li>
<li id="li_unique_id_4">menu 4</li>
</ul>
//the jquery workaround
//place this in your footer
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'></script>
<script type='text/javascript'>
$(function(){
<?php
global $current_user;
//converts user id to username
$user_info = get_userdata($current_user->ID);
?>
$("<li id='menu-item-2091' class='menu-item menu-item-209'><a href='https://www.mysite.com/members/<?php echo $user_info->user_login; ?>'>Profile</a></li>").insertAfter("#secondary_nav #li_unique_id_2");
});
</script>
You can also use insertBefore function
Did you check Wordpress menu option in the themes->menu for this ? You can easily add menu from there also you can set custom menu from there.Hope it will help you.
So after calling wp_nav_menu like:
<?php wp_nav_menu( array('menu' => 'Primary Menu' )); ?>
I end up with:
<li id="menu-item-1">
<li id="menu-item-2">
... ids like menu-item-1, menu-item-2, etc.
Is there some way to replace the numbers with the title of the page instead,so
menu-item-1 becomes menu-item-contact,
menu-item-2 becomes menu-item-store, etc?
You'll need to filter the ID using WordPress's nav_menu_item_id filter, which is applied in the nav-menu-template.php file. It takes three arguments, but the second one is what we need to actually get the title of the menu item, and turn it into something useful for the ID attribute. Here's a function to do that, which works for me in WordPress 3.4.1:
function custom_nav_menu_item_id($id, $item) {
$title = sanitize_title_with_dashes($item->title);
return 'menu-item-'.$title;
}
add_filter('nav_menu_item_id', 'custom_nav_menu_item_id', 10, 2);
This uses another WordPress function to sanitize the title into a string usable for the ID attribute (or any other HTML attribute).
Note that this function get's the menu item's title, which migth be different than the post or page title if you change it in the Menu panel from the admin.
Based on #Jeremy answer : I just add sanitize_title() to remove accents and special char.
function custom_nav_menu_item_id($id, $item) {
$title = sanitize_title_with_dashes(sanitize_title($item->title));
return 'menu-item-'.$title;
}
add_filter('nav_menu_item_id', 'custom_nav_menu_item_id', 10, 2);
/** for a better wp cleaning take a look # this gist and include it in your function.php */
I want to add a submenu of a wordpress menu into my theme. I want to use the wp_nav_menu function of Wordpress 3.0. And in other words, I want to see the submenu not the subpages which means that wp_list_pages is not the right function because I want the submenu and not the subpages.
Let's assume the menu structure looks like that:
Home
Entry1
Entry3
Entry4
Entry2
Entry5
Entry6
I want that if someone clicks on Entry1 (and makes it the parent) the Theme just shows the submenu of this entry. In the case of Entry1 it's:
Entry3
Entry4
I know that there is a code like that:
<?php
$children = ($post->post_parent) ? wp_list_pages('title_li=&child_of='.$post->post_parent.'&echo=0') : wp_list_pages('title_li=&child_of='.$post->ID.'&echo=0');
if($children) { echo('<ul>'.$children.'</ul>'); }
?>
However, the point is that I'm talking about the menu structure and not the page structure. Oh, and the depth parameter does not work because it means to here and not from here.
I think there could be a solution with a custom walker but I don't know how to implement that.
Function reference for wp_nav_menu
http://codex.wordpress.org/Template_Tags/wp_nav_menu
I'm looking for a solution for this problem for so long so please help me. Thanks a lot.
In order to get this to work I had to hide the .sub-menu as soon as the page loaded. Then, show only the relevant sub-menu by targeting ".current_page_item .sub-menu"
$(document).ready(function() {
$(".sub-menu").hide(); // hide the submenu on page load
$(".current_page_item .sub-menu").show();
)};
This should help: From http://www.svennerberg.com/2009/02/creating-a-submenu-in-wordpress/
<?php
$has_subpages = false;
// Check to see if the current page has any subpages
$children = wp_list_pages('&child_of='.$post->ID.'&echo=0');
if($children) {
$has_subpages = true;
}
// Reseting $children
$children = "";
// Fetching the right thing depending on if we're on a subpage or on a parent page (that has subpages)
if(is_page() && $post->post_parent) {
// This is a subpage
$children = wp_list_pages("title_li=&include=".$post->post_parent ."&echo=0");
$children .= wp_list_pages("title_li=&child_of=".$post->post_parent ."&echo=0");
} else if($has_subpages) {
// This is a parent page that have subpages
$children = wp_list_pages("title_li=&include=".$post->ID ."&echo=0");
$children .= wp_list_pages("title_li=&child_of=".$post->ID ."&echo=0");
}
?>
<?php // Check to see if we have anything to output ?>
<?php if ($children) { ?>
<ul class="submenu">
<?php echo $children; ?>
</ul>
<?php } ?>
One solution is to put another wp_nav_menu function on page and to modify css to hide inactive menu items.