Taxonomy Metadata Without a Plugin

I have already written about metaboxes for posts (pages and custom post types). Let’s find out now how to add additional setting fields on category and tag edit screen (and also for custom taxonomies). Step 1. Create a Database Table The first thing you should now, that WordPress doesn’t have a place in database where […]

May 18, 2015 / #wp-admin

I have already written about metaboxes for posts (pages and custom post types). Let’s find out now how to add additional setting fields on category and tag edit screen (and also for custom taxonomies).

Step 1. Create a Database Table

The first thing you should now, that WordPress doesn’t have a place in database where it can store taxonomy metadata by default.

Okay, we will create that table now. There to ways to do it:

  1. In phpMyAdmin.
  2. SQL query.

We will go the second way and create the table by inserting the code into functions.php.

global $pagenow, $wpdb; // we need $wpdb always when working with Wordpress database
if ( is_admin() && isset($_GET['activated'] ) && $pagenow == "themes.php" ) { // this code runs only once when theme 
	$db_collation = '';
	if($wpdb->has_cap('collation')) { 
		if(!empty($wpdb->charset)) $db_collation = "DEFAULT CHARACTER SET $wpdb->charset"; // charset
		if(!empty($wpdb->collate)) $db_collation .= " COLLATE $wpdb->collate";
	}
 
	// the SQL query
	// the table should be named so (wp_termmeta, i.e prefix_termmeta), otherweise the functions won't work
	$wpdb->query("CREATE TABLE IF NOT EXISTS ". $wpdb->prefix . "termmeta (
		`meta_id` bigint(20) NOT NULL AUTO_INCREMENT,
		`term_id` bigint(20) NOT NULL,
		`meta_key` varchar(255) NOT NULL,
		`meta_value` longtext DEFAULT '' NOT NULL,
		PRIMARY KEY id (`meta_id`)) $db_collation;"
	);
}

Now the table was created and we can go to the next step.

Step 2. PHP Class for additional Setting Fields

Using the class is very easy and fast.

This class supports the following inputs: <input> (text and checkbox), <select>, <textarea>. You can also add another fields: radio buttons, images etc.

This metabox class contains only the most important code, please add user capability and nonce field verifications by yourself.

<?php
class rudrTaxonomyFields {
	/*
	 * This functions generates the hooks (class constructor)
	 */
	function __construct( $params ) {
		$this->params = $params;
		$this->prefix = $this->params['id'] .'_'; // prefix
		foreach ( $this->params['tax'] as $tax ) { // for each taxonomy, specified in parameters
			add_action($tax . '_edit_form_fields', array(&$this, 'fields'), 10, 2 ); // field hook
		}
		add_action('edit_term', array(&$this, 'update'), 10,1); // saving hook
	}
	/*
	 * This functions generates the input fields
	 */
	function fields( $term_object, $taxonomy_name ){
 
		foreach ( $this->params['args'] as $arg ) { // для каждого описанного параметра...
 
			?><tr class="form-field"><?php
				// определяем значение произвольного поля таксономии
				if(!$val = get_metadata('term', $term_object->term_id, $this->prefix .$arg['id'], true)) $val = $arg['std'];
				switch ( $arg['type'] ) {
					case 'text':{ ?>
						<th scope="row"><label for="<?php echo $this->prefix .$arg['id'] ?>"><?php echo $arg['title'] ?></label></th>
						<td>
							<input name="<?php echo $this->prefix .$arg['id'] ?>" type="<?php echo $arg['type'] ?>" id="<?php echo $this->prefix .$param['id'] ?>" value="<?php echo $val ?>" class="regular-text" />
							<?php if(isset( $arg['description'] ) ) echo '<p class="description">' . $arg['description'] . '</p>'  ?>
						</td>
						<?php
						break;							
					}
					case 'textarea':{ ?>
						<th scope="row"><label for="<?php echo $this->prefix .$arg['id'] ?>"><?php echo $arg['title'] ?></label></th>
						<td>
							<textarea name="<?php echo $this->prefix .$arg['id'] ?>" type="<?php echo $arg['type'] ?>" id="<?php echo $this->prefix .$arg['id'] ?>" class="large-text" /><?php echo $val ?></textarea>
							<?php if(isset( $arg['description'] ) ) echo '<p class="description">' . $arg['description'] . '</p>'  ?>
						</td>
						<?php
						break;							
					}
					case 'checkbox':{ ?>
						<th scope="row"><label for="<?php echo $this->prefix .$arg['id'] ?>"><?php echo $arg['title'] ?></label></th>
						<td>
							<label for="<?php echo $this->prefix .$arg['id'] ?>"><input name="<?php echo $this->prefix .$arg['id'] ?>" type="<?php echo $arg['type'] ?>" id="<?php echo $this->prefix .$arg['id'] ?>"<?php echo ($val=='on') ? ' checked="checked"' : '' ?> />
							<?php if(isset( $arg['description'] ) ) echo $arg['description']  ?></label>
						</td>
						<?php
						break;							
					}
					case 'select':{ ?>
						<th scope="row"><label for="<?php echo $this->prefix .$arg['id'] ?>"><?php echo $arg['title'] ?></label></th>
						<td>
							<label for="<?php echo $this->prefix .$arg['id'] ?>">
							<select name="<?php echo $this->prefix .$arg['id'] ?>" id="<?php echo $this->prefix .$arg['id'] ?>"><option>...</option><?php
								foreach($arg['args'] as $value=>$name){
									?><option value="<?php echo $value ?>"<?php echo ( $value == $val ) ? ' selected="selected"' : '' ?>><?php echo $name ?></option><?php
								}
							?></select></label>
							<?php if(isset( $arg['description'] ) ) echo '<p class="description">' . $arg['description'] . '</p>'  ?>
						</td>
						<?php
						break;							
					}
				} 
			?></tr><?php
 
		}
 
	}
	/*
	 * Функция сохранения значений полей
	 */
	function update( $term_id ){
		foreach ( $this->params['args'] as $arg ) {
			if ( isset( $_POST[ $this->prefix . $arg['id'] ] ) && trim( $_POST[ $this->prefix . $arg['id'] ] ) ) {
				update_metadata('term', $term_id, $this->prefix . $arg['id'], trim($_POST[ $this->prefix . $arg['id'] ], '') );
			} else {
				delete_metadata('term', $term_id, $this->prefix . $arg['id'], '', false);
			}
		}
	}
}

Insert this PHP class into you plugin or theme, after that you can create the array with class parameters like this:

$params = array(
	array(
		'id'	=>	'taxmeta', // ID
		'tax'	=>	array('post_tag', 'game'), // taxonomy names
		'args'	=>	array(
			array(
				'id'			=>	'order', // name and id attributes
				'title'			=>	'Order', // field label
				'type'			=>	'text', // input field type
				'description'			=>	'Set the order number.',
				'std'			=>	'0' // default value
			),
			array(
				'id'			=>	'homepage',
				'title'			=>	'Homepage',
				'type'			=>	'checkbox',
				'description'			=>	'Show on homepage',
				'std'			=>	''
			)
		)
	),
	array(
		'id'	=>	'gamemeta',
		'tax'	=>	array('game'),
		'args'	=>	array(
			array(
				'id'			=>	'genre',
				'title'			=>	'Genre',
				'type'			=>	'select',
				'description'			=>	'Please select a game genre.',
				'std'			=>	'',
				'args'			=>	array('genre1' => 'Shooter', 'genre2' => 'MMORPG', 'genre3' => 'Racing' ) // value=>label
			),
			array(
				'id'			=>	'reqs',
				'title'			=>	'System requirements',
				'type'			=>	'textarea',
				'std'			=>	''
			)
		)
	)
);
 
foreach ($params as $param) {
	$rudrtaxmeta = new rudrTaxonomyFields($param);
}

Look at the result:

term additional input fields

That’s all. If you have any question, please leave it in comments.

Only the best of WordPress

once a week, no spam

Leave your question or feedback

phpjsHTMLCSSSQLCode
Please, enter a comment
Please, enter a name
Incorrect email