Taxonomy Page Parent Menu Collapsed

WordPress allows you to create your own menus in the admin area, to do this you can use the function add_menu_page().

<?php
add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position );
?>

When this menu item is in place you are also able to add sub-menu items to the page that can be used to make your own custom option pages under this menu by using the function add_submenu_page().

<?php add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function ); ?>

Using the submenu page you can add any URL you want to the menu items anything from a settings page, link to the front-end, link to a custom post types, link to custom taxonomy.

If you were to add a custom taxonomy edit tags page /wp-admin/edit-tags.php?taxonomy=category to the menu you will see different behaviour with the menus then with other submenu pages.

When you add a sub-menu page WordPress will automatically expand the parent menu item to visually show where in the hierarchy you currently are. But with a custom taxonomy page WordPress will not understand it's parent item in the menu and will collapse the menu item.

Using the below snippet you can add a new Javascript file to the page to check to see if the top level menu item is open on a certain page, if it's not then we add the CSS class to expand the menu item.

add_action('admin_head', 'pu_set_open_menu');

/**
 * Open the correct menu for taxonomy
 */
public function pu_set_open_menu()
{
    $screen = get_current_screen();
    if( $screen->base === 'edit-tags' && $screen->taxonomy === 'taxonomy_type_name' )
    {
        wp_enqueue_script( 'open-menu-parent', plugins_url('../assets/js/admin-menu.js', __FILE__ ), array('jquery') );
    }
}

As you can see from the code above we can discover what page we are on by using the get_current_screen() function, this allows us to get the base page and check the taxonomy type to make sure we're on the right page before adding the Javascript file.

(function ( $ ) {
    // Close all the other parent menus
    $('.wp-has-current-submenu').removeClass('wp-has-current-submenu');

    // Open your specific parent menu
    $('.toplevel_page_top-menu-level-item')
        .removeClass('wp-not-current-submenu')
        .addClass('wp-has-current-submenu wp-menu-open');

}(jQuery));

In this tutorial we are going to look at how we can programmatically set a menu to a menu location. In WordPress you assign a menu to a location by going to the menu page in the admin area and click on manage locations this will take you to the page /wp-admin/nav-menus.php?action=locations.

From here you will see a list of all the locations assigned to your theme with a dropdown where you can choose what menu you want to assign to the location.

An example of when you will need to programmatically set this is on a plugin activation you create a number of new menus based on user role and want to assign these to a menu location. First this will need to get a list of menu locations, get a list of menus and assign the menu ID to the location.

Get All Menu Locations

First we need to get a list of all the registered menu locations in your WordPress theme to do this we can use the get_theme_mod() function, passing in the parameter of nav_menu_locations.

$locations = get_theme_mod( 'nav_menu_locations' );

This returns an array of key value pairs for the locations, the key being the ID of the menu location and the value is the menu term ID that is used in this location, so to change the menu in this location we need to replace the value.

Change Menu Assigned To Location

Once we get the menu locations we can then loop through these locations and get the menu that we want to add to the menu, all we have to do is assign the menu term ID to the location array.

When we have changed the locations we then set these in the theme by using the function set_theme_mod() passing in the parameter of nav_menu_locations.

$locations = get_theme_mod( 'nav_menu_locations' );

if(!empty($locations))
{
    foreach($locations as $locationId => $menuValue)
    {
        switch($locationId)
        {
            case 'admin-menu-location':
                $menu = get_term_by('name', 'Admin Menu', 'nav_menu');
            break;

            case 'author-menu-location':
                $menu = get_term_by('name', 'Author Menu', 'nav_menu');
            break;

            case 'subscriber-menu-location':
                $menu = get_term_by('name', 'Default Menu', 'nav_menu');
            break;
        }

        if(isset($menu))
        {
            $locations[$locationId] = $menu->term_id;
        }
    }

    set_theme_mod('nav_menu_locations', $locations);
}

The in-built WordPress menu system allows the content author to create a menu by a simple drag n drop interface, it allows you to select existing posts, page or let you create custom links to add to the menu.

Using the drag n drop interface you can select child elements on the menu.

When you output the menu on your theme using the function wp_nav_menu() WordPress will automatically create the HTML for the menu and the sub-menu on your theme allowing you to easily create a menu link this.

  • Parent 1
  • Parent 2
    • Child 1
    • Child 2
  • Parent 3
    • Child A
    • Child B

When WordPress automatically creates the HTML for you it will also add the CSS classes that you can use in your theme, something similar to below.

<ul id="navbar-1" class="menu">
    <li id="menu-item-1" class="menu-item menu-item-type-post_type menu-item-object-page firstmenuitem"><a href="">Parent 1</a></li>
    <li id="menu-item-2" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children"><a href="">Parent 2</a>
    <ul class="sub-menu">
        <li id="menu-item-3" class="menu-item menu-item-type-post_type menu-item-object-page"><a href="">Child 1</a></li>
        <li id="menu-item-4" class="menu-item menu-item-type-post_type menu-item-object-page"><a href="">Child 2</a></li>
        <li id="menu-item-5" class="menu-item menu-item-type-post_type menu-item-object-page"><a href="">Child 3</a></li>
    </ul>
    </li>
    <li id="menu-item-6" class="menu-item menu-item-type-post_type menu-item-object-page"><a href="">Parent 3</a></li>
    <li id="menu-item-7" class="menu-item menu-item-type-post_type menu-item-object-page"><a href="">Parent 4</a></li>
</ul>

In this example we want the Child sub-menu to be display when you are on the Parent 2 page and hidden on all the other pages. Because of the automatic CSS classes that are added to WordPress we can simply use CSS to make sure the menu is hidden on all pages apart from the Parent page.

First we need to hide the sub-menu on all pages.

.menu .sub-menu 
{ 
    display: none; 
}

When WordPress is on a page that is on the menu it will add a new CSS class to the parent item called current-menu-item. We can then use this class to display the sub-menu when you are on the correct page.

.menu .current-menu-item .sub-menu 
{ 
    display:block; 
}

.menu .current-menu-ancestor .sub-menu 
{ 
    display:block; 
}

In WordPress 3.8 the core had a change to all icons, they now use Dashicons which are fonts that mean you can display an icon by simply adding a CSS class. This can change a few things in the admin area of your application, for example when adding menus to the admin area you might need to change the icon to use a CSS class. If you have created any new admin pages you might need to change the way the icon at the top of the page is displayed to use the new CSS classes.

Dashicons

This is an open source project that you can download the latest version from Github.

Dashicons

WordPress will get the latest version of this and include it in the release.

To understand how you can use these in your projects you can have a look at the documentation of Dashicons.

dashicons

Dashicons Documentation

Menu Item Dashicons

There are a few times when you are going to need to use these for new menu items, this will either be when adding a new menu in the admin area or by creating new post types.

When you are creating the new post type you will use the function register_post_type( $post_type, $args ).

One of the arguments is menu_icon which will be where you can specify the dashicon CSS class to use for the menu.

function custom_init() {
    $args = array(
      'public' => true,
      'label'  => 'Products',
      'menu_icon' => 'dashicons-format-audio'    // Displays a music note icon
    );
    register_post_type( 'products', $args );
}
add_action( 'init', 'custom_init' );

Inside the menu_icon argument you can replace this with any of the CSS classes found on the dashicons documentation. If you want to use your own menu icons then you can provide the absolute path to the icon you want to use.

Add Menu Item

The other time when you will need to define the menu icon you want to use is by using the WordPress function add_menu_page().

<?php add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position ); ?>

As you can see from the above parameters is the 6th parameter is for icon_url which will allow you to change what icon you want to use on the menu. The default will be the Gear icon that is used by all new menu items but you can change this to be anything you want.

To change the icon to a question mark you need to use the CSS class dashicons-editor-help.

<?php add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, 'dashicons-editor-help', $position ); ?>

Added In WordPress 3.9

If you have recently upgraded to WordPress 3.9 then you will now have extra dashicons available to use on your WordPress website.

- dashicons-media-archive - dashicons-media-audio - dashicons-media-code - dashicons-media-default - dashicons-media-document - dashicons-media-interactive - dashicons-media-spreadsheet - dashicons-media-text - dashicons-media-video - dashicons-playlist-audio - dashicons-playlist-video

To see more of the new dashicons you can see them on the WordPress blog.

WordPress 3.9 Dashicons

The following code snippet will allow you to style a specific menu item differently to the other items.

When WordPress creates a menu it will use the menus setup in the WordPress admin, this interface gives the user full flexibility of the what items go in the menu and where they are positioned in the theme.

WordPress will automatically add ID's and Classes to these menus so that you can style them in your theme stylesheet. There are different ways that you can style a specific menu item, WordPress will add an ID to the list item of the menu, so you can use this in your stylesheet. But the problem with this is that it will use the ID of the database, so if your working over different development environments or if this menu item is deleted and re-added the ID's will be different.

A better solution will be to run off the title of the menu item, for example if you have a navigation bar and would want to style the home page link different to the other pages then you can use the following code.

add_filter('nav_menu_css_class' , 'conditional_nav_menu_class' , 10 , 2);
function conditional_nav_menu_class($classes, $item){
     if( strtolower($item->title) == "home" ){ 
             $classes[] = "home-icon";
     }
     return $classes;
}

This code uses the filter nav_menu_css_class which will allow you to change the the classes that are added to the menu items. Because there are a number of classes that are added we need to return an array of CSS classes to go onto the menu item.

To add the extra CSS class we just need to check that the menu item title equals home, then we can add a CSS class of home-icon to the classes array.

WordPress comes with a default menu system which gives full control to the admin user of the site to change or create as many menu items as you want.

To access the menu system in the admin area you just need to go to Appearance -> Menu. From this screen you will be able to see all the menus that currently exist on your WordPress site, you can select any of these menus and change the menu items to anything you want. You can even create new menus and add these to different theme locations.

You can add any links you want, WordPress has a list on the left side of the page, that will display all the pages that are created on your site. If you have custom post types you can make these posts appear in the menu list if the option show_in_nav_menus is set to true.

With all the control that the user has on the menu system you would think that you will never need to change the menu items in the code. But there are occasions when you need to programmatically add or change menu items in a given menu.

The main times you will need to do this is to add a login or logout buttons to the navigation, this will most likely be on the main site navigation. If the current user is logged in you want to add a log out button and if they're logged out then you need to add a login button.

To do this we use the wp_nav_menu_items filter which will run after WordPress has created the HTML to print the menu on the screen. This gives us access to all the items that will be used, this means that we can simply add a new menu item to the end of the list with the links that we need.

add_filter( 'wp_nav_menu_items', 'add_logout_link', 10, 2);

/**
 * Add a login link to the members navigation
 */
function add_logout_link( $items, $args )
{
    if($args->theme_location == 'site_navigation')
    {
        if(is_user_logged_in())
        {
            $items .= '<li><a href="'. wp_logout_url() .'">Log Out</a></li>';
        } else {
            $items .= '<li><a href="'. wp_login_url() .'">Log In</a></li>';
        }
    }

    return $items;
}

In WordPress the user can create their own menus in the CMS area by just going to Appearance -> Menus.

From this page you can then assign these menus to locations in the theme by choosing the theme location for the menu. These theme locations are setup by the theme developer and is done by using the function register_nav_menus();

The register nav menu function can be placed in the functions.php file.

register_nav_menus( array(
	'header_menu' => 'Header Menu',
	'footer_menu' => 'Footer Menu'
) );

When you navigate to the theme menu location page you will see two new theme locations for the header menu and the footer menu.

menu-locations

By default these menu locations won't have a menu assigned to them, when the user creates new menus they will need to assign them to the menu locations.

To display these menus in the correct theme location you will need to place the function wp_nav_menu() in your theme in the position you want the menu to be displayed.

<?php

$defaults = array(
	'theme_location'  => '',
	'menu'            => '',
	'container'       => 'div',
	'container_class' => '',
	'container_id'    => '',
	'menu_class'      => 'menu',
	'menu_id'         => '',
	'echo'            => true,
	'fallback_cb'     => 'wp_page_menu',
	'before'          => '',
	'after'           => '',
	'link_before'     => '',
	'link_after'      => '',
	'items_wrap'      => '<ul id="%1$s" class="%2$s">%3$s</ul>',
	'depth'           => 0,
	'walker'          => ''
);

wp_nav_menu( $defaults );

?>

As you can see the first argument you can pass through the theme_location ID, this is how WordPress will know what menu to display in this location. If a menu isn't assigned to this theme location then WordPress will display links to all the pages created in your WordPress site.

If you are creating a theme for a client this can be quite confusing to the user when they first see the menu with pages on there. To make sure that the menu is not displayed until the menu location has a menu assigned, you can use the WordPress function of has_nav_menu( $location ).

This takes one parameter of the theme menu location ID, if a menu has been assigned then you can display the navigation menu.

if ( has_nav_menu( 'header_menu' ) ) {
     wp_nav_menu( array('theme_location' => 'header_menu') );
}

Changing Fallback Function

Another option to remove the page menu if the menu doesn't exist is to change the fallback property. By default the fallback function is set to wp_page_menu, changing this to false will make sure that no menu is returned.

wp_nav_menu( array('theme_location' => 'header_menu', 'fallback_cb' => false) );

The problem with having a multi-author blog is that you have a lot of users which have access to the admin area of your WordPress site.

When they have access to your admin site they have access to change everything about your blog.

Yes you can use your access roles and set the different capabilities, but what if you have multiple admin users but you only want the super admin user to be admin to change theme or plugins.

You need a way of blocking access to the themes area. You can block access to the themes screen to anyone apart from the super admin user. Below is the snippet to check the user ID and remove the themes item from the menu. Read more...

If you are a plugin or theme developer then you will get to the stage where you need to add a link to your plugin or theme settings page in your WordPress admin area.

The settings page will allow you your user to customise the plugin or theme in anyway they want. There are different ways you can add links to your plugin or theme settings page. Some people like to put links to the theme settings under the appearance tab, some people prefer to create a brand new menu item in the WordPress admin area just for your theme.

If you are creating a theme I think it's better to add your link to your theme settings page under your appearance tag. This is because a theme is used for the appearance of your site and all the settings should be under the appearance tab. Read more...

Creating a WordPress theme can be lots of work, but the basic HTML for themes are normally quite similar. Each theme will have a way of looping through a list of posts to show the most recent posts, or to display all the posts in a category.

The HTML to display a single post inside the single.php will mainly be the same on any theme you have the header for the title, the date for the post, the main content and then the comments section.

The thing that makes each WordPress theme different is the CSS, this will decide how the theme looks and feels. Because wordpress has functions to add in CSS to your theme you need to know what these CSS classes are so you can style your theme. In this article we are going to a have a look at the CSS classes you will find inside a WordPress theme.

You should be able to take the CSS in this article and use it as a starting point for your next WordPress theme. Read more...