When you’re making a plugin, sometimes you need a sidebar icon. And adding those in is relatively simple, depending on how you do it. But when you’re adding in something to the toolbar, things get a little messier…
Dashicons and the Admin Sidebar
The easiest way to add in an icon is to use a Dashicon – part of a set of icons developed by WordPress itself. These are designed to just work with WordPress, and you can include it in your call to add a menu page like so:
add_menu_page( 'HalfElf', 'HalfElf', 'manage_options', 'varnish-page', 'halfelf_settings_page', 'dashicons-carrot', 75 );
These will automatically change colors for you when people change their profile colors.
Dashicons and the Toolbar
But what if you want to add a menu to the toolbar? Well this is a little bit more complicated, due to the fact that there just isn’t a built in way to add that icon.
When you add in a toolbar menu, it looks like this:
add_action( 'admin_bar_menu', 'halfelf_add_admin_bar_menu', 999 ); function halfelf_add_admin_bar_menu( $wp_admin_bar ) { $args = array( 'id' => 'halfelf_add_admin_bar_menu', 'title' => 'HalfElf', 'href' => 'https://example.com', ); $wp_admin_bar->add_node( $args ); }
While I think the array should accept ‘icon’, it doesn’t, which means you have two choices to add in your icon:
1) Put <span class="dashicons dashicons-carron"></span>
in front of the ‘HalfElf’ on the title line
2) Use some CSS
Personally I pick option 2, because that will allow the icon to show when the screen is in mobile view, and all you see are the icons.
For that to work, I have the following custom CSS:
#wpadminbar #wp-admin-bar-purge-varnish-cache .ab-icon:before { content: '\f511'; top: 4px; } @media screen and (max-width: 782px) { #wpadminbar li#wp-admin-bar-purge-varnish-cache{ display: block!important; } }
I call it on the front and back end, and this works pretty well.
Adding a Custom SVG
But. What happens when your coworker doesn’t like your joke about the carrot? Well now we’re into the weird land of “I want to use a Custom SVG for my admin bar and my toolbar.” And this is strange because while you can just echo out the SVG, the color can be a bit of a mess. Unlike a font-icon, SVGs don’t always play nicely with the sidebar. You have to define their colors in order for the fill replacement to work, and even then I found out that it doesn’t go well with the toolbar!
I lifted a page from Yoast SEO, who uses a function get_icon_svg()
and calls it in place of 'dashicons-carrot'
, making my menu this:
add_menu_page( 'HalfElf', 'HalfElf', 'manage_options', 'varnish-page', 'halfelf_settings_page', get_icon_svg( true, '#82878c' ), 75 );
Yoasties, if you’re wondering why I have the extra variable, let me explain.
In their default, they have a one parameter, the true/false, and it defaults to true, so they just use get_icon_svg()
and call it a day. But I had cases where I wanted things to have specific colors, so I added in a parameter for the color. In addition, I put in some extra checks on how to determine the color based on what admin colors the user had selected:
function get_icon_svg( $base64 = true, $icon_color = false ) { global $_wp_admin_css_colors; $fill = ( false !== $icon_color )? sanitize_hex_color( $icon_color ) : '#82878c'; if ( is_admin() && false === $icon_color ) { $admin_colors = json_decode( json_encode( $_wp_admin_css_colors ), true ) ; $current_color = get_user_option( 'admin_color' ); $fill = $admin_colors[$current_color]['icon_colors']['base']; } $svg = '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="100%" height="100%" style="fill:' . $fill . '" viewBox="0 0 36.2 34.39" role="img" aria-hidden="true" focusable="false"><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path fill="' . $fill . '" d="M24.41,0H4L0,18.39H12.16v2a2,2,0,0,0,4.08,0v-2H24.1a8.8,8.8,0,0,1,4.09-1Z"/><path fill="' . $fill . '" d="M21.5,20.4H18.24a4,4,0,0,1-8.08,0v0H.2v8.68H19.61a9.15,9.15,0,0,1-.41-2.68A9,9,0,0,1,21.5,20.4Z"/><path fill="' . $fill . '" d="M28.7,33.85a7,7,0,1,1,7-7A7,7,0,0,1,28.7,33.85Zm-1.61-5.36h5V25.28H30.31v-3H27.09Z"/><path fill="' . $fill . '" d="M28.7,20.46a6.43,6.43,0,1,1-6.43,6.43,6.43,6.43,0,0,1,6.43-6.43M26.56,29h6.09V24.74H30.84V21.8H26.56V29m2.14-9.64a7.5,7.5,0,1,0,7.5,7.5,7.51,7.51,0,0,0-7.5-7.5ZM27.63,28V22.87h2.14v2.95h1.81V28Z"/></g></g></svg>'; if ( $base64 ) { return 'data:image/svg+xml;base64,' . base64_encode( $svg ); } return $svg; }
Personally I find it pretty crazy, and the icon on the toolbar doesn’t reflect the changes until the page is reloaded, but that’s a small price to pay since it doesn’t happen all that often.