• Skip to secondary menu
  • Skip to main content
  • Skip to primary sidebar
  • Home
  • Projects
  • Products
  • Themes
  • Tools
  • Request for Quote

Vengala Vinay

Having 12+ Years of Experience in Software Development

  • Home
  • WordPress
  • PHP
    • Codeigniter
  • Django
  • Magento
  • Selenium
  • Server
Home » How to build custom ACF Pro dynamic fields extensions utilizing modern REST API Controllers schemas

How to build custom ACF Pro dynamic fields extensions utilizing modern REST API Controllers schemas

Leveraging WordPress REST API Controllers for Advanced ACF PRO Dynamic Field Extensions

Advanced Custom Fields (ACF) PRO offers a powerful mechanism for creating dynamic field population through its “Dynamic Content” feature. While this is excellent for many use cases, extending its capabilities beyond simple database lookups or static options often requires a more robust solution. This is where the WordPress REST API and custom controller schemas come into play. By building custom REST API endpoints and exposing structured data, we can create highly sophisticated dynamic field behaviors that are both scalable and maintainable.

This guide will walk you through building a custom ACF PRO dynamic field extension that fetches data from a custom REST API endpoint. We’ll focus on creating a well-defined schema for our API response, enabling ACF to reliably parse and utilize this data for field options, choices, or even complex nested structures.

Designing the Custom REST API Endpoint

The core of our extension will be a custom REST API endpoint. For this example, let’s imagine we need to populate a select field with a list of active projects from an external project management system. We’ll simulate this by creating a custom endpoint within our WordPress site that returns project data.

We’ll use the `register_rest_route` function to define our endpoint. It’s crucial to define a clear namespace and route. For better organization, we’ll use a custom plugin or theme’s `functions.php` file.

Registering the REST Route

Here’s the PHP code to register our custom endpoint:

<?php
/**
 * Plugin Name: ACF Dynamic Project Fields
 * Description: Extends ACF PRO with dynamic fields for project data.
 * Version: 1.0
 * Author: Antigravity
 */

add_action( 'rest_api_init', function () {
    register_rest_route( 'acfdpf/v1', '/projects', array(
        'methods'  => 'GET',
        'callback' => 'acfdpf_get_projects_callback',
        'permission_callback' => '__return_true', // For simplicity, allow public access. In production, implement proper authentication.
    ) );
} );

function acfdpf_get_projects_callback( WP_REST_Request $request ) {
    // In a real-world scenario, this would fetch data from an external API,
    // a custom database table, or another complex data source.
    // For this example, we'll return a static array.

    $projects = array(
        array(
            'id' => 101,
            'name' => 'Project Alpha',
            'status' => 'active',
            'client' => 'Acme Corp',
            'deadline' => '2024-12-31',
        ),
        array(
            'id' => 102,
            'name' => 'Project Beta',
            'status' => 'active',
            'client' => 'Globex Inc',
            'deadline' => '2025-03-15',
        ),
        array(
            'id' => 103,
            'name' => 'Project Gamma',
            'status' => 'completed',
            'client' => 'Initech',
            'deadline' => '2023-11-30',
        ),
        array(
            'id' => 104,
            'name' => 'Project Delta',
            'status' => 'active',
            'client' => 'Cyberdyne Systems',
            'deadline' => '2024-09-01',
        ),
    );

    // Filter for active projects as per our requirement
    $active_projects = array_filter( $projects, function( $project ) {
        return $project['status'] === 'active';
    } );

    // Re-index array keys after filtering
    $active_projects = array_values( $active_projects );

    // Prepare the response data according to our desired schema
    $response_data = array_map( function( $project ) {
        return array(
            'value' => $project['id'], // The value to be stored in the ACF field
            'label' => sprintf( '%s (%s)', $project['name'], $project['client'] ), // The display label in the ACF field
            'details' => array( // Additional data that can be leveraged by ACF
                'status' => $project['status'],
                'client' => $project['client'],
                'deadline' => $project['deadline'],
            ),
        );
    }, $active_projects );

    return new WP_REST_Response( $response_data, 200 );
}
?>

In this callback function:

  • We define a static array of projects, simulating data fetched from an external source.
  • We filter this array to include only ‘active’ projects.
  • We then transform the filtered data into a specific structure that ACF can easily consume: an array of objects, each with a value and a label. We also include a nested details array for richer data.
  • The response is wrapped in a WP_REST_Response object with a 200 OK status.

To test this endpoint, you can navigate to YOUR_SITE_URL/wp-json/acfdpf/v1/projects. You should see a JSON response similar to this:

[
    {
        "value": 101,
        "label": "Project Alpha (Acme Corp)",
        "details": {
            "status": "active",
            "client": "Acme Corp",
            "deadline": "2024-12-31"
        }
    },
    {
        "value": 102,
        "label": "Project Beta (Globex Inc)",
        "details": {
            "status": "active",
            "client": "Globex Inc",
            "deadline": "2025-03-15"
        }
    },
    {
        "value": 104,
        "label": "Project Delta (Cyberdyne Systems)",
        "details": {
            "status": "active",
            "client": "Cyberdyne Systems",
            "deadline": "2024-09-01"
        }
    }
]

Configuring ACF PRO Dynamic Fields

Now that we have our REST API endpoint ready, we can configure an ACF PRO field to use this data dynamically. We’ll assume you have ACF PRO installed and activated.

Setting up the Select Field

In your ACF Field Group settings, add a new field. Choose the “Select” field type. Then, scroll down to the “Conditional Logic” section and enable “Dynamic Content”.

Under the “Dynamic Content” settings, configure the following:

  • Source: Select “REST API”.
  • REST API URL: Enter the full URL to your custom endpoint: YOUR_SITE_URL/wp-json/acfdpf/v1/projects.
  • Value Format: This tells ACF which key in your JSON response should be used for the field’s stored value. Based on our schema, this should be value.
  • Label Format: This specifies the key for the display text in the dropdown. For us, this is label.
  • Return Format: Choose “Value” if you want to store only the selected project ID.

For more advanced scenarios, you can use the “Details Format” to map additional data. For instance, if you wanted to store the client name alongside the project ID (though typically you’d just store the ID), you could configure it. However, for a standard select field, value and label are sufficient.

Advanced Data Handling and Schema Design

The power of this approach lies in the flexibility of the REST API response schema. You are not limited to simple key-value pairs. ACF PRO can interpret nested structures.

Leveraging Nested Data

Consider a scenario where you want to display the project name and client in the select dropdown, but store the project ID. Our current schema already supports this with value and label. However, if you needed to access the details array for further processing (e.g., in JavaScript or within PHP after saving), your API response should be structured accordingly.

Let’s say you wanted to populate a “Client” field dynamically based on the selected project. This would typically involve JavaScript on the front-end or a more complex ACF setup. However, if your API could provide a lookup for client details, you could structure it like this:

[
    {
        "value": 101,
        "label": "Project Alpha",
        "client_name": "Acme Corp", // Directly available
        "client_details": { // Nested object
            "id": "acme-corp-id",
            "contact_person": "Jane Doe"
        }
    },
    // ... other projects
]

ACF PRO’s dynamic fields primarily use the top-level value and label keys. For accessing nested data or performing actions based on selections, you would typically need to:

  • Client-side JavaScript: Use ACF’s JavaScript API to listen for changes on the select field and then make further AJAX calls or manipulate other fields based on the selected value and its associated data (which you might embed as data attributes or fetch via another API call).
  • Server-side Processing: When the post is saved, you can access the saved value and use it to perform additional actions or lookups within your plugin’s save hooks (e.g., save_post).

Customizing the REST API Response Schema

The key is to ensure your callback function returns data in a predictable and parseable format. ACF PRO expects an array of objects, where each object has at least a value and a label key. You can add any other keys you need for your specific application logic.

For instance, if you were fetching data from an external service that returned data in a different format, you would map it within your callback:

function acfdpf_get_external_data_callback( WP_REST_Request $request ) {
    $external_api_data = fetch_data_from_external_service(); // Assume this function exists

    $acf_compatible_data = array_map( function( $item ) {
        return array(
            'value' => $item['external_id'], // Map external ID to ACF 'value'
            'label' => $item['display_name'], // Map external name to ACF 'label'
            'external_status' => $item['status'], // Keep original status for potential later use
            'nested_info' => array( // Nest other relevant data
                'category' => $item['category'],
                'created_at' => $item['timestamp'],
            ),
        );
    }, $external_api_data );

    return new WP_REST_Response( $acf_compatible_data, 200 );
}

Error Handling and Permissions

In a production environment, robust error handling and secure permissions are paramount. The current example uses 'permission_callback' => '__return_true' for simplicity, which is insecure.

Implementing Permissions

You should implement proper checks to ensure only authorized users or applications can access your data. This could involve:

  • Checking user capabilities: current_user_can( 'edit_posts' ).
  • Using nonce verification for authenticated requests.
  • Implementing OAuth or API keys if the endpoint is meant for external applications.

Example with capability check:

add_action( 'rest_api_init', function () {
    register_rest_route( 'acfdpf/v1', '/projects', array(
        'methods'  => 'GET',
        'callback' => 'acfdpf_get_projects_callback',
        'permission_callback' => function ( WP_REST_Request $request ) {
            // Only allow users who can edit posts to access this data
            return current_user_can( 'edit_posts' );
        },
    ) );
} );

Handling API Errors

If your data source is external, it might fail. Your callback should gracefully handle these failures and return appropriate error responses.

function acfdpf_get_projects_callback( WP_REST_Request $request ) {
    // Attempt to fetch data from an external API
    $response = wp_remote_get( 'https://api.external-project-manager.com/projects' );

    if ( is_wp_error( $response ) ) {
        return new WP_Error( 'external_api_error', 'Failed to connect to the external project API.', array( 'status' => 500 ) );
    }

    $body = wp_remote_retrieve_body( $response );
    $external_data = json_decode( $body, true );

    if ( json_last_error() !== JSON_ERROR_NONE || empty( $external_data ) ) {
        return new WP_Error( 'external_api_parse_error', 'Failed to parse response from external project API.', array( 'status' => 500 ) );
    }

    // ... (rest of the data transformation logic as before) ...

    return new WP_REST_Response( $acf_compatible_data, 200 );
}

By implementing these practices, you can build highly dynamic and robust ACF PRO field extensions that integrate seamlessly with your WordPress site and external data sources.

Primary Sidebar

A little about the Author

Having 12+ Years of Experience in Software Development, Vinay is a principal software architect, senior systems engineer, and elite technical consultant. He specializes in bespoke PHP/WordPress development, high-performance Magento 2 & Shopify architectures, custom plugin/theme development from scratch, and legacy code modernization (including VB6, VB.NET, PyQt, and Crystal Reports). Known for solving complex database bottlenecks, speed optimization (Core Web Vitals), and advanced security code auditing, Vinay engineers production-ready systems designed to scale under heavy concurrent load conditions.



Chat on WhatsApp

Recent Posts

  • Troubleshooting WP_DEBUG notice floods in production when using modern Understrap styling structures wrappers
  • How to build custom WooCommerce core overrides extensions utilizing modern Metadata API (add_post_meta) schemas
  • How to securely integrate Firebase Realtime DB endpoints into WordPress custom plugins using Filesystem API
  • Step-by-Step Guide to building a custom real-time activity logs block for Gutenberg using REST API custom routes
  • WordPress Development Recipe: Efficient binary storage and retrieval in custom tables using Named Arguments

Categories

  • apache (1)
  • Business & Monetization (390)
  • Centos (4)
  • Comparisons & Decision Making (55)
  • Debian (2)
  • Debugging & Troubleshooting (643)
  • Desktop Applications (14)
  • DevOps (7)
  • DevOps & Cloud Scaling (962)
  • Django (1)
  • Laravel (4)
  • Migration & Architecture (192)
  • Mobile Applications (24)
  • MySQL (1)
  • Performance & Optimization (849)
  • PHP (5)
  • PHP Development (37)
  • Plugins & Themes (244)
  • Programming Languages (9)
  • Python (20)
  • Ruby on Rails (1)
  • Security & Compliance (622)
  • SEO & Growth (492)
  • Server (23)
  • Ubuntu (9)
  • VB6 & VB.NET (8)
  • Web Applications & Frontend (19)
  • Web Assembly (Wasm) (2)
  • WordPress (22)
  • WordPress Plugin Development (271)
  • WordPress Theme Development (357)

Recent Posts

  • Troubleshooting WP_DEBUG notice floods in production when using modern Understrap styling structures wrappers
  • How to build custom WooCommerce core overrides extensions utilizing modern Metadata API (add_post_meta) schemas
  • How to securely integrate Firebase Realtime DB endpoints into WordPress custom plugins using Filesystem API

Top Categories

  • DevOps & Cloud Scaling (962)
  • Performance & Optimization (849)
  • Debugging & Troubleshooting (643)
  • Security & Compliance (622)
  • SEO & Growth (492)
  • Business & Monetization (390)

Our Products

  • ERP & LMS Systems (4)
  • Directories & Marketplaces (4)
  • Healthcare Portals (3)
  • Point of Sale (POS) (2)
  • E-Commerce Engines (2)

Our Services

  • E-Commerce Development (10)
  • WordPress Development (8)
  • Python & Desktop GUI (7)
  • General Consulting (7)
  • Legacy Modernization (5)
  • Mobile App Development (4)

Copyright © 2026 · Vinay Vengala