Options Page
The Options_Page class registers ACF Options Pages from config arrays. Each page is organized into tabs (groups), and each tabβs fields are composed with ACF_Builder islands β the same pattern used for Flexible Content modules.
Options pages store global site settings (header navigation, footer content, social media links, API keys, etc.) accessible via get_field('field_name', 'option').
Key Features
Section titled βKey Featuresβ- Tabbed layout: Groups are rendered as ACF tabs on a single options page
- Island-composed fields: Uses
ACF_Builderfor consistent field definitions - Deterministic keys: Generated with
md5()β safe for migrations - show_when support: Conditional visibility between fields
- Submenu pages: Registered under the Terra admin menu by default
Configuration
Section titled βConfigurationβThe Options Page config is typically split into separate files per tab in functions/project/config/general-options/:
functions/project/config/general-options/βββ index.php # Merges all tabsβββ header.php # Header navigation fieldsβββ footer.php # Footer content fieldsβββ site_identity.php # Logo, faviconβββ social_media.php # Social media URLsβββ scripts.php # Header/footer scriptsβββ api_keys.php # API credentialsβββ error_404.php # 404 page contentTab file example
Section titled βTab file exampleβ<?phpreturn [ 'title' => 'Social Media', 'fields' => array_merge( ACF_Builder::url(['name' => 'linkedin_url', 'label' => 'LinkedIn']), ACF_Builder::url(['name' => 'twitter_url', 'label' => 'Twitter / X']), ACF_Builder::url(['name' => 'facebook_url', 'label' => 'Facebook']), ACF_Builder::url(['name' => 'instagram_url', 'label' => 'Instagram']), ACF_Builder::url(['name' => 'youtube_url', 'label' => 'YouTube']), ),];Index file (merging all tabs)
Section titled βIndex file (merging all tabs)β<?php$groups = [];foreach (glob(__DIR__ . '/*.php') as $file) { $name = basename($file, '.php'); if ($name !== 'index') { $groups[$name] = require $file; }}
return [ 'page_title' => 'General Options', 'menu_slug' => 'general-options', 'parent_slug' => 'terra_dashboard', 'groups' => $groups,];Parameters
Section titled βParametersβ| Parameter | Type | Description |
|---|---|---|
page_title | string | Title shown in the admin page |
menu_title | string | Menu label (defaults to page_title) |
menu_slug | string | URL slug for the page |
parent_slug | string | Parent menu slug (e.g., 'terra_dashboard') |
capability | string | Required capability (default: 'edit_posts') |
icon_url | string | Menu icon URL (optional) |
position | int | Menu position (optional) |
redirect | bool | Redirect to first child (default: false) |
groups | array | Keyed array of tab configs, each with title and fields |
Using Options in Templates
Section titled βUsing Options in TemplatesβAccess options page fields with get_field() using the 'option' post ID:
<?php// In any template file$linkedin = get_field('linkedin_url', 'option');$logo = get_field('site_logo', 'option');$nav = get_field('header_nav', 'option');
// In a loop over a repeater$nav_items = get_field('header_navigation', 'option');if ($nav_items) { foreach ($nav_items as $item) { echo '<a href="' . esc_url($item['link']['url']) . '">'; echo esc_html($item['link']['title']); echo '</a>'; }}Example: Header Navigation
Section titled βExample: Header Navigationβ<?phpreturn [ 'title' => 'Header', 'fields' => array_merge( ACF_Builder::repeater([ 'name' => 'header_navigation', 'label' => 'Navigation Items', 'layout' => 'block', 'fields' => array_merge( ACF_Builder::link(['name' => 'link', 'label' => 'Link']), ACF_Builder::boolean(['name' => 'has_dropdown', 'label' => 'Has Dropdown?']), ACF_Builder::repeater([ 'name' => 'dropdown_items', 'label' => 'Dropdown Items', 'fields' => array_merge( ACF_Builder::link(['name' => 'dropdown_link']), ACF_Builder::image(['name' => 'dropdown_icon']), ACF_Builder::text(['name' => 'dropdown_description', 'rows' => 2]), ), ]), ), ]), ACF_Builder::link(['name' => 'header_cta', 'label' => 'CTA Button']), ),];Knowledge Check
Test your understanding of this section
Loading questions...