The default custom fields functionality in WordPress is to help end-users add content and customize their websites fast and easily. However, it is limited to only text fields and thus, is not enough in most cases. Then you may want to look for a plugin that can help you create fields in any type to save any kind of data as Meta Box plugin, it’s so easy. But you know what, even when you don’t want to use any plugin from others, you can create one by yourselves to create new custom fields in your totally new types.
Let’s find out how!
Requirements:
Before going into the details, it should be mentioned that you need to have some basic knowledge about:
- PHP and HTML
- How to make a simple WordPress plugin
In WordPress, there are no functions to add any user interface for custom fields directly. All functions related to custom fields are made via an API named meta box. So, let's talk about the meta box before going into the details of creating new custom fields.
What is Meta Box?
Back to the first post of this series, we know the definition of custom fields:
So, in terms of the user interface, custom fields are the form fields that allow users to fill data.
In the post editor of WordPress, you'll see the areas that contain additional information about the post such as the Publish box, Format box, and Categories box. That information is grouped into boxes called "meta boxes", which means boxes that contain metadata. This is the origin of our plugin's name, Meta Box. However, the term "meta box" here refers to the above boxes, not our plugin.
In the previous post, we used a meta box to add some basic custom fields of the text type. In the next section, let's create a meta box that has some different field types. To do that, we need to create a small plugin.
Create a Simple Custom Field Plugin
Creating a plugin is recommended to add functionality to WordPress. Let's create a simple plugin follow these steps:
- Create a new folder named
hello-custom-fields
, which is the name of the plugin, inside thewp-content/plugins
folder. - Inside that folder, create a .php file named
hello-custom-fields.php
with the content below:
<?php /** * Plugin Name: Hello Custom Field * Plugin URI: https://metabox.io * Description: A simple plugin for custom fields. * Version: 1.0 * Author: Meta Box * Author URI: https://metabox.io * License: GPL2 */
You can read more details about how to make a plugin here.
For this practice, I will use the created plugin to allow users to fill in the information of a book with some custom fields like this:
- Author: a text field
- Publish year: a date field
- Price: a number field
Things we need to do:
- Create a meta box
- Add custom fields to that meta box
- Save the values of custom fields
- Display the value of each custom field on the front end
Here we go!
Create a Meta Box
WordPress provides the add_meta_box
function to add meta boxes on whatever page we want. This function has the following syntax:
add_meta_box( $id, $title, $callback, $screen, $context, $priority, $callback_args)
Where:
Name | Description |
$id |
Meta box ID. |
$title |
Title of the meta box. |
$callback |
The function that fills the box with the desired content. The function should echo its output. |
$screen |
The screen or screens on which to show the box (such as a post type, link , or comment ). |
$context |
The context within the screen where the boxes should display. Post edit screen contexts include normal , side , and advanced . Default value: advanced . |
$priority |
The priority within the context where the boxes should show (high , low ). Default value: high . |
$callback_args |
Data should be set as the $args property of the box array (which is the second parameter passed to your callback). Default value: null . |
We'll create a meta box with the title "Hello Custom Fields" in the edit/create posts screen. Open the created .php
file and add the following snippet:
/** * Register meta boxes. */ function hcf_register_meta_boxes() { add_meta_box( 'hcf-1', __( 'Hello Custom Field', 'hcf' ), 'hcf_display_callback', 'post' ); } add_action( 'add_meta_boxes', 'hcf_register_meta_boxes' ); /** * Meta box display callback. * * @param WP_Post $post Current post object. */ function hcf_display_callback( $post ) { echo "Hello Custom Field"; }
Anything echoed in the hcf_display_callback
function will be displayed.
Currently, this function displays only a simple text paragraph. In the next section, we will display some inputs for users to enter values for books.
Add Custom Fields into a Meta Box
To add custom fields into a meta box, we need to modify the callback function to output form inputs. To shorten the code, let's create a file form.php
that contains the code of the form. Here is the snippet:
/** * Meta box display callback. * * @param WP_Post $post Current post object. */ function hcf_display_callback( $post ) { include plugin_dir_path( __FILE__ ) . './form.php'; }
Content of the file form.php
as below:
<div class="hcf_box"> <style scoped> .hcf_box{ display: grid; grid-template-columns: max-content 1fr; grid-row-gap: 10px; grid-column-gap: 20px; } .hcf_field{ display: contents; } </style> <p class="meta-options hcf_field"> <label for="hcf_author">Author</label> <input id="hcf_author" type="text" name="hcf_author"> </p> <p class="meta-options hcf_field"> <label for="hcf_published_date">Published Date</label> <input id="hcf_published_date" type="date" name="hcf_published_date"> </p> <p class="meta-options hcf_field"> <label for="hcf_price">Price</label> <input id="hcf_price" type="number" name="hcf_price"> </p> </div>
You can separate the style into an individual file. But, it is not necessary in this case because we are making a small example only and the code is simple.
The result will be like this:
Unlike the default functionality of WordPress which supports only text fields, using code to add custom fields allows you to use whatever type of fields you want. In the above screenshot, we use a date field that allows users to pick any date without entering manually.
This ability helps users fill data easier, reduce mistakes, and help you validate the data (if needed).
Save the Custom Fields
We had the form for users to fill in data, but WordPress does not save it automatically. We must save it ourselves.
In order to save custom fields when users save or update a post, we need to hook into the save_post
action. save_post
is called after the post is saved. To save the custom fields, we'll use the update_post_meta
function . Put the following code into the plugin file:
/** * Save meta box content. * * @param int $post_id Post ID */ function hcf_save_meta_box( $post_id ) { if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return; if ( $parent_id = wp_is_post_revision( $post_id ) ) { $post_id = $parent_id; } $fields = [ 'hcf_author', 'hcf_published_date', 'hcf_price', ]; foreach ( $fields as $field ) { if ( array_key_exists( $field, $_POST ) ) { update_post_meta( $post_id, $field, sanitize_text_field( $_POST[$field] ) ); } } } add_action( 'save_post', 'hcf_save_meta_box' );
Now, try to fill the data in the meta box and save the post. After reloading the page, you will not see any value which you put into the fields. Don't worry! The data has been saved into the database already.
Let's take a look at the code of the custom fields once again! The fields are missing the value
attribute which shows the value in the fields. So, we have to get the value of the fields from the database, then output it to the value
attribute:
<div class="hcf_box"> <style scoped> .hcf_box{ display: grid; grid-template-columns: max-content 1fr; grid-row-gap: 10px; grid-column-gap: 20px; } .hcf_field{ display: contents; } </style> <p class="meta-options hcf_field"> <label for="hcf_author">Author</label> <input id="hcf_author" type="text" name="hcf_author" value="<?php echo esc_attr( get_post_meta( get_the_ID(), 'hcf_author', true ) ); ?>"> </p> <p class="meta-options hcf_field"> <label for="hcf_published_date">Published Date</label> <input id="hcf_published_date" type="date" name="hcf_published_date" value="<?php echo esc_attr( get_post_meta( get_the_ID(), 'hcf_published_date', true ) ); ?>"> </p> <p class="meta-options hcf_field"> <label for="hcf_price">Price</label> <input id="hcf_price" type="number" name="hcf_price" value="<?php echo esc_attr( get_post_meta( get_the_ID(), 'hcf_price', true ) ); ?>"> </p> </div>
Then, the result is:
We have done creating, adding custom fields to the edit screen, and saving the custom fields values. That's all for the backend. And our simple plugin is done!
Now let's get the custom fields’ values and display them on the frontend. So, we'll need to modify our theme's files a little bit.
Get and Display Custom Fields in the Frontend
To get the custom fields values, all we need to do is using the get_post_meta
function. We have talked about this in the previous post. The code doesn't change too much:
<ul> <li><strong>Author: </strong><?php echo esc_attr( get_post_meta( get_the_ID(), 'hcf_author', true ) ); ?></li> <li><strong>Published Date: </strong><?php echo esc_attr( get_post_meta( get_the_ID(), 'hcf_published_date', true ) ); ?></li> <li><strong>Price: </strong><?php echo esc_attr( get_post_meta( get_the_ID(), 'hcf_price', true ) ); ?></li> </ul>
Get Custom Fields Values Outside the Loop
The get_post_meta
function requires a mandatory parameter for the post ID. If you want to get custom field data from any post outside the loop, you need to know its ID. There are many ways to get it.
Hardcode the Post ID
There are many ways to hardcode. You may use post ID directly in the get_post_meta
function as below:
get_post_meta( 12, 'hcf_author', true );
Or, define it in a file of that function:
// In the wp-config.php file define( MY_POST_ID, 12 ); // In the theme's file echo get_post_meta( MY_POST_ID, 'hcf_author', true);
However, the hardcode is not encouraged. If you make some queries to get posts, then you can use the ID of the queried posts and pass it to the get_post_meta
function.
Get the Post ID from Queries
The following code demonstrates getting field's value from a post in a custom query:
$the_slug = 'my_slug'; $args = array( 'name' => $the_slug, 'post_type' => 'post', 'post_status' => 'publish', 'posts_per_page' => 1, ); $my_posts = get_posts( $args ); $my_post = current( $my_posts ); if ( $my_post ) { echo get_post_meta( $my_post->ID, 'hcf_author', true ); }
Conclusion
Creating your own custom field requires some codes. But it gives you the full power to decide using which field type to use to fit your needs. Although, it also means that you are responsible for handling the data.
You can create any field type you want, even the most complicated field types such as gallery or repeater field. It depends only on your coding skill and imagination.
However, if you find it takes a lot of time and effort, you can use other custom field plugins from some third parties, for example, our Meta Box plugin. If you use it, we already have a tutorial on how to create custom fields with Meta Box plugin. By the way, our Meta Box plugin provides not only a simple way to create various types of custom fields, but ways to display them on the frontend as a form, save them in a custom table, display them on the frontend with simple action, etc. Those features will benefit you a lot, so we highly recommend you use it instead of creating your own plugin.
Back to the meaning of the custom fields, it is the implementation of the metadata architecture. Custom fields give us more information about objects (posts). However, until now, we only use it to store the data and display the data. However, one of the most popular applications of the custom fields is getting posts based on their value. Let's talk about that later in this series.
Hey in new wordpress while updating the meta fields it is also adding the fields in wordpress default custom fields. Any idea whats going wrong?
Nothing wrong with that. The meta boxes is just another UI that we as developers provide to users to easier enter the data. The data is still saved in WordPress default custom fields. And if you have the "Custom Fields" meta box enabled in the edit screen, you'll see their value.
I've set a metabox for pages, with just a checkbox. It works fine with every page except with the loop page. I've printed out the value of post_meta and it's practically empty, except a "_edit_lock" value.
This tutorial is really unique
I did this in several other sources, but I did not succeed
I've done this by watching your tutorial in 3 minutes
if i want to add a button to allow the user to enter more than one price without having price field one and two, how can i do that?
You can do that with the Meta Box plugin and set the field price clonable.
Dude, THIS is a nice tutorial. Thanks S2
Isn't a nonce field necessary to protect against input from other sources?
i need to change author names on each post i created, how do i use custom meta box field to create post by author names, without creating a user profile, let say am the admin, if i post it shows my name always in every post, if i want to change each post author name let say assign different name to each post, not creating a user profile and using the user profile name as the author of the post, just changing each post author name to different name of my choice, let enterainment post, i will assign a name for each entertainment category i.e full name how do i do that
Hi
I used the radio button where you used the number but my data is not stored in database.
Can you please help me ?
You rock! Exactly what I needed and man you are so good at explaining and displaying your code. Really helped me out.
nice post thanks...
vary helpful article for my custom WordPress plugin development.
I want to save one of the meta box value which is a multiple select box field. So for that my form field looks like:
select name="gn_time[]" multiple="multiple" ....
However, when I save the meta value, the multiple selected values (array) is not stored in the meta value in database.
If you use the Meta Box plugin, the value is saved automatically. If not, you need to write some code to save them