New Version 1.0.0 is here

Custom fields for every corner of WordPress

Wonder Fields lets you add structured content to posts, pages, users, terms, menus, options pages and blocks. Build field groups visually, then show the values in your theme with one line of PHP.

  • Free and GPL licensed
  • Block and classic editor
  • Familiar get_field() API
Wonder Fields › Field Groups › Edit

Team section

● Active
Section titlesection_titleText
IntrointroWYSIWYG
Team membersteamRepeater
NamenameText
PhotophotoImage
Show this group ifPost Typeis equal toPageandPage TemplateisAbout
35field types, from text to flexible content
22location rules to target any edit screen
21template functions for themes
5+page builders with dynamic data
Features

Everything your content model needs, in one plugin

Design the editing experience your clients see, and keep full control of how data is stored and displayed.

Visual field groups

Drag fields into place, set labels, defaults and instructions, and group them with tabs and accordions.

Location rules and logic

Show a group only where it belongs with AND / OR rules, and hide fields based on other answers with conditional logic.

Repeaters and flexible content

Let editors add rows or pick from layouts to build sections like team lists, FAQs and page builders of your own.

Custom blocks in PHP

Register Gutenberg blocks with wf_register_block_type() and render them from a plain PHP template.

Post types, taxonomies, options

Create custom post types, taxonomies and site-wide options pages from the admin, with no extra plugin.

Local JSON and REST API

Keep field settings in version control as JSON, and read or update values through the WordPress REST API.

Also includedExport and import JSONGenerate PHPField validationShortcodePrefixed wf_ functionsGoogle MapsFront-end forms
Field types

35 field types, ready out of the box

Pick a category to see what each field stores. The code name in grey is the value you choose for type when registering fields in PHP.

Repeaters and layouts

Give editors room to grow content without breaking the design.

A repeater holds any number of rows of sub fields. Flexible content goes further: editors choose a layout for each row, and your template decides how each one looks.

  • Loop rows with have_rows() and the_row()
  • Read the layout name with get_row_layout()
  • Add or change rows in code with add_row() and update_row()
Team members · Repeater
1Asha MenonDesign lead
2Daniel OrtizDeveloper
3Mei TanakaContent strategist
+ Add row
HeroText and imageGalleryCall to actionTestimonials
Blocks

Build Gutenberg blocks with the PHP you already write.

Register a block, attach a field group to it, and render it from a template file. Editors fill in fields in the sidebar and see a live preview in the editor.

  • Blocks are named wf/your-block automatically
  • Templates get $block, $is_preview and $post_id
  • Use get_field() inside the template as usual
Block editor · Testimonial

“We rebuilt our whole site structure in an afternoon.”

Priya Raman, Studio North
We rebuilt our whole site structure in an afternoon.
Priya Raman, Studio North
Local JSON

Field settings that live in your theme and your Git history.

Every time you save a field group, post type, taxonomy or options page, Wonder Fields writes a JSON file to your theme. Deploy it to another site and sync it with one click.

  • Saved to wonder-fields-json/ in the active theme
  • Change the folder with the save_json and load_json filters
  • Faster loading, because groups come from files
your-theme/
├── functions.php
├── template-parts/blocks/testimonial.php
└── wonder-fields-json/
    ├── group_hero.json
    ├── group_team.json
    └── group_testimonial.json  new
1 field group has changes to syncSync available
How it works

From install to live content in three steps

1

Install and activate

Upload the plugin zip from Plugins › Add New › Upload Plugin and activate it. A Wonder Fields menu appears in the admin.

2

Build a field group

Add fields, choose where the group shows with location rules, and publish. Editors see the fields on their edit screens right away.

3

Show it in your theme

Print values with the_field(), loop repeaters with have_rows(), or connect fields in your page builder.

User guide

Learn Wonder Fields, step by step

Start at the top if you are new. Each section is short and includes code you can copy into your theme.

01

Install the plugin

Wonder Fields needs WordPress 6.0 or newer and PHP 7.4 or newer.

  1. In your WordPress admin, go to Plugins›Add New›Upload Plugin.
  2. Choose wonder-fields.zip and click Install Now. You can also upload the wonder-fields folder to /wp-content/plugins/ by FTP.
  3. Click Activate. A Wonder Fields menu appears in the admin sidebar with Field Groups, Post Types, Taxonomies, Options Pages, Tools and Settings.
Using the Google Map field? Add a Google Maps JavaScript API key under Wonder Fields › Settings, or set it in code with the wonder_fields/settings/google_api_key filter.
02

Create your first field group

A field group is a set of fields that appears together on an edit screen. Here is how to add a subtitle and hero image to every page.

  1. Go to Wonder Fields›Field Groups›Add New and name the group, for example Hero.
  2. Click Add Field. Enter the Label (what editors see) and check the Name (what you use in code, such as subtitle). Choose the field type.
  3. Add a second field called hero_image with the Image type.
  4. Under Location, choose Post Type is equal to Page.
  5. Click Publish. Open any page and the Hero fields are there, ready to fill in.
Field names must be unique within a group. Use lowercase letters and underscores, for example hero_image.
03

Choose where fields appear

Location rules decide which edit screens show a group. Rules in the same row must all match (AND). Add a rule group to show the fields when either set matches (OR).

AreaRules you can use
PostsPost Type, Post Template, Post Status, Post Format, Post Category, Post Taxonomy, Post
PagesPage Template, Page Type (front page, posts page, top level, parent, child), Page Parent, Page
UsersCurrent User, Current User Role, User Form, User Role
Other screensTaxonomy, Attachment, Comment, Widget, Menu Item, Block, Options Page
04

Show fields only when needed

Conditional logic keeps edit screens tidy. Open a field, turn on Conditional Logic, and pick the field and value it depends on.

For example, add a True / False field called has_video, then give an oEmbed field the rule has_video is checked. The video field only appears once the box is ticked. Hidden fields are skipped when the post is validated and saved.

05

Show values in your theme

Use the_field() to print a value and get_field() to get it for use in your own markup. Both read from the current post unless you pass a post ID.

page.php
<h2><?php the_field( 'subtitle' ); ?></h2>

<?php
$image = get_field( 'hero_image' );
if ( $image ) {
    echo wp_get_attachment_image( $image['ID'], 'large' );
}

// Read from another post.
$price = get_field( 'price', 42 );
?>

All 21 functions: get_field, the_field, get_fields, get_field_object, get_field_objects, update_field, delete_field, have_rows, the_row, get_row, get_row_layout, get_row_index, reset_rows, get_sub_field, the_sub_field, get_sub_field_object, update_sub_field, delete_sub_field, add_row, update_row, delete_row.

Every function also has a wf_ version, such as wf_get_field(). It is always available, even if another plugin already defines the unprefixed name.
06

Loop through a repeater

Create a Repeater field called team with sub fields name and role. Then loop the rows in your template:

template-parts/team.php
<?php if ( have_rows( 'team' ) ) : ?>
    <ul class="team">
    <?php while ( have_rows( 'team' ) ) : the_row(); ?>
        <li>
            <h3><?php the_sub_field( 'name' ); ?></h3>
            <p><?php the_sub_field( 'role' ); ?></p>
        </li>
    <?php endwhile; ?>
    </ul>
<?php endif; ?>
07

Build pages with flexible content

A Flexible Content field holds rows that each use one of several layouts. Check the layout name for each row and output the right markup.

page-builder.php
<?php while ( have_rows( 'sections' ) ) : the_row();

    if ( 'hero' === get_row_layout() ) {
        get_template_part( 'sections/hero' );
    } elseif ( 'gallery' === get_row_layout() ) {
        get_template_part( 'sections/gallery' );
    }

endwhile; ?>
08

Read values from users, terms and options

Pass a second argument to say where the value is stored.

WherePass as post IDExample
A post or pageThe ID or a WP_Postget_field( 'price', 42 )
Options pageoption or optionsget_field( 'phone', 'option' )
Useruser_{ID} or WP_Userget_field( 'bio', 'user_7' )
Termterm_{ID} or {taxonomy}_{ID}get_field( 'color', 'category_3' )
Commentcomment_{ID}get_field( 'rating', 'comment_12' )
Widgetwidget_{ID}get_field( 'title', 'widget_text-2' )
09

Add a site settings page

Options pages hold values that apply to the whole site, like a phone number or social links. Create one under Wonder Fields›Options Pages, or in code:

functions.php
wf_add_options_page( array(
    'page_title' => 'Site Settings',
    'menu_slug'  => 'site-settings',
) );

Then set a field group's location to Options Page is equal to Site Settings, and read values with get_field( 'phone', 'option' ).

10

Create a custom block

Register the block in functions.php, create a field group with the location Block is equal to Testimonial, and write the template.

functions.php
add_action( 'init', function () {
    wf_register_block_type( array(
        'name'            => 'testimonial',
        'title'           => 'Testimonial',
        'icon'            => 'format-quote',
        'render_template' => 'template-parts/blocks/testimonial.php',
    ) );
} );
template-parts/blocks/testimonial.php
<blockquote class="testimonial">
    <p><?php the_field( 'quote' ); ?></p>
    <cite><?php the_field( 'author' ); ?></cite>
</blockquote>

The block is registered as wf/testimonial. Templates also receive $block, $content, $is_preview and $post_id.

11

Register field groups in code

Groups registered in PHP load fast and can't be changed by accident in the admin. Tip: build a group in the admin first, then use Tools›Generate PHP to get this code for you.

functions.php
add_action( 'wonder_fields/include_fields', function () {
    wf_add_local_field_group( array(
        'key'      => 'group_hero',
        'title'    => 'Hero',
        'fields'   => array(
            array(
                'key'   => 'field_hero_title',
                'name'  => 'hero_title',
                'label' => 'Title',
                'type'  => 'text',
            ),
        ),
        'location' => array(
            array(
                array( 'param' => 'post_type', 'operator' => '==', 'value' => 'page' ),
            ),
        ),
    ) );
} );
12

Local JSON, export and import

  • Local JSON. Create a wonder-fields-json folder in your active theme. Field groups, post types, taxonomies and options pages are saved there as JSON whenever you save them.
  • Sync. When a JSON file is newer than the database copy, the Field Groups list shows Sync available. Click it to update the site.
  • Export and import. Under Wonder Fields›Tools, export groups as a JSON file, import a file on another site, or generate PHP.
functions.php
// Save JSON to a custom folder.
add_filter( 'wonder_fields/settings/save_json', function () {
    return get_stylesheet_directory() . '/fields';
} );
13

Use the REST API

Turn on Show in REST API in a field group's settings. Its values then appear in a wonder_fields property on /wp/v2 responses, and you can update them by sending the same property back.

Response from GET /wp-json/wp/v2/pages/42
{
    "id": 42,
    "title": { "rendered": "About" },
    "wonder_fields": {
        "subtitle": "Meet the people behind it",
        "hero_image": 318
    }
}
14

Customise with hooks

Most filters also accept /type=, /name= and /key= variants, so you can target one field type, one field name or one field key.

HookUse it to
wonder_fields/save_postRun code after values are saved. Use a priority below 10 to run before.
wonder_fields/load_valueChange a value as it is loaded from the database.
wonder_fields/update_valueChange a value before it is saved.
wonder_fields/format_valueChange the value your template receives.
wonder_fields/validate_valueAdd your own validation errors.
wonder_fields/prepare_fieldChange or hide a field just before it is shown.
wonder_fields/load_fieldChange field settings when they load.
functions.php
// Require a subtitle of at least 10 characters.
add_filter( 'wonder_fields/validate_value/name=subtitle', function ( $valid, $value ) {
    if ( strlen( $value ) < 10 ) {
        return 'Please write at least 10 characters.';
    }
    return $valid;
}, 10, 2 );
Page builders

Works with the builder you already use

Connect fields to text, images and links without writing a template.

Elementor Pro

Dynamic tags in a "Wonder Fields" group for text, URL, image, gallery, number and color.

Bricks

Use {wf_fieldname}, or {wf_fieldname:option} for options pages.

Beaver Builder Themer

Pick fields from "Wonder Fields" field connections.

Divi

Fields are listed under Dynamic Content in any module.

Oxygen

Find fields under Dynamic Data › Wonder Fields.

Anywhere else

[wonder_field name="subtitle"] with optional post_id. Add format="0" for the raw value.

FAQs

Questions, answered

Is Wonder Fields free?

Yes. Wonder Fields is released under the GPLv2 or later license, with every field type and feature included.

I already use ACF. Will my templates still work?

Wonder Fields uses the same function names, such as get_field(), have_rows() and the_sub_field(). If another plugin already defines those names, use the wf_ versions like wf_get_field(), which are always available.

Does it work with the block editor and the classic editor?

Yes. Field groups appear in both, and you can build your own Gutenberg blocks with wf_register_block_type().

Where are my values stored?

In the standard WordPress meta tables for posts, users, terms and comments, and in options for options pages. Your content stays in your database.

How do I move field groups between sites?

Use Local JSON and commit the wonder-fields-json folder with your theme, or export a JSON file from Wonder Fields › Tools and import it on the other site.

Are password field values ever shown on the front end?

No. The shortcode and page builder integrations never output password fields.

What do I need to run it?

WordPress 6.0 or newer and PHP 7.4 or newer. The Google Map field also needs a Google Maps JavaScript API key.

Shape your content, your way

Install Wonder Fields, build your first field group and see it on the page in minutes.