• 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 Elementor custom widgets extensions utilizing modern WordPress Settings API schemas

How to build custom Elementor custom widgets extensions utilizing modern WordPress Settings API schemas

Leveraging the WordPress Settings API for Advanced Elementor Widget Configuration

While Elementor provides a robust visual interface for designing web pages, extending its functionality with custom widgets often requires more sophisticated configuration options than simple text or color pickers. This is where the WordPress Settings API, combined with Elementor’s widget development framework, becomes invaluable. By programmatically defining settings fields using the Settings API, we can create dynamic, user-friendly interfaces for our custom widgets, offering greater control and flexibility to end-users.

Understanding the WordPress Settings API Schema

The WordPress Settings API is the backbone for managing plugin and theme options. It allows developers to register settings, sections, and fields, and handles the saving and sanitization of data. The core components are:

  • Settings: The actual data points you want to store (e.g., an API key, a specific URL).
  • Sections: Logical groupings of settings fields.
  • Fields: The input elements (text boxes, checkboxes, select dropdowns) that users interact with to set the values of your settings.

When building custom Elementor widgets, we can leverage these components to create a dedicated settings page for our widget’s global configurations or specific advanced options that don’t fit neatly within the standard Elementor control panel.

Registering Settings for a Custom Elementor Widget

Let’s assume we’re building a custom Elementor widget that fetches data from an external API. We’ll need a place to store the API key and endpoint URL. We can register these as options using the Settings API. This registration typically happens within your plugin’s main file or an included settings file, hooked into `admin_init`.

Defining the Settings Group and Options

First, we register a settings group. This group is used to identify all the settings that belong together. Then, we register the individual settings fields.

<?php
/**
 * Register settings for the custom API widget.
 */
function my_custom_api_widget_register_settings() {
    // Register settings group
    register_setting( 'my_api_widget_options_group', 'my_api_widget_settings', 'my_api_widget_sanitize_settings' );

    // Add settings section
    add_settings_section(
        'my_api_widget_section',
        __( 'External API Configuration', 'my-text-domain' ),
        'my_api_widget_section_callback',
        'my-api-widget-settings' // Menu slug
    );

    // Add API Key field
    add_settings_field(
        'api_key',
        __( 'API Key', 'my-text-domain' ),
        'my_api_widget_render_api_key_field',
        'my-api-widget-settings', // Menu slug
        'my_api_widget_section'
    );

    // Add API Endpoint field
    add_settings_field(
        'api_endpoint',
        __( 'API Endpoint URL', 'my-text-domain' ),
        'my_api_widget_render_api_endpoint_field',
        'my-api-widget-settings', // Menu slug
        'my_api_widget_section'
    );
}
add_action( 'admin_init', 'my_custom_api_widget_register_settings' );

/**
 * Sanitize settings before saving.
 */
function my_api_widget_sanitize_settings( $input ) {
    $sanitized_input = array();

    if ( isset( $input['api_key'] ) ) {
        $sanitized_input['api_key'] = sanitize_text_field( $input['api_key'] );
    }

    if ( isset( $input['api_endpoint'] ) ) {
        $sanitized_input['api_endpoint'] = esc_url_raw( $input['api_endpoint'] );
    }

    return $sanitized_input;
}

/**
 * Callback for the settings section description.
 */
function my_api_widget_section_callback() {
    echo '<p>' . __( 'Enter your API credentials and endpoint for the external service.', 'my-text-domain' ) . '</p>';
}

/**
 * Render the API Key input field.
 */
function my_api_widget_render_api_key_field() {
    $options = get_option( 'my_api_widget_settings' );
    $api_key = isset( $options['api_key'] ) ? $options['api_key'] : '';
    ?>
    <input type="text" name="my_api_widget_settings[api_key]" value="<?php echo esc_attr( $api_key ); ?>" class="regular-text" />
    <p class="description"><?php _e( 'Your unique API key.', 'my-text-domain' ); ?></p>
    <?php
}

/**
 * Render the API Endpoint input field.
 */
function my_api_widget_render_api_endpoint_field() {
    $options = get_option( 'my_api_widget_settings' );
    $api_endpoint = isset( $options['api_endpoint'] ) ? $options['api_endpoint'] : '';
    ?>
    <input type="url" name="my_api_widget_settings[api_endpoint]" value="<?php echo esc_url( $api_endpoint ); ?>" class="regular-text" />
    <p class="description"><?php _e( 'The base URL for the API endpoint.', 'my-text-domain' ); ?></p>
    <?php
}
?>

Creating the Settings Page Menu

To make these settings accessible, we need to add a menu item to the WordPress admin dashboard. This is done using `add_options_page` or `add_menu_page` hooked into `admin_menu`.

<?php
/**
 * Add settings page to the admin menu.
 */
function my_custom_api_widget_add_settings_page() {
    add_options_page(
        __( 'Custom API Widget Settings', 'my-text-domain' ), // Page title
        __( 'API Widget', 'my-text-domain' ), // Menu title
        'manage_options', // Capability required
        'my-api-widget-settings', // Menu slug (matches add_settings_section slug)
        'my_custom_api_widget_render_settings_page' // Callback function to render the page
    );
}
add_action( 'admin_menu', 'my_custom_api_widget_add_settings_page' );

/**
 * Render the settings page content.
 */
function my_custom_api_widget_render_settings_page() {
    ?>
    <div class="wrap">
        <h1><?php _e( 'Custom API Widget Settings', 'my-text-domain' ); ?></h1>
        <form action="options.php" method="post">
            <?php
            // Output security fields for the registered setting group
            settings_fields( 'my_api_widget_options_group' );
            // Output settings sections and their fields
            do_settings_sections( 'my-api-widget-settings' );
            // Output save settings button
            submit_button();
            ?>
        </form>
    </div>
    <?php
}
?>

Integrating Settings with Elementor Widgets

Now that our settings are registered and accessible via a dedicated admin page, we need to retrieve these values within our Elementor widget’s PHP class. This allows the widget to use the API key and endpoint for its operations.

Accessing Saved Options in the Widget Class

Inside your Elementor widget’s `render()` or `get_content()` methods, you can fetch the saved options using `get_option()`.

<?php
use Elementor\Widget_Base;
use Elementor\Controls_Manager;

class My_Custom_API_Widget extends Widget_Base {

    // ... widget registration and other methods ...

    protected function render() {
        $settings = get_option( 'my_api_widget_settings' );
        $api_key = isset( $settings['api_key'] ) ? $settings['api_key'] : '';
        $api_endpoint = isset( $settings['api_endpoint'] ) ? $settings['api_endpoint'] : '';

        if ( empty( $api_key ) || empty( $api_endpoint ) ) {
            echo '<p>' . __( 'API configuration is missing. Please configure in the plugin settings.', 'my-text-domain' ) . '</p>';
            return;
        }

        // Now you can use $api_key and $api_endpoint to fetch data
        // For example:
        // $response = wp_remote_get( $api_endpoint . '?apikey=' . urlencode( $api_key ) );
        // if ( ! is_wp_error( $response ) ) {
        //     $data = json_decode( wp_remote_retrieve_body( $response ), true );
        //     // Render the data
        // } else {
        //     echo '<p>' . __( 'Error fetching data.', 'my-text-domain' ) . '</p>';
        // }
    }

    // ... other widget methods ...
}
?>

Conditional Display of Controls

You might want to conditionally show or hide certain widget controls based on whether the API settings are configured. This can be achieved by checking the option values within the `_register_controls()` method.

<?php
use Elementor\Widget_Base;
use Elementor\Controls_Manager;

class My_Custom_API_Widget extends Widget_Base {

    // ... widget registration and other methods ...

    protected function _register_controls() {
        $settings = get_option( 'my_api_widget_settings' );
        $api_configured = ! empty( $settings['api_key'] ) && ! empty( $settings['api_endpoint'] );

        $this->start_controls_section(
            'content_section',
            [
                'label' => __( 'Content', 'my-text-domain' ),
                'tab' => Controls_Manager::TAB_CONTENT,
            ]
        );

        // Example: Only show this control if API is configured
        if ( $api_configured ) {
            $this->add_control(
                'api_data_source',
                [
                    'label' => __( 'Data Source', 'my-text-domain' ),
                    'type' => Controls_Manager::SELECT,
                    'options' => [
                        'posts' => __( 'Posts', 'my-text-domain' ),
                        'users' => __( 'Users', 'my-text-domain' ),
                    ],
                    'default' => 'posts',
                ]
            );
        } else {
            $this->add_control(
                'api_config_notice',
                [
                    'label' => __( 'API Configuration Required', 'my-text-domain' ),
                    'type' => Controls_Manager::RAW_HTML,
                    'raw' => __( '<div style="color: red;">Please configure your API settings in the plugin options to enable data fetching.</div>', 'my-text-domain' ),
                    'content_classes' => 'elementor-panel-alert elementor-panel-alert-danger',
                ]
            );
        }

        $this->end_controls_section();
    }

    // ... other widget methods ...
}
?>

Advanced Use Cases and Best Practices

The Settings API’s flexibility extends beyond simple API keys. You can register complex fields, including:

  • Textareas: For longer configuration strings.
  • Select dropdowns: For predefined choices.
  • Checkboxes and Radio buttons: For boolean or multiple-choice options.
  • Media Uploaders: For image or file selections (requires additional JavaScript).
  • Custom Field Types: By creating custom callback functions for `add_settings_field`.

Security Considerations

Always sanitize and validate user input rigorously. The `sanitize_text_field`, `esc_url_raw`, and other WordPress sanitization functions are crucial. For sensitive data like API keys, consider using WordPress’s built-in secrets management if available or implementing encryption if necessary, though for typical API keys, proper sanitization and secure storage (e.g., not exposing them in client-side JavaScript) is usually sufficient.

Structuring Your Plugin

For larger plugins, it’s good practice to separate your Settings API code into its own file (e.g., `includes/settings.php`) and include it in your main plugin file. This keeps your code organized and maintainable.

Conclusion

By integrating the WordPress Settings API with Elementor’s widget development, you can create highly configurable and user-friendly custom widgets. This approach provides a robust framework for managing plugin options, ensuring data integrity through sanitization, and offering a seamless experience for both developers and end-users. This pattern is particularly powerful for widgets that rely on external services or require complex, site-wide configurations.

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

  • Step-by-Step Guide to building a custom Elasticsearch search bar block for Gutenberg using React components
  • Troubleshooting guide: Resolving memory leak spikes caused by unclosed custom database loops in customer support tickets
  • Optimizing p99 database query response latency in multi-site Domain-driven architecture (DDD) blocks custom tables
  • How to design a modular Action-hook Event Mediator architecture for enterprise-level custom plugins
  • Step-by-Step Guide to building a custom database optimizer portal block for Gutenberg using Next.js headless configurations

Categories

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

Recent Posts

  • Step-by-Step Guide to building a custom Elasticsearch search bar block for Gutenberg using React components
  • Troubleshooting guide: Resolving memory leak spikes caused by unclosed custom database loops in customer support tickets
  • Optimizing p99 database query response latency in multi-site Domain-driven architecture (DDD) blocks custom tables

Top Categories

  • DevOps & Cloud Scaling (962)
  • Performance & Optimization (872)
  • Debugging & Troubleshooting (658)
  • Security & Compliance (639)
  • 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