You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Elementor多重复器组件内联编辑无法保存的问题求助

Elementor多重复器组件内联编辑无法保存的问题求助

问题还原

我做了一个Elementor自定义Widget,里面加了两个Repeater组件,每个Repeater里都有一个文本控件,想支持内联编辑。现在单个Repeater的时候,内联编辑和保存都正常,但加了第二个Repeater后,内联编辑能正常触发,但修改后的内容就是保存不了。我用的是add_inline_editing_attributes方法来实现内联编辑,请问这种多Repeater的场景下,要怎么处理才能让内联编辑的内容正常保存?

问题代码

protected function register_controls() {
    $this->start_controls_section(
        'content_section',
        [
            'label' => esc_html__( 'Test Plugin', 'test-plugin-td' ),
            'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
        ]
    );

    $repeater = new Repeater();
    $repeater->add_control(
        'text',
        [
            'label' => __( 'Business Hour', 'test-plugin-td' ),
            'type' => \Elementor\Controls_Manager::TEXT,
            'label_block' => true,
            'placeholder' => __( 'First Name', 'test-plugin-td' ),
            'default' => __( 'First Name', 'test-plugin-td' ),
            'dynamic' => [
                'active' => true,
            ],
        ]
    );
    $this->add_control(
        'business_hours',
        [
            'label' => __( 'Test Plugin', 'test-plugin-td' ),
            'type' => \Elementor\Controls_Manager::REPEATER,
            'fields' => $repeater->get_controls(),
            'default' => [
                [
                    'text' => __( 'First Name', 'test-plugin-td' ),
                ],
                [
                    'text' => __( 'Last Name', 'test-plugin-td' ),
                ],
            ],
            'title_field' => '{{{ text }}}',
        ]
    );

    $this->end_controls_section();


    $this->start_controls_section(
        'content_2section',
        [
            'label' => esc_html__( 'Test Plugin', 'test-plugin-td' ),
            'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
        ]
    );

    $repeskeater = new Repeater();
    $repeskeater->add_control(
        'text2',
        [
            'label' => __( 'Business Hour', 'test-plugin-td' ),
            'type' => \Elementor\Controls_Manager::TEXT,
            'label_block' => true,
            'placeholder' => __( 'First Name', 'test-plugin-td' ),
            'default' => __( 'First Name', 'test-plugin-td' ),
            'dynamic' => [
                'active' => true,
            ],
        ]
    );
    $this->add_control(
        'business_2hours',
        [
            'label' => __( 'Test Plugin', 'test-plugin-td' ),
            'type' => \Elementor\Controls_Manager::REPEATER,
            'fields' => $repeskeater->get_controls(),
            'default' => [
                [
                    'text' => __( 'First Name', 'test-plugin-td' ),
                ],
                [
                    'text' => __( 'Last Name', 'test-plugin-td' ),
                ],
            ],
            'title_field' => '{{{ text2 }}}',
        ]
    );

    $this->end_controls_section();
}

protected function render() {
    $settings = $this->get_settings_for_display();
    echo '<ul class="test-plugin-td">';
    foreach ( $settings['business_hours'] as $index => $item ) :
        $text_key = $this->get_repeater_setting_key( 'text', 'business_hours', $index );
        $this->add_inline_editing_attributes( $text_key );
        ?>
        <li class="business-hour-item">
            <span <?php $this->print_render_attribute_string( $text_key ); ?>>
                <?php echo esc_html( $item['text'] ); ?>
            </span>
        </li>
        <?php
    endforeach;
    echo '</ul>';

    echo '<ul class="test-plugin-td">';
    foreach ( $settings['business_2hours'] as $index => $item ) :
        $text_key = $this->get_repeater_setting_key( 'text2', 'business_2hours', $index );
        $this->add_inline_editing_attributes( $text_key );
        ?>
        <li class="business-hour-item">
            <span <?php $this->print_render_attribute_string( $text_key ); ?>>
                <?php echo esc_html( $item['text2'] ); ?>
            </span>
        </li>
        <?php
    endforeach;
    echo '</ul>';
}

解决方案&问题分析

我之前做Elementor Widget的时候也碰到过一模一样的问题,核心原因有两个,给你一步步解决:

1. 第二个Repeater的默认值key写错了(致命错误)

看你第二个Repeater的default配置里,用的是'text'作为key,但你第二个Repeater的文本控件key是text2啊!这个错误会导致Elementor无法正确映射默认值到控件,进而影响内联编辑的保存逻辑——因为Elementor找不到对应的控件绑定,修改后的数据就存不进去。

赶紧把第二个Repeater的default改成:

'default' => [
    [
        'text2' => __( 'First Name', 'test-plugin-td' ),
    ],
    [
        'text2' => __( 'Last Name', 'test-plugin-td' ),
    ],
],

2. 内联编辑属性要明确指定控件类型

虽然Elementor的add_inline_editing_attributes方法第二个参数是可选的,但在多Repeater场景下,必须明确指定控件类型(比如'basic'对应文本控件),这样Elementor才能准确识别不同Repeater里的控件,避免冲突。

修改render方法里的两行add_inline_editing_attributes代码:

  • 第一个Repeater的:
$this->add_inline_editing_attributes( $text_key, 'basic' );
  • 第二个Repeater的:
$this->add_inline_editing_attributes( $text_key, 'basic' );

3. 额外检查:确保Repeater实例完全独立

你这里已经新建了两个不同的Repeater实例($repeater和$repeskeater),这部分是对的,千万不要复用同一个Repeater实例来创建多个Repeater控件,否则一定会出现数据绑定冲突。

修正后的完整代码

protected function register_controls() {
    $this->start_controls_section(
        'content_section',
        [
            'label' => esc_html__( 'Test Plugin', 'test-plugin-td' ),
            'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
        ]
    );

    $repeater = new Repeater();
    $repeater->add_control(
        'text',
        [
            'label' => __( 'Business Hour', 'test-plugin-td' ),
            'type' => \Elementor\Controls_Manager::TEXT,
            'label_block' => true,
            'placeholder' => __( 'First Name', 'test-plugin-td' ),
            'default' => __( 'First Name', 'test-plugin-td' ),
            'dynamic' => [
                'active' => true,
            ],
        ]
    );
    $this->add_control(
        'business_hours',
        [
            'label' => __( 'Test Plugin', 'test-plugin-td' ),
            'type' => \Elementor\Controls_Manager::REPEATER,
            'fields' => $repeater->get_controls(),
            'default' => [
                [
                    'text' => __( 'First Name', 'test-plugin-td' ),
                ],
                [
                    'text' => __( 'Last Name', 'test-plugin-td' ),
                ],
            ],
            'title_field' => '{{{ text }}}',
        ]
    );

    $this->end_controls_section();


    $this->start_controls_section(
        'content_2section',
        [
            'label' => esc_html__( 'Test Plugin', 'test-plugin-td' ),
            'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
        ]
    );

    $repeskeater = new Repeater();
    $repeskeater->add_control(
        'text2',
        [
            'label' => __( 'Business Hour', 'test-plugin-td' ),
            'type' => \Elementor\Controls_Manager::TEXT,
            'label_block' => true,
            'placeholder' => __( 'First Name', 'test-plugin-td' ),
            'default' => __( 'First Name', 'test-plugin-td' ),
            'dynamic' => [
                'active' => true,
            ],
        ]
    );
    $this->add_control(
        'business_2hours',
        [
            'label' => __( 'Test Plugin', 'test-plugin-td' ),
            'type' => \Elementor\Controls_Manager::REPEATER,
            'fields' => $repeskeater->get_controls(),
            // 修正默认值的key为text2
            'default' => [
                [
                    'text2' => __( 'First Name', 'test-plugin-td' ),
                ],
                [
                    'text2' => __( 'Last Name', 'test-plugin-td' ),
                ],
            ],
            'title_field' => '{{{ text2 }}}',
        ]
    );

    $this->end_controls_section();
}

protected function render() {
    $settings = $this->get_settings_for_display();
    echo '<ul class="test-plugin-td">';
    foreach ( $settings['business_hours'] as $index => $item ) :
        $text_key = $this->get_repeater_setting_key( 'text', 'business_hours', $index );
        // 明确指定控件类型为basic
        $this->add_inline_editing_attributes( $text_key, 'basic' );
        ?>
        <li class="business-hour-item">
            <span <?php $this->print_render_attribute_string( $text_key ); ?>>
                <?php echo esc_html( $item['text'] ); ?>
            </span>
        </li>
        <?php
    endforeach;
    echo '</ul>';

    echo '<ul class="test-plugin-td">';
    foreach ( $settings['business_2hours'] as $index => $item ) :
        $text_key = $this->get_repeater_setting_key( 'text2', 'business_2hours', $index );
        // 明确指定控件类型为basic
        $this->add_inline_editing_attributes( $text_key, 'basic' );
        ?>
        <li class="business-hour-item">
            <span <?php $this->print_render_attribute_string( $text_key ); ?>>
                <?php echo esc_html( $item['text2'] ); ?>
            </span>
        </li>
        <?php
    endforeach;
    echo '</ul>';
}

做完这两个修改后,你再测试一下,两个Repeater的内联编辑应该都能正常保存了。


备注:内容来源于stack exchange,提问作者FERDAUSSK 01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 16:30:30