.
WORDPRESS PLUGINS ABOUT

Creating WordPress Custom Fields

14 minute read, 13 if you're quick

Sometimes you need to add some extra functionality to the backend of WordPress, whether to add a button in the main Dashboard page, an extra menu option in the main sidebar menu or even a whole new section in there.

When I tried looking for a solution to add a button on the Dashboard page it wasn't easy to find, I had done it before many times but just couldn't find a copy of my code anywhere.
So, thought I wouldn't be the only person so here are as many as I can find in one place.

Adding a Widget to WordPress Dashboard

The following code will add a Widget tile to the main Dashboard page in WordPress' backend. You can add a button or anything you like really here.
The link to the WordPress page on this widget is HERE

//Create WordPress Dashboard Widget/Tile
function dashboard_widget() {
	
	//WP function to add dashboard widget
	wp_add_dashboard_widget(
		'admin_dashboard_widget',//Widget ID
		'Admin Dashboard Widget Title',//Widget Name/Title
		'admin_dashboard_widget_callback',//Callback function
		'',//Optional callback control
		'',//Optional callback args
		'side',//Optional context: normal, side, column3, column4
		'high'//Optional priority: high, core, low
	);
	
}
add_action('wp_dashboard_setup', 'dashboard_widget');

//Callback function
function admin_dashboard_widget_callback() {
	
	//Add what you would like to display here
	echo "Dashboard Widget stuff here<br>";
	
	
}

Adding Single Menu Button in WordPress Dashboard

To add a single button in the WordPress Dashboard menu is very easy to add the following code to your functions.php file or plugin (if you are developing one).

This is a link to the WordPress page for this command HERE.
Here is the code you need to add:

//The add_Action will run the function add_menu_button
add_action('admin_menu', 'add_menu_button');
function add_menu_button() {

    add_menu_page( 'Title', 'Text of button', 'manage_options', 'slug', 'function_to_run','', 3 );

}
function function_to_run() {

    //Your code here
    return;

}

Adding a Group of Buttons to the WordPress Dashboard Menu

Above I showed you the code to add a single button to the WordPress Dashboard menu, the next step is to add several buttons within a group.

This will provide a dropdown option whereby a selection of buttons will be available. The important part here is that the submenu options use the main menu_page slug in parameter 1. This ties the all together.
This is the link to the WordPress documentation for this command HERE.

function main_function(){
	
	add_menu_page('Group Page Title', 'Main Button Title', 'manage_options', 'group-slug', 'function_to_run', 'https://example.com/icon.png', 200);//Last number = position
	add_submenu_page( 'group-slug', 'Page title', 'Page Title 1', 'manage_options' , 'page_slug', 'function_to_run', 1 );//Last number = position
	add_submenu_page( 'group-slug', 'Page title', 'Page Title 2', 'manage_options' , 'page_slug2', 'function_to_run', 2 );//Last number = position
		
}
add_action('admin_menu', 'main_function');

//What to display on the menu page.
function function_to_run() {

    //Your code here

}

How to create an extra Column in the WooCommerce Product list

Creating an extra column for the WooCommerce product page is straightforward to do by adding a small amount of code into the Functions.php file of your WordPress theme.
There are two functions you need to add which are below. The first function creates the column in the WordPress page (wp-admin/edit.php?post_type=product).
The second will add the content to the column you have just created.

add_filter( 'manage_edit-product_columns', 'function_to_run', 9999 );
function function_to_run( $columns ){
   $columns['stockMsg'] = 'Stock Message';
   $columns['deliveryMsg'] = 'Delivery';
   return $columns;
}

As you can see this will create two columns called Stock Message and Delivery.
The next function will add some content for those columns.

add_action( 'manage_product_posts_custom_column', 'function_to_run_content', 10, 2 );
function function_to_run_content( $column, $product_id ){
    if ( $column == 'stockMsg' ) {
		echo $v ['text_under_price'][0];
	}

    if ( $column == 'deliveryMsg' ) {
		echo $v ['text_under_price'][0];
	}
}

How to add a Custom Field to the Bulk Edit section of WordPress

To add a custom field to the bulk edit area of WordPress or WooCommerce you need to add two small functions to your Functions.php file.
The first will create the field, whilst the second will save the changes when using the new custom field.
Let's get straight to it.
Here is the first function that creates the custom field.

add_action( 'woocommerce_product_bulk_edit_start', 'function_to_run' );
function function_to_run() {
	?>
    <div class="inline-edit-group">
      <label class="alignleft">
         <span class="title"><?php _e( 'Your Field Title', 'woocommerce' ); ?></span>
         <span class="input-text-wrap">
            <input type="text" name="field_name" class="text" value="">
         </span>
        </label>
    </div>
    <?php
}

This will create a field called Your Field Title with a single input field, you can add as many HTML form fields as you like here.
The next function will save the uses of the field in the WordPress database table post_meta.

add_action( 'woocommerce_product_bulk_edit_save', 'function_to_run_save' );
function function_to_run_save( $product ) {
	
	$post_id = $product->get_id(); 
	if ( isset( $_REQUEST['field_name'] ) ) {
		
		$field_name= $_REQUEST['field_name'];
		update_post_meta( $post_id, 'field_name', wc_clean( $field_name) );
		
	}
	
}

Creating a Custom Field in the Inventory sections of WooCommerce

To add a custom field to the Inventory section of WooCommerce in the Edit Product page you need to add two small functions to your Themes Functions.php file.
The first creates the field whilst the second saves the content when using the field.
So, here is the code for the first part, creating the custom field.

add_action('woocommerce_product_options_inventory_product_data', 'inventory_tab_field');
function inventory_tab_field()
{
    echo '<div class="product_custom_field">';
    woocommerce_wp_text_input(
        array(
            'id' => 'delivery_message',
            'placeholder' => 'Available on back-order, delivery normally 1 - 2 weeks',
            'label' => __('Delivery message', 'woocommerce'),
            'desc_tip' => true,
        )
    );
    echo '</div>';
}

The second function simply saves any content used in the new field to the WordPress post_meta table.

add_action('woocommerce_process_product_meta', 'inventory_tab_field_save');
function inventory_tab_field_save( $post_id ) {
	
    $f = $_POST['delivery_message'];
    if ( ! empty( $f ) ) {
		
        update_post_meta( $post_id , 'delivery_message', sanitize_text_field( $_POST['delivery_message'] ) );
		
	} else {
		
        update_post_meta( $post_id , 'delivery_message', 'Available on back-order, delivery normally 1 - 2 weeks' );
		
	}
	
}

In this example, I added an IF statement to use a pre-defined message if one has not been added using the new custom field.

Creating a Custom Field in the General section of WooCommerce

There are two steps to saving a field to the General tab in the Edit page of a WooCommerce product. First create the field and second save the data to the postmeta table.

// Step 1: Add the custom field to the General product tab
add_action('woocommerce_product_options_general_product_data', 'add_custom_general_fields');

function add_custom_general_fields() {
    // Display the custom text field
    woocommerce_wp_text_input( 
        array( 
            'id' => 'custom_field_name', // The custom field ID
            'label' => __('Custom Field Name', 'woocommerce'), // The custom field label
            'placeholder' => '', // Placeholder
            'description' => __('Enter a custom value here.', 'woocommerce'), // Description
            'desc_tip' => 'true', // Show description as tooltip
            'type' => 'text' // Field type
        )
    );
}

// Step 2: Save the custom field value when the product is saved
add_action('woocommerce_admin_process_product_object', 'save_custom_general_fields', 10, 1);

function save_custom_general_fields($product) {
    if (isset($_POST['custom_field_name'])) {
        $product->update_meta_data('custom_field_name', sanitize_text_field($_POST['custom_field_name']));
    }
}

Create a Custom Field in the WordPress Media Library

To create a custom field in the Media Library we will use two functions below. The first will create the field and the second will save the data.

In this example we will call the field File Date, here is the first function to add to your functions.php file.

function media_file_date( $form_fields, $post ) {
	
    $form_fields['media-file'] = array(
        'label' => 'File Date:',
        'input' => 'date',
        'value' => get_post_meta( $post->ID, 'media_file_date', true ),
    );

    return $form_fields;
}
add_filter( 'attachment_fields_to_edit', 'media_file_date', 1, 2 );

The second function will save any data used in the field to the postmeta table.

function media_file_date_save( $post, $attachment ) {
	
    if( isset( $attachment['media-file'] ) )
        update_post_meta( $post['ID'], 'media_file_date', $attachment['media-file'] );

    return $post;
}
add_filter( 'attachment_fields_to_save', 'media_file_date_save', 10, 2 );

Create Custom Fields in Post, Page and Product pages.

To create the fields in their own separate boxes in the EDIT admin page of the post it is broken down into 3 parts.

  1. Create the fields
  2. Display the fields
  3. Save the field data

Create the fields:

add_action('add_meta_boxes', [$this, 'function_name_to_create_fields']);

function function_name_to_create_fields() {
add_meta_box(
    'name_of_field_box',
    'Title of the box',
    [$this, 'display_field_function'],
    ['post', 'page', 'product'],
    'normal',
    'high'
);
}

Display the fields:

function display_field_function() {
wp_nonce_field(basename(__FILE__), "nonce_name_needed_in_save_section");
?>
<style>
    .fields label {
        font-weight: bold;
        line-height: 30px;
    }

    .jgam_seo1_field input {
        width: 100%;
    }
</style>
<div class="fields">
    <label for="field1">Field 1</label>
    <input name="field1" type="text" value="<?php echo get_post_meta($post->ID, "name_of_meta_key1", true); ?>">
    <br>
    <label for="field2">Field 2</label>
    <input name="field2" type="text" value="<?php echo get_post_meta($post->ID, "name_of_meta_key2", true); ?>">
    <br>
    <label for="field3">Field 3</label>
    <input name="field3" type="text" value="<?php echo get_post_meta($post->ID, "name_of_meta_key3", true); ?>">
    <br>
</div>
<?php
}

Save the Fields data:

add_action('save_post', [$this, 'function_name_to_save_data']);

function function_name_to_save_data() {
// Verify nonce
if (!isset($_POST['nonce_name_needed_in_save_section']) || !wp_verify_nonce($_POST['nonce_name_needed_in_save_section'], basename(__FILE__))) {
return $post_id;
}

// Check autosave
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return $post_id;
}

// Check permissions
if (isset($_POST['post_type']) && 'page' == $_POST['post_type']) {
if (!current_user_can('edit_page', $post_id)) {
return $post_id;
}
} else {
if (!current_user_can('edit_post', $post_id)) {
return $post_id;
}
}

// Save/Update meta fields
if (isset($_POST['field1'])) {
update_post_meta($post_id, 'name_of_meta_key1', sanitize_text_field($_POST['field1']));
}

if (isset($_POST['field2'])) {
update_post_meta($post_id, 'name_of_meta_key2', sanitize_text_field($_POST['field2']));
}

if (isset($_POST['field3'])) {
update_post_meta($post_id, 'name_of_meta_key3', sanitize_text_field($_POST['field3']));
}
}

Create Custom Fields for Category and WooCommerce Product Category pages

Category pages are a little more complicated but follow the same format as a normal Post type page as above. The data is stored in the termmeta table this time.

Create the fields:

add_action('category_add_form_fields', [$this, 'add_custom_fields_to_category'], 10, 2);
add_action('product_cat_add_form_fields', [$this, 'add_custom_fields_to_category'], 10, 2);

public function add_custom_fields_to_category($taxonomy)
{
?>
    <div class="form-field">
        <label for="category_custom_field_1"><?php _e('Custom Field 1', 'textdomain'); ?></label>
        <input type="text" name="category_custom_field_1" id="category_custom_field_1" value="">
        <p class="description"><?php _e('Enter value for custom field 1', 'textdomain'); ?></p>
    </div>
    <div class="form-field">
        <label for="category_custom_field_2"><?php _e('Custom Field 2', 'textdomain'); ?></label>
        <input type="text" name="category_custom_field_2" id="category_custom_field_2" value="">
        <p class="description"><?php _e('Enter value for custom field 2', 'textdomain'); ?></p>
    </div>
    <div class="form-field">
        <label for="category_custom_field_3"><?php _e('Custom Field 3', 'textdomain'); ?></label>
        <input type="text" name="category_custom_field_3" id="category_custom_field_3" value="">
        <p class="description"><?php _e('Enter value for custom field 3', 'textdomain'); ?></p>
    </div>
<?php
}

Edit the Fields:

add_action('category_edit_form_fields', [$this, 'edit_custom_fields_in_category'], 10, 2);
add_action('product_cat_edit_form_fields', [$this, 'edit_custom_fields_in_category'], 10, 2);

public function edit_custom_fields_in_category($term, $taxonomy)
{
    $custom_field_1 = get_term_meta($term->term_id, 'category_custom_field_1', true);
    $custom_field_2 = get_term_meta($term->term_id, 'category_custom_field_2', true);
    $custom_field_3 = get_term_meta($term->term_id, 'category_custom_field_3', true);
    ?>
    <tr class="form-field">
        <th scope="row" valign="top"><label for="category_custom_field_1"><?php _e('Custom Field 1', 'textdomain'); ?></label></th>
        <td>
            <input type="text" name="category_custom_field_1" id="category_custom_field_1" value="<?php echo esc_attr($custom_field_1); ?>">
            <p class="description"><?php _e('Enter value for custom field 1', 'textdomain'); ?></p>
        </td>
    </tr>
    <tr class="form-field">
        <th scope="row" valign="top"><label for="category_custom_field_2"><?php _e('Custom Field 2', 'textdomain'); ?></label></th>
        <td>
            <input type="text" name="category_custom_field_2" id="category_custom_field_2" value="<?php echo esc_attr($custom_field_2); ?>">
            <p class="description"><?php _e('Enter value for custom field 2', 'textdomain'); ?></p>
        </td>
    </tr>
    <tr class="form-field">
        <th scope="row" valign="top"><label for="category_custom_field_3"><?php _e('Custom Field 3', 'textdomain'); ?></label></th>
        <td>
            <input type="text" name="category_custom_field_3" id="category_custom_field_3" value="<?php echo esc_attr($custom_field_3); ?>">
            <p class="description"><?php _e('Enter value for custom field 3', 'textdomain'); ?></p>
        </td>
    </tr>
    <?php
}

Save the Field data:

add_action('created_category', [$this, 'save_custom_fields_in_category'], 10, 2);
add_action('edited_category', [$this, 'save_custom_fields_in_category'], 10, 2);
add_action('created_product_cat', [$this, 'save_custom_fields_in_category'], 10, 2);
add_action('edited_product_cat', [$this, 'save_custom_fields_in_category'], 10, 2);

public function save_custom_fields_in_category($term_id)
{
if (isset($_POST['category_custom_field_1'])) {
update_term_meta($term_id, 'category_custom_field_1', sanitize_text_field($_POST['category_custom_field_1']));
}
if (isset($_POST['category_custom_field_2'])) {
update_term_meta($term_id, 'category_custom_field_2', sanitize_text_field($_POST['category_custom_field_2']));
}
if (isset($_POST['category_custom_field_3'])) {
update_term_meta($term_id, 'category_custom_field_3', sanitize_text_field($_POST['category_custom_field_3']));
}
}

Display the Fields:

add_filter('the_content', [$this, 'display_custom_fields_in_category']);

public function display_custom_fields_in_category($content)
{
if (is_category() || is_tax('product_cat')) {
$term = get_queried_object();
$custom_field_1 = get_term_meta($term->term_id, 'category_custom_field_1', true);
$custom_field_2 = get_term_meta($term->term_id, 'category_custom_field_2', true);
$custom_field_3 = get_term_meta($term->term_id, 'category_custom_field_3', true);

if ($custom_field_1 || $custom_field_2 || $custom_field_3) {
$content .= '<div class="category-custom-fields">';
    if ($custom_field_1) {
    $content .= '<p>' . __('Custom Field 1:', 'textdomain') . ' ' . esc_html($custom_field_1) . '</p>';
    }
    if ($custom_field_2) {
    $content .= '<p>' . __('Custom Field 2:', 'textdomain') . ' ' . esc_html($custom_field_2) . '</p>';
    }
    if ($custom_field_3) {
    $content .= '<p>' . __('Custom Field 3:', 'textdomain') . ' ' . esc_html($custom_field_3) . '</p>';
    }
    $content .= '</div>';
}
}
return $content;
}
^