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!!!!