Last year I talked about how I made icons for my taxonomy terms. When you have a limited number of terms, that makes sense. When you have a taxonomy with the potential for a high volume of terms, like nations (192), or worse an unlimited number of terms, this approach looses its value.
Instead, I realized what I needed for a particular project was a custom icon for each taxonomy. Not the term.
I split this up into two files because I used a slightly different setup for my settings API, but the tl;dr of all this is I made a settings page under themes called “Taxonomy Icons” which loads all the public, non-default taxonomies and associates them with an icon.
For this to work for you, you will need to have your images in a folder and define that as your IMAGE_PATH in the code below. Also mine is using .svg files, so change that if you’re not.
File 1: taxonomy-icons.php
The one gotcha with this is I usually set my default values with $this->plugin_vars = array(); in the __construct function. You can’t do that with custom taxonomies, as they don’t exist yet.
class TaxonomyIcons {
private $settings;
const SETTINGS_KEY = 'taxicons_settings';
const IMAGE_PATH = '/path/to/your/images/';
/*
* Construct
*
* Actions to happen immediately
*/
public function __construct() {
add_action( 'admin_menu', array( $this, 'admin_menu' ) );
add_action( 'admin_init', array( $this, 'admin_init' ) );
add_action( 'init', array( $this, 'init' ) );
// Normally this array is all the default values
// Since we can't set it here, it's a placeholder
$this->plugin_vars = array();
// Create the list of imagess
$this->images_array = array();
foreach ( glob( static::IMAGE_PATH . '*.svg' ) as $file) {
$this->images_array[ basename($file, '.svg') ] = basename($file);
}
// Permissions needed to use this plugin
$this->plugin_permission = 'edit_posts';
// Menus and their titles
$this->plugin_menus = array(
'taxicons' => array(
'slug' => 'taxicons',
'submenu' => 'themes.php',
'display_name' => __ ( 'Taxonomy Icons', 'taxonomy-icons' ),
),
);
}
/**
* admin_init function.
*
* @access public
* @return void
* @since 0.1.0
*/
function admin_init() {
// Since we couldn't set it in _construct, we do it here
// Create a default (false) for all current taxonomies
$taxonomies = get_taxonomies( array( 'public' => true, '_builtin' => false ), 'names', 'and' );
if ( $taxonomies && empty( $this->plugin_vars ) ) {
foreach ( $taxonomies as $taxonomy ) {
$this->plugin_vars[$taxonomy] = false;
}
}
}
/**
* init function.
*
* @access public
* @return void
* @since 0.1.0
*/
function init() {
add_shortcode( 'taxonomy-icon', array( $this, 'shortcode' ) );
}
/**
* Get Settings
*
* @access public
* @param bool $force (default: false)
* @return settings array
* @since 0.1.0
*/
function get_settings( $force = false) {
if ( is_null( $this->settings ) || $force ) {
$this->settings = get_option( static::SETTINGS_KEY, $this->plugin_vars );
}
return $this->settings;
}
/**
* Get individual setting
*
* @access public
* @param mixed $key
* @return key value (if available)
* @since 0.1.0
*/
function get_setting( $key ) {
$this->get_settings();
if ( isset( $this->settings[$key] ) ) {
return $this->settings[$key];
} else {
return false;
}
}
/**
* Set setting from array
*
* @access public
* @param mixed $key
* @param mixed $value
* @return void
* @since 0.1.0
*/
function set_setting( $key, $value ) {
$this->settings[$key] = $value;
}
/**
* Save individual setting
*
* @access public
* @return void
* @since 0.1.0
*/
function save_settings() {
update_option( static::SETTINGS_KEY, $this->settings );
}
/**
* admin_menu function.
*
* @access public
* @return void
* @since 0.1.0
*/
function admin_menu() {
foreach ( $this->plugin_menus as $menu ) {
$hook_suffixes[ $menu['slug'] ] = add_submenu_page(
$menu['submenu'],
$menu['display_name'],
$menu['display_name'],
$this->plugin_permission,
$menu['slug'],
array( $this, 'render_page' )
);
}
foreach ( $hook_suffixes as $hook_suffix ) {
add_action( 'load-' . $hook_suffix , array( $this, 'plugin_load' ) );
}
}
/**
* Plugin Load
* Tells plugin to handle post requests
*
* @access public
* @return void
* @since 0.1.0
*/
function plugin_load() {
$this->handle_post_request();
}
/**
* Handle Post Requests
*
* This saves our settings
*
* @access public
* @return void
* @since 0.1.0
*/
function handle_post_request() {
if ( empty( $_POST['action'] ) || 'save' != $_POST['action'] || !current_user_can( 'edit_posts' ) ) return;
if ( !wp_verify_nonce( $_POST['_wpnonce'], 'taxicons-save-settings' ) ) die( 'Cheating, eh?' );
$this->get_settings();
$post_vars = $this->plugin_vars;
foreach ( $post_vars as $var => $default ) {
if ( !isset( $_POST[$var] ) ) continue;
$this->set_setting( $var, sanitize_text_field( $_POST[$var] ) );
}
$this->save_settings();
}
/**
* Render admin settings page
* If setup is not complete, display setup instead.
*
* @access public
* @return void
* @since 0.1.0
*/
function render_page() {
// Not sure why we'd ever end up here, but just in case
if ( empty( $_GET['page'] ) ) wp_die( 'Error, page cannot render.' );
$screen = get_current_screen();
$view = $screen->id;
$this->render_view( $view );
}
/**
* Render page view
*
* @access public
* @param mixed $view
* @param array $args ( default: array() )
* @return content based on the $view param
* @since 0.1.0
*/
function render_view( $view, $args = array() ) {
extract( $args );
include 'view-' . $view . '.php';
}
/**
* Render Taxicon
*
* This outputs the taxonomy icon associated with a specific taxonomy
*
* @access public
* @param mixed $taxonomy
* @return void
*/
public function render_taxicon ( $taxonomy ) {
// BAIL: If it's empty, or the taxonomy doesn't exist
if ( !$taxonomy || taxonomy_exists( $taxonomy ) == false ) return;
$filename = $this->get_setting( $taxonomy );
// BAIL: If the setting is false or otherwise empty
if ( $filename == false || !$filename || empty( $filename ) ) return;
$icon = file_get_contents( static::IMAGE_PATH . $filename . '.svg' );
$taxicon = '<span role="img" class="taxonomy-icon ' . $filename . '">' . $icon . '</span>';
echo $taxicon;
}
/*
* Shortcode
*
* Generate the Taxicon via shortcode
*
* @param array $atts Attributes for the shortcode
* - tax: The taxonomy
* @return SVG icon of awesomeness
*/
function shortcode( $atts ) {
return $this->render_taxicon( $atts[ 'tax' ] );
}
}
new TaxonomyIcons();
File 2: view-appearance_page_taxicons.php
Why that name? If you look at my render_view function, I pass the ID from get_current_screen() to it, and that means the ID is appearance_page_taxicons and that’s the page name.
<div class="wrap">
<h1><?php _e( 'Taxonomy Icons', 'taxonomy-icons' ); ?></h1>
<div>
<p><?php __( 'Taxonomy Icons allows you to assign an icon to a non-default taxonomy in order to make it look damn awesome.', 'taxonomy-icons' ); ?></p>
<p><?php __( 'By default, Taxonomy Icons don\'t display in your theme. In order to use them, you can use a shortcode or a function:' , 'taxonomy-icons' ); ?></p>
<ul>
<li>Shortcode: <code>[taxonomy-icon tax=TAXONOMY]</code></li>
</ul>
<form method="post">
<?php
if ( isset( $_GET['updated'] ) ) {
?>
<div class="notice notice-success is-dismissible"><p><?php _e( 'Settings saved.', 'taxonomy-icons' ); ?></p></div>
<?php
}
?>
<input type="hidden" name="action" value="save" />
<?php wp_nonce_field( 'taxicons-save-settings' ) ?>
<table class="form-table">
<tr>
<th scope="row"><?php _e( 'Category', 'taxonomy-icons' ); ?></th>
<th scope="row"><?php _e( 'Current Icon', 'taxonomy-icons' ); ?></th>
<th scope="row"><?php _e( 'Select Icon', 'taxonomy-icons' ); ?></th>
</tr>
<?php
foreach ( $this->plugin_vars as $taxonomy => $value ) {
?>
<tr>
<td>
<strong><?php echo get_taxonomy( $taxonomy )->label; ?></strong>
<br /><em><?php echo get_taxonomy( $taxonomy )->name; ?></em>
</td>
<td>
<?php
if ( $this->get_setting( $taxonomy ) && $this->get_setting( $taxonomy ) !== false ) {
echo $this->render_taxicon( $taxonomy );
}
?>
</td>
<td>
<select name="<?php echo $taxonomy; ?>" class="taxonomy-icon">
<option value="">-- <?php _e( 'Select an Icon', 'taxonomy-icons' ); ?> --</option>
<?php
foreach ( $this->images_array as $file => $name ) {
?><option value="<?php echo esc_attr( $file ); ?>" <?php echo $file == $this->get_setting( $taxonomy ) ? 'selected="selected"' : ''; ?>><?php echo esc_html( $name ); ?></option><?php
};
?>
</select>
</td>
</tr><?php
}
?>
<tr valign="top">
<td colspan="3">
<button type="submit" class="button button-primary"><?php _e( 'Save', 'taxonomy-icons' ); ?></button>
</td>
</tr>
</table>
</form>
</div>
</div>
End Result
And in the end?
![]()
By the way, the image has some wrong text, but that is what it looks like.


Comments
One response to “Taxonomy Icons”
… and Mika has deep knowledge about taxonomy. It was one of her strengths in Montessori. Happy Birthday Mika!!!!