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
| Option | Type | Required | Description |
|---|---|---|---|
id | string | ✅ | Unique field identifier — used as the option key |
type | string | ✅ | Must be group |
title | string | ✅ | Heading shown in the group’s collapsed bar |
subtitle | string | — | Smaller descriptive text shown beside the title |
desc | string | — | Help text shown inside the expanded group |
fields | array | ✅ | Array of sub-field definitions — same structure as regular fields |
default | array | — | Associative array of default sub-field values keyed by sub-field ID |
required | array | — | Conditional 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
grouporrepeaterinside a Group is not supported.