Blog

Introducing Term Meta Data In WordPress

WordPress 4.4 introduced term meta data which allows you to save meta values for terms in a similar way to post meta data. This is a highly anticipated and logical addition to the WordPress system.

So far, the post and comment meta systems allowed us to add arbitrary data to posts and comments. This can be used to add ratings to comments, indicate your mood while you were writing a post, attach prices to product posts, and various other information you think is relevant to your content. As of the newest version of WordPress, meta data can now be added to terms which allows us to create features like default category thumbnails in a standardized way. This tutorial will show you how you can edit, update and retrieve these meta data for terms.

Under The Hood Of Term Meta Data Link

The logic behind term meta data is not new, already being used for posts, comments and users.

To enable meta data for terms, the new

termmeta

table was introduced. It saves the combination of the

term_id

,

meta_key

and

meta_value

, plus an incrementing

meta_id

.

Meta Data Functions Link

Four new functions were introduced to handle create, read, update and delete (CRUD) operations for term meta data:

  • add_term_meta()

    : adds the meta data

  • update_term_meta()

    : updates existing meta data

  • delete_term_meta()

    : deletes meta data

  • get_term_meta()

    : retrieves the meta data

Under the hood, these functions use the same code that the corresponding functions for post meta data use as well.

Adding Meta Data With A New Term

In order to extend the form to add a term, we make use of the

{$taxonomy}_add_form_fields

hook. For our

house_feature

taxonomy it resolves into

house_feature_add_form_fields

.

add_action( 'house_feature_add_form_fields', 'add_feature_group_field', 10, 2 );
function add_feature_group_field($taxonomy) {
global $feature_groups;
?><div class="form-field term-group">
<label for="featuret-group"><?php _e('Feature Group', 'my_plugin'); ?></label>
<select class="postform" id="equipment-group" name="feature-group">
<option value="-1"><?php _e('none', 'my_plugin'); ?></option><?php foreach ($feature_groups as $_group_key => $_group) : ?>
<option value=" " class=""><?php echo $_group; ?></option>
<?php endforeach; ?>
</select>
</div><?php
}

To save the term meta we need to hook into the action, which is fired when the new term is being saved. This time we use the created_{$taxonomy} hook.

add_action( 'created_house_feature', 'save_feature_meta', 10, 2 );

function save_feature_meta( $term_id, $tt_id ){
if( isset( $_POST[‘feature-group’] ) && ” !== $_POST[‘feature-group’] ){
$group = sanitize_title( $_POST[‘feature-group’] );
add_term_meta( $term_id, ‘feature-group’, $group, true );
}
}

We get the term data from the $_POST array sent with the form and save it using the new add_term_meta() function. Like add_post_meta(), it takes four arguments:

$term_id: the id of the term,
$meta_key: the meta key,
$meta_value: the value,
$unique: whether the key can only be used once; defaults to false.

I am setting $unique to true, because I want each feature of the house to be listed in only one group.

Updating A Term With Meta Data Link

Even though they share similar features, adding a new term and updating an existing one is technically different in WordPress. Therefore, we need to add an update routine too.

We make use of the {$taxonomy}_edit_form_fields hook to get the field for the group into the edit form.

 

add_action( 'house_feature_edit_form_fields', 'edit_feature_group_field', 10, 2 );

function edit_feature_group_field( $term, $taxonomy ){

global $feature_groups;

// get current group
$feature_group = get_term_meta( $term->term_id, ‘feature-group’, true );

?><tr class=”form-field term-group-wrap”>
<th scope=”row”><label for=”feature-group”><?php _e( ‘Feature Group’, ‘my_plugin’ ); ?></label></th>
<td><select class=”postform” id=”feature-group” name=”feature-group”>
<option value=”-1″><?php _e( ‘none’, ‘my_plugin’ ); ?></option>
<?php foreach( $feature_groups as $_group_key => $_group ) : ?>
<option value=” ” <?php selected( $feature_group, $_group_key ); ?>><?php echo $_group; ?></option>
<?php endforeach; ?>
</select></td>
</tr><?php
}

In addition to the add form, we need to retrieve the existing term data using get_term_meta() and pre-select it. This function has three arguments:

$term_id: the id of the term,
$key: the key of the meta data,
$single: whether to return a single result; defaults to false which would return an array.

Since I am expecting only one value to be returned, I set $single to true.

We now need to hook into edited_{$taxonomy} to save the data.

add_action( 'edited_house_feature', 'update_feature_meta', 10, 2 );

function update_feature_meta( $term_id, $tt_id ){

if( isset( $_POST[‘feature-group’] ) && ” !== $_POST[‘feature-group’] ){
$group = sanitize_title( $_POST[‘feature-group’] );
update_term_meta( $term_id, ‘feature-group’, $group );
}
}

We use update_term_meta() to overwrite the existing value instead of adding a new set of meta data.

Displaying The Term Meta Data In The Term List Link

The meta data is saved now. Let’s display it in a new column in the term list table. First, let’s add the column and header to the table. Finding the correct hook to extend a table in the WordPress dashboard is again a bit tricky because of so many flexible hook names.

The pattern you can use here is manage_edit-{$taxonomy}_columns, even though this is not exactly how the hook is defined.

add_filter('manage_edit-house_feature_columns', 'add_feature_group_column' );

function add_feature_group_column( $columns ){
$columns[‘feature_group’] = __( ‘Group’, ‘my_plugin’ );
return $columns;
}

To add the content into the column fields, you can use the hook pattern manage_{$taxonomy}_custom_column.

add_filter('manage_house_feature_custom_column', 'add_feature_group_column_content', 10, 3 );

function add_feature_group_column_content( $content, $column_name, $term_id ){
global $feature_groups;

if( $column_name !== ‘feature_group’ ){
return $content;
}

$term_id = absint( $term_id );
$feature_group = get_term_meta( $term_id, ‘feature-group’, true );

if( !empty( $feature_group ) ){
$content .= esc_attr( $feature_groups[ $feature_group ] );
}

return $content;
}

Again, we use get_term_meta() to retrieve the value and then simply attach it to the existing content. This would allow other developers to attach something else here as well.

It was in the nature of my project, that many terms shared the same value, so let’s make the group column sortable. We only need to add it to the sortable columns.

add_filter( 'manage_edit-house_feature_sortable_columns', 'add_feature_group_column_sortable' );
function add_feature_group_column_sortable( $sortable ){
$sortable[ 'feature_group' ] = 'feature_group';
return $sortable;
}

Deleting Term Meta Data

If you remove a term, the corresponding meta data will also be removed, so you don’t need to clean up after yourself.

However, if you find yourself needing to remove term meta data, you can use the

delete_term_meta()

function. It takes up to three arguments:

  • $term_id

    : the id of the term

  • $meta_key

    : the meta key

  • $meta_value

    : the previous value

You only need to provide

$meta_value

if you want to remove meta data with a specific value.

Retrieving Terms By Meta Value

Like with posts, you can also retrieve terms using the meta values. Set the

meta_query

parameter when using

get_terms()

or

wp_get_object_terms()

.

With the following query I would retrieve all features in the

kitchen

group.

$args = array(
    'hide_empty' => false, // also retrieve terms which are not used yet
    'meta_query' => array(
        array(
           'key'       => 'feature-group',
           'value'     => 'kitchen',
           'compare'   => 'LIKE'
        )
    )
);

$terms = get_terms( ‘house_feature’, $args );

Comments (1)

  • john Reply

    This should be the best collection of blogging website i ever found out.

    April 14, 2016 at 12:52 pm

Leave a Reply