Custom Fields are a way to assign post specific data in WordPress. These, can then be displayed in your dynamic templates and/or custom cards. Many designers choose to use custom fields as the primary way to structure their client sites.
A WordPress site structured around custom fields offers a user-friendly and intuitive interface for clients. When editing a post, particularly custom post types, clients can easily fill out the provided fields without having to navigate a page builder or, even more frustrating, Gutenberg.
There are 2 ways you can register custom fields in the Total theme; using a plugin or via the built-in PHP class. In this article I will first go over which plugin I recommend (ACF)
TL;DR: Download, install and use the Advanced Custom Fields plugin.
Recommended Custom Field Plugin: ACF
The only plugin I personally recommend for adding custom fields is going to be the Advanced Custom Fields Plugin (ACF) – this plugin is entirely free, although the Pro version offers some amazing extended functionality.
ACF is managed and developed by WPEngine which is one of the best WordPress hosting companies out there and we actually use their hosting ourselves. They are a well known and reputable brand in the WordPress space. This means, the plugin is unlikely to be abandoned and should receive continual updates and support.
And using Advanced Custom Fields is extremely easy, it adds a whole UI to your WP admin where you can easily add custom fields to your posts, pages, taxonomies and even create a custom theme panel with extra settings for your site.

Using ACF Fields in Total Elements
Total offers seamless integration with Advanced Custom Fields (ACF) in various ways. One of the standout features is the ability to select your registered fields when working with theme elements. Here is a sample screenshot from the Image element when set to display an image assigned via a custom field:

This makes it simple to incorporate custom field data directly into your page layouts.
Benefits of using ACF
Here are some of the reasons why you would want to use ACF over other solutions for implementing custom fields:
- User-friendly UI for easily adding and managing your fields.
- Ability to assign fields to pages, posts and taxonomies.
- Easily select your custom fields in theme elements; no need to remember all your field names.
- Built-in support for advanced fields: gallery, relationship & repeater fields.
Do You Need ACF Pro?
ACF Free has everything most customers will need so you don’t necessarily need the pro version. However, it includes some additional fields that can be very useful. The most impactful Pro feature is probably the repeater field.
With the repeater field you can create repeating content – for example, if you’re building a staff or team directory, you might need to repeat the structure for each team member. The repeater field can hold details like name, position, bio, and social media links for every staff member, and it can be repeated as needed. You can display the ACF repeater field data using the Total’s exclusive ACF Repeater Template element.
By the way, we are currently not an affiliate of ACF (I don’t think they even have an affiliate program). We recommend ACF Pro because it’s awesome.
Custom Fields Built-in PHP Class
If all you need is to add custom fields to posts or pages and you rather not use a plugin, Total has a handy PHP class that can be used instead. This will allow you to register custom fields via your child theme. Below is an example of how you can use the class:
/**
* Register custom fields.
*/
function my_register_custom_metaboxes() {
if ( ! class_exists( 'WPEX_Meta_Factory' ) || ! is_admin() ) {
return;
}
new WPEX_Meta_Factory( array(
'id' => 'YOUR_UNIQUE_METABOX_ID',
'title' => esc_html__( 'Metabox Title', 'text_domain' ),
'screen' => array( 'post', 'page', 'portfolio' ), //post types to add the metabox to
'context' => 'normal',
'priority' => 'default',
// @important since Total Theme Core v1.7.1 you can now pass a function that returns the fields to prevent
// the fields from being stored in memory and so they are only called when needed.
'fields' => array(
// Select Field
array(
'name' => esc_html__( 'Select example', 'text_domain' ),
'desc' => esc_html__( 'Custom description if needed', 'text_domain' ),
'id' => 'YOUR_UNIQUE_CUSTOM_FIELD_NAME',
'type' => 'select',
'choices' => array(
'' => esc_html__( 'Choice 1', 'text_domain' ),
'option-2' => esc_html__( 'Choice 2', 'text_domain' ),
),
),
// Button Group Field
array(
'name' => esc_html__( 'Button Select example', 'text_domain' ),
'id' => 'YOUR_UNIQUE_CUSTOM_FIELD_NAME',
'type' => 'button_group',
'choices' => array(
'' => esc_html__( 'Choice 1', 'text_domain' ),
'option-2' => esc_html__( 'Choice 2', 'text_domain' ),
),
),
// Checkbox Field
array(
'name' => esc_html__( 'Checkbox example', 'text_domain' ),
'id' => 'YOUR_UNIQUE_CUSTOM_FIELD_NAME',
'type' => 'checkbox',
),
// Text Field
array(
'name' => esc_html__( 'Text Type', 'text_domain' ),
'id' => 'YOUR_UNIQUE_CUSTOM_FIELD_NAME',
'type' => 'text',
),
// HTML Field
array(
'name' => esc_html__( 'Text Type', 'text_domain' ),
'id' => 'YOUR_UNIQUE_CUSTOM_FIELD_NAME',
'type' => 'text',
'allow_html' => true,
),
// Textarea Field
array(
'name' => esc_html__( 'Textarea Type', 'text_domain' ),
'id' => 'YOUR_UNIQUE_CUSTOM_FIELD_NAME',
'type' => 'textarea',
),
// URL Field
array(
'name' => esc_html__( 'URL Type', 'text_domain' ),
'id' => 'YOUR_UNIQUE_CUSTOM_FIELD_NAME',
'type' => 'url',
),
// Date Field
array(
'name' => esc_html__( 'Date Type', 'text_domain' ),
'id' => 'YOUR_UNIQUE_CUSTOM_FIELD_NAME',
'type' => 'date',
),
// Upload Field
array(
'name' => esc_html__( 'Upload Type', 'text_domain' ),
'id' => 'YOUR_UNIQUE_CUSTOM_FIELD_NAME',
'type' => 'upload',
'return' => 'id', // return ID or URL
),
// Group Field
array(
'name' => esc_html__( 'Group/Repeater Type', 'text_domain' ),
'id' => 'YOUR_UNIQUE_CUSTOM_FIELD_NAME',
'type' => 'group',
'group_sort' => true, // allow drag/drop sorting of the fields
'group_title' => esc_html__( 'The Title for each group item (optional)', 'text_domain' ),
'fields' => array(
// Add your repeater fields here
),
),
)
) );
}
add_action( 'admin_init', 'my_register_custom_metaboxes' );
For each metabox you want to add you will create a new instance of the WPEX_Meta_Factory
class and pass an array of your parameters.
The following field types are available:
- text
- textarea
- date
- url
- number
- iframe
- html
- wp_editot
- select
- button_group
- checkbox
- color
- icon_select
- multi_select
- upload
- group
- select_template
Benefits of using the PHP Class
Here are the benefits of using the PHP class.
- No need for 3rd party plugins.
- The end user can’t modify the fields and mess things up.
- Easy to use; the theme handles the creation of the custom field UI and saving of the fields.
I would recommend adding the code for your custom fields in their own files; one file for each class to keep things neat and clean. And also loading these files only when is_admin
returns true.