A container for nesting related fields together under a single heading.
Overview
The Group field renders a set of sub-fields inside a card container under a shared label. It returns a single associative array of all sub-field values keyed by sub-field ID — one row, always. Use it to organise tightly related fields — all settings for a single UI component, an SEO block, a CTA, or a hero section — into one logical unit without creating a separate navigation section.
For repeatable rows of the same structure, use the Repeater field. For a visual divider between fields, use the Section field.
Field Registration
[
'id' => 'seo_settings',
'type' => 'group',
'title' => __( 'SEO Settings', 'your-textdomain' ),
'subtitle' => __( 'Meta title, description, and indexing preference', 'your-textdomain' ),
'fields' => [
[
'id' => 'meta_title',
'type' => 'text',
'title' => __( 'Meta Title', 'your-textdomain' ),
],
[
'id' => 'meta_description',
'type' => 'textarea',
'title' => __( 'Meta Description', 'your-textdomain' ),
'rows' => 2,
],
[
'id' => 'noindex',
'type' => 'toggle',
'title' => __( 'Discourage Search Engines', 'your-textdomain' ),
'default' => false,
],
],
]
Field Options
| Option | Type | Required | Description |
|---|---|---|---|
id | string | ✅ | Unique field identifier — used as the option key |
type | string | ✅ | Must be group |
title | string | ✅ | Label shown above the group container |
subtitle | string | — | Descriptive text shown below the label |
desc | string | — | Alternative to subtitle — shown in the same position |
fields | array | ✅ | Array of sub-field definitions — same structure as regular fields |
required | array | — | Conditional logic rules — see Conditional Logic |
Supported Sub-field Types
Group passes each sub-field through FieldRenderer with no exclusion list. All registered field types work as sub-fields except:
group— nesting a group inside a group is not supportedrepeater— nesting a repeater inside a group is not supported
Everything else is supported: text, textarea, number, spinner, slider, select, button_set, radio, checkbox, select_image, toggle, switch, color, gradient_picker, image, gallery, icon, typography, dimensions, spacing, border, background, link, date_picker, social_media, code_editor
Note: Sub-fields that return structured arrays — image, gallery, link, background, typography, spacing, border, dimensions — return their full documented shapes inside the group value, exactly as they would as standalone fields.
Return Value
Type: array
Returns an associative array of sub-field values keyed by sub-field ID, or an empty array {} if nothing has been saved yet.
$seo = themeplus_get_option( 'seo_settings', [] );
// Returns:
// [
// 'meta_title' => 'My Page Title',
// 'meta_description' => 'A short description of the page.',
// 'noindex' => false,
// ]
Usage Examples
Reading group sub-field values
$seo = themeplus_get_option( 'seo_settings', [] );
$meta_title = $seo['meta_title'] ?? '';
$meta_desc = $seo['meta_description'] ?? '';
$noindex = $seo['noindex'] ?? false;
if ( $meta_title ) {
echo '<meta name="title" content="' . esc_attr( $meta_title ) . '">';
}
if ( $meta_desc ) {
echo '<meta name="description" content="' . esc_attr( $meta_desc ) . '">';
}
if ( $noindex ) {
echo '<meta name="robots" content="noindex, nofollow">';
}
Logo settings group
[
'id' => 'header_logo',
'type' => 'group',
'title' => __( 'Logo Settings', 'your-textdomain' ),
'fields' => [
[
'id' => 'image',
'type' => 'image',
'title' => __( 'Logo Image', 'your-textdomain' ),
// Returns: { id, url, width, height, alt, title }
],
[
'id' => 'width',
'type' => 'number',
'title' => __( 'Logo Width', 'your-textdomain' ),
'default' => 160,
'unit' => 'px',
],
[
'id' => 'link_url',
'type' => 'text',
'title' => __( 'Logo Link URL', 'your-textdomain' ),
'default' => '',
],
],
]
$logo = themeplus_get_option( 'header_logo', [] );
$image = $logo['image'] ?? []; // full image array
$width = $logo['width'] ?? 160;
$link_url = $logo['link_url'] ?? home_url( '/' );
$img_url = $image['url'] ?? '';
$img_alt = $image['alt'] ?? get_bloginfo( 'name' );
if ( $img_url ) {
echo '<a href="' . esc_url( $link_url ) . '" class="site-logo">';
echo '<img src="' . esc_url( $img_url ) . '" alt="' . esc_attr( $img_alt ) . '" width="' . absint( $width ) . '">';
echo '</a>';
}
Announcement bar group
[
'id' => 'enable_announcement_bar',
'type' => 'toggle',
'title' => __( 'Enable Announcement Bar', 'your-textdomain' ),
'default' => false,
],
[
'id' => 'announcement_bar',
'type' => 'group',
'title' => __( 'Announcement Bar', 'your-textdomain' ),
'required' => ['enable_announcement_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' => 'cta',
'type' => 'link',
'title' => __( 'CTA Link (optional)', 'your-textdomain' ),
'default' => [
'url' => '',
'text' => '',
'target' => '_self',
'rel' => '',
],
],
],
],
$enabled = themeplus_get_option( 'enable_announcement_bar', false );
$bar = themeplus_get_option( 'announcement_bar', [] );
if ( $enabled && ! empty( $bar ) ) {
$message = $bar['message'] ?? '';
$bg_color = $bar['bg_color'] ?? '#2271b1';
$text_color = $bar['text_color'] ?? '#ffffff';
$cta = $bar['cta'] ?? [];
echo '<div class="announcement-bar" style="background: ' . esc_attr( $bg_color ) . '; color: ' . esc_attr( $text_color ) . ';">';
echo esc_html( $message );
if ( ! empty( $cta['url'] ) ) {
$rel = '_blank' === ( $cta['target'] ?? '_self' ) ? 'noopener noreferrer' : ( $cta['rel'] ?? '' );
echo ' <a href="' . esc_url( $cta['url'] ) . '" target="' . esc_attr( $cta['target'] ?? '_self' ) . '" rel="' . esc_attr( $rel ) . '">' . esc_html( $cta['text'] ?? '' ) . '</a>';
}
echo '</div>';
}
Notes
- Always use
??null coalescing when reading sub-keys — a partially saved group may be missing keys added after the user first saved. - Sub-fields that return structured arrays (
image,gallery,link,background,typography, etc.) return their full documented shapes inside the group — use the same key access patterns as when using those fields standalone. - Group produces exactly one set of values — it cannot be duplicated into multiple rows. For repeatable rows, use the Repeater field.
- Nesting
grouporrepeaterinside a Group is not supported. - Group is best for 3–8 tightly related fields that belong together conceptually. For fewer than 3 fields, registering them flat in the section is often cleaner. For more fields or if navigation is needed, create a dedicated section with
themeplus_add_section().