Skip to content

Group Field

A collapsible container for nesting related fields together under a single heading.

Overview

The Group field renders a collapsible panel that wraps a defined set of sub-fields under a shared heading. It returns an associative array of all sub-field values keyed by sub-field ID. Use it to organize tightly related fields — such as all settings for a single UI component — into one collapsible unit without creating a separate navigation section.


Field Registration

php

[
    'id'      => 'header_logo',
    'type'    => 'group',
    'title'   => __('Logo Settings', 'your-textdomain'),
    'subtitle' => __('Image, size, and link for the header logo', 'your-textdomain'),
    'fields'  => [
        [
            'id'    => 'image',
            'type'  => 'image',
            'title' => __('Logo Image', 'your-textdomain'),
        ],
        [
            'id'      => 'width',
            'type'    => 'number',
            'title'   => __('Logo Width', 'your-textdomain'),
            'default' => 160,
            'unit'    => 'px',
        ],
        [
            'id'      => 'link',
            'type'    => 'link',
            'title'   => __('Logo Link', 'your-textdomain'),
            'default' => ['url' => '', 'target' => '_self'],
        ],
    ],
]

Field Options

OptionTypeRequiredDescription
idstringUnique field identifier — used as the option key
typestringMust be group
titlestringHeading shown in the group’s collapsed bar
subtitlestringSmaller descriptive text shown beside the title
descstringHelp text shown inside the expanded group
fieldsarrayArray of sub-field definitions — same structure as regular fields
defaultarrayAssociative array of default sub-field values keyed by sub-field ID
requiredarrayConditional logic rules — see Conditional Logic

Supported Sub-field Types

Most standard field types are supported as sub-fields inside a Group:

text, textarea, number, slider, select, button_set, radio, checkbox, toggle, color, gradient_picker, image, gallery, icon, typography, dimensions, spacing, border, background, link, date_picker, social_media, code_editor

Nesting a group or repeater inside a Group is not supported.


Return Value

Type: array

Returns an associative array of sub-field values keyed by sub-field ID, or the default array if nothing has been saved yet.

php

$logo = themeplus_get_option( 'header_logo', [] );
// Returns:
// [
//     'image' => 42,
//     'width' => 160,
//     'link'  => ['url' => 'https://example.com', 'target' => '_self'],
// ]

Usage Examples

Reading group sub-field values

php

$logo     = themeplus_get_option( 'header_logo', [] );
$image_id = $logo['image'] ?? '';
$width    = $logo['width'] ?? 160;
$link     = $logo['link']  ?? ['url' => home_url('/'), 'target' => '_self'];

$url    = $link['url']    ?? home_url('/');
$target = $link['target'] ?? '_self';
$rel    = $target === '_blank' ? ' rel="noopener noreferrer"' : '';

echo '<a href="' . esc_url( $url ) . '" target="' . esc_attr( $target ) . '"' . $rel . ' class="site-logo">';
if ( $image_id ) {
    echo wp_get_attachment_image( (int) $image_id, 'full', false, [
        'class' => 'site-logo__img',
        'style' => 'width: ' . absint( $width ) . 'px;',
        'alt'   => get_bloginfo('name'),
    ]);
}
echo '</a>';

Hero section group

php

[
    'id'      => 'hero',
    'type'    => 'group',
    'title'   => __('Hero Section', 'your-textdomain'),
    'fields'  => [
        [
            'id'      => 'heading',
            'type'    => 'text',
            'title'   => __('Heading', 'your-textdomain'),
            'default' => __('Welcome to Our Site', 'your-textdomain'),
        ],
        [
            'id'      => 'subheading',
            'type'    => 'textarea',
            'title'   => __('Subheading', 'your-textdomain'),
            'default' => '',
        ],
        [
            'id'      => 'cta_label',
            'type'    => 'text',
            'title'   => __('CTA Button Label', 'your-textdomain'),
            'default' => __('Get Started', 'your-textdomain'),
        ],
        [
            'id'      => 'cta_link',
            'type'    => 'link',
            'title'   => __('CTA Button Link', 'your-textdomain'),
            'default' => ['url' => '', 'target' => '_self'],
        ],
        [
            'id'      => 'background',
            'type'    => 'background',
            'title'   => __('Background', 'your-textdomain'),
            'default' => ['color' => '#0a0a0a', 'image' => '', 'size' => 'cover', 'repeat' => 'no-repeat', 'position' => 'center center', 'attachment' => 'scroll'],
        ],
    ],
]

php

$hero       = themeplus_get_option( 'hero', [] );
$heading    = $hero['heading']    ?? '';
$subheading = $hero['subheading'] ?? '';
$cta_label  = $hero['cta_label']  ?? '';
$cta_link   = $hero['cta_link']   ?? ['url' => '', 'target' => '_self'];
$bg         = $hero['background'] ?? [];

$bg_color = esc_attr( $bg['color'] ?? '#0a0a0a' );
$bg_image_id = $bg['image'] ?? '';
$bg_url   = $bg_image_id ? wp_get_attachment_image_url( (int) $bg_image_id, 'full' ) : '';

$style  = 'background-color: ' . $bg_color . ';';
if ( $bg_url ) {
    $style .= 'background-image: url(' . esc_url( $bg_url ) . ');';
    $style .= 'background-size: cover; background-position: center center; background-repeat: no-repeat;';
}

echo '<section class="hero" style="' . $style . '">';
if ( $heading )    echo '<h1>' . esc_html( $heading ) . '</h1>';
if ( $subheading ) echo '<p>'  . esc_html( $subheading ) . '</p>';
if ( $cta_link['url'] ?? '' ) {
    $rel = ( $cta_link['target'] ?? '_self' ) === '_blank' ? ' rel="noopener noreferrer"' : '';
    echo '<a href="' . esc_url( $cta_link['url'] ) . '" target="' . esc_attr( $cta_link['target'] ?? '_self' ) . '"' . $rel . ' class="btn btn--primary">';
    echo esc_html( $cta_label ?: __('Learn More', 'your-textdomain') );
    echo '</a>';
}
echo '</section>';

With a conditional field

php

[
    'id'      => 'enable_sticky_bar',
    'type'    => 'toggle',
    'title'   => __('Enable Sticky Announcement Bar', 'your-textdomain'),
    'default' => false,
],
[
    'id'       => 'sticky_bar',
    'type'     => 'group',
    'title'    => __('Announcement Bar', 'your-textdomain'),
    'required' => ['enable_sticky_bar', '==', true],
    'fields'   => [
        [
            'id'      => 'message',
            'type'    => 'text',
            'title'   => __('Message', 'your-textdomain'),
            'default' => __('Free shipping on orders over $50', 'your-textdomain'),
        ],
        [
            'id'      => 'bg_color',
            'type'    => 'color',
            'title'   => __('Background Color', 'your-textdomain'),
            'default' => '#2271b1',
        ],
        [
            'id'      => 'text_color',
            'type'    => 'color',
            'title'   => __('Text Color', 'your-textdomain'),
            'default' => '#ffffff',
        ],
        [
            'id'      => 'link',
            'type'    => 'link',
            'title'   => __('Link (optional)', 'your-textdomain'),
            'default' => ['url' => '', 'target' => '_self'],
        ],
    ],
],

Notes

  • Always use the ?? null coalescing operator when reading individual sub-keys — a partially saved group may be missing some keys if sub-fields were added after the user first saved.
  • Group is best used when 3–8 tightly related fields belong together conceptually and would clutter the section if listed flat. For fewer than 3 fields, registering them flat is often cleaner. For more than 8 fields, consider creating a dedicated navigation section instead.
  • Unlike Repeater, a Group produces exactly one set of values — it cannot be duplicated into multiple rows.
  • Nesting a group or repeater inside a Group is not supported.

On This Page