Extending `Elegant Tabs for WooCommerce` plugin with more features described in the post

  • Elegant Tabs for Woo-commerce does not inherently support the creation of custom tabs for individual products.

  • It does not provide a dedicated interface on the Woo-commerce Edit Product screen -> product data container -> Elegant Custom Tab field to manage tabs on a per-product basis.

  • Elegant Tabs may don’t have the capability to save tabs for reuse across multiple products.

  • Elegant Tabs don’t support to override the global Tabs to re-use them as a template for other products.

    What i have tried so far:

    Adding Local Tabs:

// Add fields for local tabs on product edit page
add_action('woocommerce_product_options_general_product_data', 'add_product_local_tabs');

function add_product_local_tabs() {
    global $post;

    $local_tabs = get_post_meta($post->ID, '_local_elegant_tabs', true) ?: array();
    
    echo '<div class="options_group">';
    echo '<h3>' . __('Custom Product Tabs', 'woocommerce') . '</h3>';
    echo '<div id="custom_product_tabs_container">';
    
    foreach ($local_tabs as $tab_id => $tab) {
        echo '<div class="custom-tab" data-tab-id="' . esc_attr($tab_id) . '">';
        echo '<input type="text" name="custom_tab_title[' . esc_attr($tab_id) . ']" value="' . esc_attr($tab['title']) . '" placeholder="Tab Title" />';
        echo '<textarea name="custom_tab_content[' . esc_attr($tab_id) . ']" placeholder="Tab Content">' . esc_textarea($tab['content']) . '</textarea>';
        echo '<button type="button" class="remove_tab">' . __('Remove Tab', 'woocommerce') . '</button>';
        echo '</div>';
    }
    
    echo '</div>'; // custom_product_tabs_container
    echo '<button type="button" id="add_new_custom_tab" class="button">' . __('Add New Tab', 'woocommerce') . '</button>';
    echo '</div>'; // End options_group
}

Save Local Tabs on Product Update

// Save custom product tabs data
add_action('woocommerce_process_product_meta', 'save_custom_product_tabs');

function save_custom_product_tabs($post_id) {
    if (isset($_POST['custom_tab_title']) && isset($_POST['custom_tab_content'])) {
        $local_tabs = array();

        foreach ($_POST['custom_tab_title'] as $tab_id => $title) {
            if (!empty($title)) {
                $local_tabs[$tab_id] = array(
                    'title' => sanitize_text_field($title),
                    'content' => wp_kses_post($_POST['custom_tab_content'][$tab_id]),
                );
            }
        }

        update_post_meta($post_id, '_local_elegant_tabs', $local_tabs);
    } else {
        delete_post_meta($post_id, '_local_elegant_tabs');
    }
}

Scripting for Dynamic Tab Management

jQuery(document).ready(function($) {
    let tabCount = $('.custom-tab').length;

    $('#add_new_custom_tab').on('click', function() {
        tabCount++;
        const newTab = `
            <div class="custom-tab" data-tab-id="${tabCount}">
                <input type="text" name="custom_tab_title[${tabCount}]" placeholder="Tab Title" />
                <textarea name="custom_tab_content[${tabCount}]"></textarea>
                <button type="button" class="remove_tab">Remove Tab</button>
            </div>`;
        $('#custom_product_tabs_container').append(newTab);
    });

    $(document).on('click', '.remove_tab', function() {
        $(this).closest('.custom-tab').remove();
    });
});

Extending Tab Display

add_filter('woocommerce_product_tabs', 'combine_global_and_local_tabs', 100, 2);

function combine_global_and_local_tabs($tabs, $product) {
    $local_tabs = get_post_meta($product->get_id(), '_local_elegant_tabs', true);
    
    if (!empty($local_tabs)) {
        foreach ($local_tabs as $tab) {
            $tabs[] = array(
                'title' => esc_html($tab['title']),
                'callback' => function() use ($tab) {
                    echo wp_kses_post($tab['content']);
                },
            );
        }
    }

    return $tabs;
}

Issues:
For No Reason 4 Field is added which automatically adds 4 Empty Tabs

Data Field

Solution i’m expecting
enter image description here