WordPress ACF Field Generator

Build Advanced Custom Fields groups visually and export acf_add_local_field_group() PHP plus escaped template code.

Runs in your browser

Field group

Location rules

Show this field group if…

Common values: post, page, attachment, product

Presentation & settings

Lower numbers appear first.

Adds an acf object to REST responses (ACF 6.1+).

Hide on screen

Fields (11)

Repeater and Gallery fields require ACF PRO. The free version ignores them.
show_in_rest exposes these values in the REST API (ACF 6.1+). Do not enable it for private data.

PHP — acf_add_local_field_group()

add_action( 'acf/include_fields', function () {
	if ( ! function_exists( 'acf_add_local_field_group' ) ) {
		return;
	}

	acf_add_local_field_group( array(
		'key'                   => 'group_c0c458a52dd37',
		'title'                 => 'Book Details',
		'fields'                => array(
			array(
				'key'               => 'field_c2a0d1246d8ab',
				'label'             => 'General',
				'name'              => '',
				'aria-label'        => '',
				'type'              => 'tab',
				'instructions'      => '',
				'required'          => 0,
				'conditional_logic' => 0,
				'wrapper'           => array(
					'width' => '',
					'class' => '',
					'id'    => '',
				),
				'placement'         => 'top',
				'endpoint'          => 0,
				'selected'          => 0,
			),
			array(
				'key'               => 'field_e5a728fb9a018',
				'label'             => 'Subtitle',
				'name'              => 'subtitle',
				'aria-label'        => '',
				'type'              => 'text',
				'instructions'      => '',
				'required'          => 0,
				'conditional_logic' => 0,
				'wrapper'           => array(
					'width' => '50',
					'class' => '',
					'id'    => '',
				),
				'default_value'     => '',
				'maxlength'         => '',
				'placeholder'       => 'A short tagline',
				'prepend'           => '',
				'append'            => '',
			),
			array(
				'key'               => 'field_303f17df4421b',
				'label'             => 'ISBN',
				'name'              => 'isbn',
				'aria-label'        => '',
				'type'              => 'text',
				'instructions'      => '13-digit ISBN without dashes.',
				'required'          => 1,
				'conditional_logic' => 0,
				'wrapper'           => array(
					'width' => '50',
					'class' => '',
					'id'    => '',
				),
				'default_value'     => '',
				'maxlength'         => '',
				'placeholder'       => '',
				'prepend'           => '',
				'append'            => '',
			),
			array(
				'key'               => 'field_b1f86888f6e96',
				'label'             => 'Cover Image',
				'name'              => 'cover_image',
				'aria-label'        => '',
				'type'              => 'image',
				'instructions'      => '',
				'required'          => 0,
				'conditional_logic' => 0,
				'wrapper'           => array(
					'width' => '',
					'class' => '',
					'id'    => '',
				),
				'return_format'     => 'array',
				'library'           => 'all',
				'min_width'         => '',
				'min_height'        => '',
				'min_size'          => '',
				'max_width'         => '',
				'max_height'        => '',
				'max_size'          => '',
				'mime_types'        => '',
				'preview_size'      => 'medium',
			),
			array(
				'key'               => 'field_17757da0b6240',
				'label'             => 'Format',
				'name'              => 'format',
				'aria-label'        => '',
				'type'              => 'select',
				'instructions'      => '',
				'required'          => 0,
				'conditional_logic' => 0,
				'wrapper'           => array(
					'width' => '',
					'class' => '',
					'id'    => '',
				),
				'choices'           => array(
					'hardcover' => 'Hardcover',
					'paperback' => 'Paperback',
					'ebook'     => 'E-book',
					'audiobook' => 'Audiobook',
				),
				'default_value'     => 'paperback',
				'return_format'     => 'value',
				'multiple'          => 0,
				'allow_null'        => 0,
				'ui'                => 0,
				'ajax'              => 0,
				'placeholder'       => '',
			),
			array(
				'key'               => 'field_5c8388b09c4b6',
				'label'             => 'Price',
				'name'              => 'price',
				'aria-label'        => '',
				'type'              => 'number',
				'instructions'      => 'Price in USD.',
				'required'          => 0,
				'conditional_logic' => 0,
				'wrapper'           => array(
					'width' => '',
					'class' => '',
					'id'    => '',
				),
				'default_value'     => '',
				'min'               => 0,
				'max'               => '',
				'placeholder'       => '',
				'step'              => 0.01,
				'prepend'           => '',
				'append'            => '',
			),
			array(
				'key'               => 'field_23bf34d0774d9',
				'label'             => 'Publication Date',
				'name'              => 'publication_date',
				'aria-label'        => '',
				'type'              => 'date_picker',
				'instructions'      => '',
				'required'          => 0,
				'conditional_logic' => 0,
				'wrapper'           => array(
					'width' => '',
					'class' => '',
					'id'    => '',
				),
				'display_format'    => 'F j, Y',
				'return_format'     => 'F j, Y',
				'first_day'         => 1,
			),
			array(
				'key'               => 'field_e2f991fd4bd53',
				'label'             => 'Featured',
				'name'              => 'featured',
				'aria-label'        => '',
				'type'              => 'true_false',
				'instructions'      => '',
				'required'          => 0,
				'conditional_logic' => 0,
				'wrapper'           => array(
					'width' => '',
					'class' => '',
					'id'    => '',
				),
				'message'           => 'Show this book on the home page',
				'default_value'     => 0,
				'ui'                => 1,
				'ui_on_text'        => '',
				'ui_off_text'       => '',
			),
			array(
				'key'               => 'field_c318e95b91164',
				'label'             => 'Extras',
				'name'              => '',
				'aria-label'        => '',
				'type'              => 'tab',
				'instructions'      => '',
				'required'          => 0,
				'conditional_logic' => 0,
				'wrapper'           => array(
					'width' => '',
					'class' => '',
					'id'    => '',
				),
				'placement'         => 'top',
				'endpoint'          => 0,
				'selected'          => 0,
			),
			array(
				'key'               => 'field_f8f2d156abec4',
				'label'             => 'Buy Link',
				'name'              => 'buy_link',
				'aria-label'        => '',
				'type'              => 'link',
				'instructions'      => '',
				'required'          => 0,
				'conditional_logic' => 0,
				'wrapper'           => array(
					'width' => '',
					'class' => '',
					'id'    => '',
				),
				'return_format'     => 'array',
			),
			array(
				'key'               => 'field_68461c1470646',
				'label'             => 'Reviews',
				'name'              => 'reviews',
				'aria-label'        => '',
				'type'              => 'repeater',
				'instructions'      => '',
				'required'          => 0,
				'conditional_logic' => 0,
				'wrapper'           => array(
					'width' => '',
					'class' => '',
					'id'    => '',
				),
				'layout'            => 'block',
				'pagination'        => 0,
				'min'               => '',
				'max'               => '',
				'collapsed'         => '',
				'button_label'      => 'Add review',
				'rows_per_page'     => 20,
				'sub_fields'        => array(
					array(
						'key'               => 'field_394ab86bafb65',
						'label'             => 'Quote',
						'name'              => 'quote',
						'aria-label'        => '',
						'type'              => 'textarea',
						'instructions'      => '',
						'required'          => 0,
						'conditional_logic' => 0,
						'wrapper'           => array(
							'width' => '',
							'class' => '',
							'id'    => '',
						),
						'parent_repeater'   => 'field_68461c1470646',
						'default_value'     => '',
						'maxlength'         => '',
						'rows'              => 3,
						'placeholder'       => '',
						'new_lines'         => '',
					),
					array(
						'key'               => 'field_cccff6ce3e316',
						'label'             => 'Reviewer',
						'name'              => 'reviewer',
						'aria-label'        => '',
						'type'              => 'text',
						'instructions'      => '',
						'required'          => 0,
						'conditional_logic' => 0,
						'wrapper'           => array(
							'width' => '',
							'class' => '',
							'id'    => '',
						),
						'parent_repeater'   => 'field_68461c1470646',
						'default_value'     => '',
						'maxlength'         => '',
						'placeholder'       => '',
						'prepend'           => '',
						'append'            => '',
					),
					array(
						'key'               => 'field_134429ca9341a',
						'label'             => 'Source URL',
						'name'              => 'source_url',
						'aria-label'        => '',
						'type'              => 'url',
						'instructions'      => '',
						'required'          => 0,
						'conditional_logic' => 0,
						'wrapper'           => array(
							'width' => '',
							'class' => '',
							'id'    => '',
						),
						'parent_repeater'   => 'field_68461c1470646',
						'default_value'     => '',
						'placeholder'       => '',
					),
				),
			),
		),
		'location'              => array(
			array(
				array(
					'param'    => 'post_type',
					'operator' => '==',
					'value'    => 'book',
				),
			),
		),
		'menu_order'            => 0,
		'position'              => 'acf_after_title',
		'style'                 => 'default',
		'label_placement'       => 'top',
		'instruction_placement' => 'label',
		'hide_on_screen'        => '',
		'active'                => true,
		'description'           => 'Extra information shown on single book pages.',
		'show_in_rest'          => 1,
	) );
} );

Template usage

<?php
/**
 * Template usage for “Book Details”.
 * Use inside the loop (e.g. single.php). Outside it, pass the post ID:
 * get_field( 'name', $post_id ). For options pages use 'option' as the ID.
 * Tip: the_field( 'name' ) echoes a value directly; since ACF 6.2.5 it is escaped.
 */
// Subtitle (Text)
$subtitle = get_field( 'subtitle' );
if ( $subtitle ) {
	echo '<p>' . esc_html( $subtitle ) . '</p>';
}
// Shorthand: the_field( 'subtitle' ); (escaped since ACF 6.2.5)

// ISBN (Text)
$isbn = get_field( 'isbn' );
if ( $isbn ) {
	echo '<p>' . esc_html( $isbn ) . '</p>';
}
// Shorthand: the_field( 'isbn' ); (escaped since ACF 6.2.5)

// Cover Image (Image)
$cover_image = get_field( 'cover_image' );
if ( $cover_image ) {
	echo wp_get_attachment_image( $cover_image['ID'], 'large' );
}

// Format (Select)
$format = get_field( 'format' );
if ( $format ) {
	echo '<p>' . esc_html( $format ) . '</p>';
}

// Price (Number)
$price = get_field( 'price' );
if ( is_numeric( $price ) ) {
	echo '<p>' . esc_html( $price ) . '</p>';
}
// Shorthand: the_field( 'price' ); (escaped since ACF 6.2.5)

// Publication Date (Date Picker)
$publication_date = get_field( 'publication_date' );
if ( $publication_date ) {
	echo '<p>' . esc_html( $publication_date ) . '</p>';
}
// Shorthand: the_field( 'publication_date' ); (escaped since ACF 6.2.5)

// Featured (True / False)
$featured = get_field( 'featured' );
if ( $featured ) {
	// Featured is checked.
}

// Buy Link (Link)
$buy_link = get_field( 'buy_link' );
if ( $buy_link ) {
	$link_target = $buy_link['target'] ? $buy_link['target'] : '_self';
	echo '<a href="' . esc_url( $buy_link['url'] ) . '" target="' . esc_attr( $link_target ) . '">' . esc_html( $buy_link['title'] ) . '</a>';
}

// Reviews (Repeater)
if ( have_rows( 'reviews' ) ) {
	echo '<ul>';
	while ( have_rows( 'reviews' ) ) {
		the_row();
		echo '<li>';
		// Quote (Text Area)
		$quote = get_sub_field( 'quote' );
		if ( $quote ) {
			echo '<p>' . esc_html( $quote ) . '</p>';
		}

		// Reviewer (Text)
		$reviewer = get_sub_field( 'reviewer' );
		if ( $reviewer ) {
			echo '<p>' . esc_html( $reviewer ) . '</p>';
		}
		// Shorthand: the_sub_field( 'reviewer' );

		// Source URL (URL)
		$source_url = get_sub_field( 'source_url' );
		if ( $source_url ) {
			echo '<a href="' . esc_url( $source_url ) . '">' . esc_html( $source_url ) . '</a>';
		}
		echo '</li>';
	}
	echo '</ul>';
}
Keys are deterministic
Group key group_c0c458a52dd37 and every field key are derived from the group title and field names, so regenerating the same structure gives the same keys. Renaming a field changes its key — existing values are still found by name.

Registering ACF field groups in PHP

Advanced Custom Fields (ACF) lets you add structured data — a subtitle, a price, a gallery, a list of team members — to posts, pages, terms, users, options pages and blocks. Field groups are usually built in the admin UI and stored in the database, but for themes and plugins you ship to clients it is far better to register them in code with acf_add_local_field_group(): the fields are version-controlled, deploy with your code, cannot be broken by an editor, and load without a database query.

Writing those arrays by hand is tedious and error-prone. Every field needs a unique key, a name, the right type-specific settings and correctly nested location rules, and repeaters need parent_repeater references. This builder gives you the ACF editing experience in the browser and outputs clean PHP in the same shape ACF’s own exporter produces, hooked to acf/include_fields (ACF 6+) with a function_exists() guard so your site never fatals when ACF is deactivated.

A second panel writes the template code for every field: get_field() with the correct escaping for its type (esc_html(), esc_url(), wp_kses_post(), wp_get_attachment_image()), have_rows() loops for repeaters and array access for groups — ready to paste into single.php or a block template.

How to use the WordPress ACF Field Generator

  1. Click Load sample to explore a complete group, or Start blank. Give the group a title and set location rules — rules in one box are AND, separate boxes are OR.
  2. Add fields, choose their type and expand each card to set the label, name, instructions and type-specific options such as choices, return format or post-type filters.
  3. Use the arrows to reorder fields, and add sub fields to Group and Repeater fields. Errors such as duplicate names are highlighted in red.
  4. Copy the PHP into your theme’s functions.php, a plugin or an inc/acf-fields.php file that you include.
  5. Copy the template usage code into your template and adjust the markup.

Example

The generated structure for a single text field (keys are deterministic hashes):

add_action( 'acf/include_fields', function () {
	if ( ! function_exists( 'acf_add_local_field_group' ) ) {
		return;
	}

	acf_add_local_field_group( array(
		'key'      => 'group_7c1f0a3e9b2d4',
		'title'    => 'Book Details',
		'fields'   => array(
			array(
				'key'   => 'field_3e8a91c07f5b2',
				'label' => 'Subtitle',
				'name'  => 'subtitle',
				'type'  => 'text',
			),
		),
		'location' => array( array( array( 'param' => 'post_type', 'operator' => '==', 'value' => 'book' ) ) ),
	) );
} );

Things worth knowing

  • Keys must be unique site-wide and must not change once content exists if you rely on them. This tool derives them from a hash of the group title and field path — not random — so regenerating gives the same keys.
  • Field names are what you query. Values are saved as post meta under the name (and a hidden _name meta pointing to the key). Keep names short, snake_case and unique within their level.
  • Return formats matter. An Image field returning an array gives you ID, url, alt and sizes; returning an ID lets you use wp_get_attachment_image() for responsive srcset markup.
  • Repeater and Gallery fields require ACF PRO; the free plugin ignores them.
  • Prefer the JSON workflow for teams that edit fields in the admin? Use the ACF JSON Generator and read the ACF field groups guide.

Where these fields usually live

ACF groups are typically attached to a custom post type from the CPT Generator or to terms of a custom taxonomy from the Taxonomy Generator. To output fields inside post content, wrap the template code in a shortcode.

Frequently Asked Questions

Can I still edit fields registered in PHP from the ACF admin?

No. Local field groups appear under the field-group list but are read-only, because PHP is the source of truth. To edit them in the UI, import the JSON version instead or change the code.

Why acf/include_fields instead of acf/init?

ACF 6 introduced acf/include_fields as the dedicated hook for registering local fields, and its own PHP export uses it. acf/init still works on older versions.

Do I need to escape get_field() output?

Yes. get_field() returns raw values, so escape at output: esc_html() for text, esc_url() for URLs, esc_attr() in attributes and wp_kses_post() for WYSIWYG content. Since ACF 6.2.5 the_field() escapes unsafe HTML automatically, but explicit escaping is clearer and works everywhere.

How do I read fields from an options page or a term?

Pass the object as the second argument: get_field( 'logo', 'option' ) for options pages, get_field( 'color', 'term_12' ) or get_field( 'color', $term ) for terms, and get_field( 'bio', 'user_3' ) for users.

What happens if two field groups use the same field name?

They share the same meta key and overwrite each other on save. Only use the same name in two groups when they never appear on the same screen.