Getting plugged in – part 4: meta boxes

Numerous tutorials exist for adding and using meta boxes; some manage to make it seem like a dark art by rushing through too much in one go without explaining exactly what is going on.

This isn't going to be a guide, more a detailing of the steps I have taken to get a meta box in place for adding the 'liked' and 'reply' custom fields on posts then converting those into #indieweb webmention links.

Display a simple meta box

This is the easy bit, and I actually mean easy.

WordPress provides the add_meta_boxes hook and add_meta_box() function to easily register a custom box. We first need to create a function which calls add_meta_box() then add that function as an action to the add_meta_boxes hook:

function landr_custom_meta() {
    add_meta_box( 'landr_meta', 'Like and Replies', 'landr_meta_callback', 'post' );
}

add_action( 'add_meta_boxes', 'landr_custom_meta' );

The add_meta_box() function needs four parameters although more can be used to control where the meta box sits on the page, these are: ID, the box title, a callback function which actually does the work, and the type of post we want it to be used with.

Just to prove everything is set up properly a callback function can be created:

function landr_meta_callback() {
    echo 'Likes and replies go here.';
}

And, just like that we have a meta box.

It doesn't do anything yet, but it was easy to create. Now comes the fun stuff.

Adding fields and saving values

Getting the required fields in is just a case of adding some standard HTML (so I won't go in to that here) ensuring that the fields are named properly so they can be referenced later.

With the fields added we need to be able to write their values to the database if they have been populated. Another function coming up added as an action to the save_post hook.

As we saw before, security is paramount when dealing with WordPress plugins. Because we are dealing with something that can write to the WordPress database we need to ensure that this is handled securely.

There are two steps to take: firstly, adding a nonce (number used once) field to the meta box which will prevent improper access, and double-checking that the person trying to save the data is allowed to do so:

//create nonce

wp_nonce_field( basename( <strong>FILE</strong> ), 'landr_nonce' );

//check if nonce exists and is verified

if ( ! isset( $_POST[ 'landr_nonce'] ) ) {
    return;
}

if ( ! wp_verify_nonce( $_POST['landr_nonce'], basename( <strong>FILE</strong> ) ) ) {
    return;
}

//check permission to edit post

if ( ! current_user_can( 'edit_post', $post_id ) ) {
    return;
}

The 'liked' or 'reply' values can then be written to the postmeta table using add_post_meta() ready to be converted into webmention links.

if ( isset( $_POST['liked-url'] ) ) {
    $liked_url = sanitize_text_field( $_POST['liked-url'] );
    add_post_meta( $post_id, 'Liked', $liked_url );
}

if ( isset( $_POST['reply-url'] ) ) {
    $reply_url = sanitize_text_field( $_POST['reply-url'] );
    add_post_meta( $post_id, 'Reply', $reply_url );
}

Webmentions

Previously, the plugin used the content_save_pre hook to add the webmention link to the start of the post content. With the new code linked to save_post it wasn't going to work as it fires after content_save_pre.

The original code to write the link was modified slightly and moved into the same function so everything is processed at the same time.

It needs some tidying up but the updated plugin can be viewed in the GitHub repository.