Elementor 自定义块开发:add_control 全参数详解
在 WordPress 主题内嵌 Elementor 自定义块(Widget)开发中,add_control() 是核心方法------它决定了后台控制面板的所有交互和配置项。很多开发者只用到基础参数,却忽略了其强大的高级参数(如 condition、options 等),导致控件灵活性不足、适配性差。
本文将以主题路径 wp-content/themes/ele-themes/src/Elementor/Widgets/Services.php 为例,手把手拆解 add_control() 所有常用参数,每个 key 后面直接备注用途,全程实战可复制,新手也能轻松上手,适合收藏备用、直接发表学习。
先明确前提:本文所有示例均适配 Elementor 免费版,基于主题内嵌开发(非独立插件),命名空间、文件路径完全贴合 ele-themes 主题,复制到你的 Services.php 【Services.php是块名称】即可直接使用。
一、核心基础:add_control() 整体结构
先看 add_control() 的通用结构,后续所有参数均围绕这个结构展开,每个部分的作用直接备注在后面:
Plain
$this->add_control(
'control_id', // 【必选】控件唯一标识(英文,后续前端渲染、样式控制需用到,不可重复)
[
'label' => '控件名称', // 【必选】后台显示的控件标题,直观告诉用户这个控件的作用
'type' => Controls_Manager::TEXT, // 【必选】控件类型(文本、开关、下拉等,决定控件形态)
// 以下是所有常用高级参数,每个均带备注
'default' => '默认值', // 【可选】控件的默认显示值,减少用户输入成本
'label_block' => true, // 【可选】是否让控件占满后台编辑区整行,提升美观度和操作便捷性
'label_on' => '开启', // 【可选】仅适用于开关(SWITCHER)控件,开启状态显示的文字
'label_off' => '关闭', // 【可选】仅适用于开关(SWITCHER)控件,关闭状态显示的文字
'rows' => 4, // 【可选】仅适用于多行文本(TEXTAREA),设置输入框的高度(行数)
'options' => [], // 【可选】适用于下拉(SELECT)、选择按钮(CHOOSE)等,设置可选选项列表
'condition' => [], // 【可选】条件显示,根据其他控件的取值,决定当前控件是否显示
'show_external' => true, // 【可选】仅适用于链接(URL)控件,是否显示"在新窗口打开"的勾选框
'prevent_empty' => false, // 【可选】仅适用于链接(URL)控件,是否禁止用户留空(true=必须填写)
'placeholder' => '请输入内容', // 【可选】输入类控件的提示文本,引导用户正确输入
'description' => '控件说明', // 【可选】控件下方的辅助说明,解释该控件的用途、注意事项
'min' => 0, // 【可选】仅适用于数字(NUMBER)、滑块(SLIDER),设置最小值
'max' => 100, // 【可选】仅适用于数字(NUMBER)、滑块(SLIDER),设置最大值
'step' => 1, // 【可选】仅适用于数字(NUMBER)、滑块(SLIDER),设置每次增减的步长
'suffix' => 'px', // 【可选】仅适用于数字(NUMBER)、滑块(SLIDER),设置单位(如px、%)
'multiple' => false, // 【可选】仅适用于SELECT2控件,是否允许多选
]
);
二、实战示例:全覆盖所有参数的add_control用法
以下示例均嵌入 Services.php 的 register_controls() 方法中,完全贴合的主题(ele-themes),每个控件都对应服务块的实际需求,参数备注清晰,可直接复制使用。
先给出完整的类结构(确保和你的主题路径、命名空间一致),再逐个展示控件示例:
Plain
<?php
namespace Travel_Agent\Elementor\Widgets; // 【主题专属命名空间】贴合ele-themes主题
use Elementor\Widget_Base;
use Elementor\Controls_Manager;
use Elementor\Repeater;
if (!defined('ABSPATH')) exit; // 禁止直接访问文件
/**
* 主题服务块(Services)- Elementor自定义控件实战
*/
class Services extends Widget_Base {
// 小工具基础信息(必写,和add_control无关,仅保证代码可运行)
public function get_name() {
return 'agent_services'; // 小工具唯一标识
}
public function get_title() {
return esc_html__('服务展示块', 'travel-agent'); // 后台显示标题
}
public function get_icon() {
return 'eicon-icon-box'; // 小工具图标
}
public function get_categories() {
return ['general', 'travel-agent']; // 小工具分类(主题专属分类更规范)
}
// 核心:注册所有控件(重点看这里的add_control示例)
protected function register_controls() {
// 第一个控件组:服务基础设置(方便后台分类管理)
$this->start_controls_section(
'section_service_basic',
[
'label' => esc_html__('基础设置', 'travel-agent'),
'tab' => Controls_Manager::TAB_CONTENT, // 放在"内容"选项卡
]
);
// 1. 文本输入框(TEXT)- 服务标题(覆盖label_block、default、placeholder、description)
$this->add_control(
'service_main_title', // 【控件唯一标识】后续渲染用,英文无空格
[
'label' => esc_html__('服务主标题', 'travel-agent'), // 【控件显示名称】后台直观看到
'type' => Controls_Manager::TEXT, // 【控件类型】文本输入框
'default' => esc_html__('我们的核心服务', 'travel-agent'), // 【默认值】用户无需手动输入,直接显示
'label_block' => true, // 【占满整行】让控件在后台编辑区占满一行,更美观
'placeholder' => esc_html__('请输入服务主标题(如:我们的核心服务)', 'travel-agent'), // 【提示文本】引导用户输入
'description' => esc_html__('该标题将显示在服务块顶部,建议控制在15字以内', 'travel-agent'), // 【辅助说明】告诉用户注意事项
]
);
// 2. 开关控件(SWITCHER)- 是否显示主标题(覆盖label_on、label_off、return_value)
$this->add_control(
'show_main_title', // 【控件唯一标识】用于后续condition判断
[
'label' => esc_html__('显示主标题', 'travel-agent'), // 【控件显示名称】
'type' => Controls_Manager::SWITCHER, // 【控件类型】开关控件(yes/no)
'label_on' => esc_html__('显示', 'travel-agent'), // 【开启状态文字】开关打开时显示"显示"
'label_off' => esc_html__('隐藏', 'travel-agent'), // 【关闭状态文字】开关关闭时显示"隐藏"
'return_value' => 'yes', // 【返回值】开启时返回yes,关闭时返回false(可自定义)
'default' => 'yes', // 【默认值】默认开启显示
]
);
// 3. 下拉选择器(SELECT)- 服务布局样式(覆盖options、condition)
$this->add_control(
'service_layout', // 【控件唯一标识】后续前端渲染布局用
[
'label' => esc_html__('服务布局样式', 'travel-agent'), // 【控件显示名称】
'type' => Controls_Manager::SELECT, // 【控件类型】下拉选择器
'options' => [ // 【可选选项】下拉列表的选项,key是存储值,value是显示文本
'grid' => esc_html__('网格布局(推荐)', 'travel-agent'),
'list' => esc_html__('列表布局', 'travel-agent'),
'slider' => esc_html__('轮播布局', 'travel-agent'),
],
'default' => 'grid', // 【默认值】默认选择网格布局
'condition' => [ // 【条件显示】只有当show_main_title为yes时,才显示这个控件
'show_main_title' => 'yes'
],
'description' => esc_html__('选择服务块的展示布局,网格布局适配移动端', 'travel-agent'),
]
);
// 4. 多行文本框(TEXTAREA)- 服务简介(覆盖rows)
$this->add_control(
'service_intro', // 【控件唯一标识】后续渲染服务简介用
[
'label' => esc_html__('服务简介', 'travel-agent'), // 【控件显示名称】
'type' => Controls_Manager::TEXTAREA, // 【控件类型】多行文本框
'rows' => 4, // 【输入框行数】设置文本框高度,4行足够输入简介(可调整)
'default' => esc_html__('专注提供高品质旅游服务,涵盖酒店预订、景点门票、定制行程等一站式服务,让您的旅行更省心。', 'travel-agent'),
'label_block' => true,
'placeholder' => esc_html__('请输入服务简介,简要介绍服务内容', 'travel-agent'),
]
);
// 5. 链接控件(URL)- 更多服务链接(覆盖show_external、prevent_empty)
$this->add_control(
'more_service_link', // 【控件唯一标识】后续渲染链接用
[
'label' => esc_html__('更多服务链接', 'travel-agent'), // 【控件显示名称】
'type' => Controls_Manager::URL, // 【控件类型】链接输入控件
'show_external' => true, // 【显示新窗口选项】显示"在新窗口打开"的勾选框,用户可选择
'prevent_empty' => false, // 【允许留空】false=可留空(不强制用户填写),true=必须填写
'placeholder' => esc_html__('https://www.example.com/services', 'travel-agent'),
'description' => esc_html__('点击"更多服务"按钮跳转的地址,留空则不显示该按钮', 'travel-agent'),
]
);
// 6. 数字输入框(NUMBER)- 服务卡片间距(覆盖min、max、step、suffix)
$this->add_control(
'card_spacing', // 【控件唯一标识】后续控制样式用
[
'label' => esc_html__('服务卡片间距', 'travel-agent'), // 【控件显示名称】
'type' => Controls_Manager::NUMBER, // 【控件类型】数字输入框
'default' => 20, // 【默认值】默认间距20px
'min' => 0, // 【最小值】间距不能小于0px
'max' => 50, // 【最大值】间距不能大于50px
'step' => 2, // 【步长】每次增减2px,更精准
'suffix' => 'px', // 【单位】显示px,告诉用户输入的是像素值
'condition' => [ // 【条件显示】只有布局为网格时,才显示间距设置
'service_layout' => 'grid'
],
]
);
// 7. 选择按钮(CHOOSE)- 文字对齐方式(覆盖options)
$this->add_control(
'text_align', // 【控件唯一标识】后续控制文字对齐样式用
[
'label' => esc_html__('文字对齐方式', 'travel-agent'), // 【控件显示名称】
'type' => Controls_Manager::CHOOSE, // 【控件类型】选择按钮(直观易懂)
'options' => [ // 【可选选项】每个选项带标题和图标,更直观
'left' => [
'title' => esc_html__('左对齐', 'travel-agent'),
'icon' => 'eicon-text-align-left' // Elementor内置图标
],
'center' => [
'title' => esc_html__('居中对齐', 'travel-agent'),
'icon' => 'eicon-text-align-center'
],
'right' => [
'title' => esc_html__('右对齐', 'travel-agent'),
'icon' => 'eicon-text-align-right'
],
],
'default' => 'center', // 【默认值】默认居中对齐
'label_block' => true,
]
);
// 8. 多选下拉(SELECT2)- 显示的服务类型(覆盖multiple、options)
$this->add_control(
'service_types', // 【控件唯一标识】后续筛选服务用
[
'label' => esc_html__('显示的服务类型', 'travel-agent'), // 【控件显示名称】
'type' => Controls_Manager::SELECT2, // 【控件类型】支持搜索的下拉控件
'label_block' => true,
'multiple' => true, // 【允许多选】用户可选择多个服务类型
'options' => [ // 【可选选项】旅游主题常用服务类型
'hotel' => esc_html__('酒店预订', 'travel-agent'),
'ticket' => esc_html__('景点门票', 'travel-agent'),
'custom' => esc_html__('定制行程', 'travel-agent'),
'transfer' => esc_html__('接送服务', 'travel-agent'),
'guide' => esc_html__('导游服务', 'travel-agent'),
],
'default' => ['hotel', 'ticket'], // 【默认值】默认显示酒店和门票服务
]
);
$this->end_controls_section(); // 结束基础设置控件组
// 第二个控件组:服务项设置(用Repeater,可添加多个服务,顺带演示Repeater中的add_control)
$this->start_controls_section(
'section_service_items',
[
'label' => esc_html__('服务项设置', 'travel-agent'),
'tab' => Controls_Manager::TAB_CONTENT,
]
);
// 重复器(Repeater)- 可添加多个服务项
$repeater = new Repeater();
// Repeater中的文本控件(复用前面的参数,重点演示condition)
$repeater->add_control(
'item_title', // 【Repeater控件唯一标识】每个服务项的标题
[
'label' => esc_html__('服务项标题', 'travel-agent'),
'type' => Controls_Manager::TEXT,
'default' => esc_html__('酒店预订', 'travel-agent'),
'label_block' => true,
'placeholder' => esc_html__('请输入单个服务项标题', 'travel-agent'),
]
);
// Repeater中的图标控件(新增,演示基础用法)
$repeater->add_control(
'item_icon', // 【Repeater控件唯一标识】每个服务项的图标
[
'label' => esc_html__('服务项图标', 'travel-agent'),
'type' => Controls_Manager::ICONS, // 【控件类型】图标选择器
'default' => [
'value' => 'fas fa-hotel', // 默认图标
'library' => 'fa-solid',
],
]
);
// Repeater中的链接控件(覆盖prevent_empty=true)
$repeater->add_control(
'item_link', // 【Repeater控件唯一标识】每个服务项的链接
[
'label' => esc_html__('服务项链接', 'travel-agent'),
'type' => Controls_Manager::URL,
'show_external' => true,
'prevent_empty' => true, // 【禁止留空】每个服务项必须填写链接
'placeholder' => esc_html__('https://www.example.com/hotel', 'travel-agent'),
'condition' => [ // 【条件显示】只有服务类型包含酒店时,才显示该链接控件
'service_types' => 'hotel'
],
]
);
// 将Repeater添加到主控件中
$this->add_control(
'service_items', // 【Repeater唯一标识】后续渲染所有服务项用
[
'label' => esc_html__('服务项列表', 'travel-agent'),
'type' => Controls_Manager::REPEATER,
'fields' => $repeater->get_controls(), // 引入Repeater中的所有控件
'default' => [ // 默认添加2个服务项
[
'item_title' => esc_html__('酒店预订', 'travel-agent'),
'item_icon' => ['value' => 'fas fa-hotel', 'library' => 'fa-solid'],
],
[
'item_title' => esc_html__('景点门票', 'travel-agent'),
'item_icon' => ['value' => 'fas fa-ticket-alt', 'library' => 'fa-solid'],
],
],
'title_field' => '{{{ item_title }}}', // Repeater列表中显示的标题(用服务项标题)
]
);
$this->end_controls_section(); // 结束服务项控件组
}
// 前端渲染(简化版,仅演示如何调用控件值,不影响add_control讲解)
protected function render() {
$settings = $this->get_settings_for_display(); // 获取所有控件的值
// 渲染逻辑(可根据自己的需求扩展)
echo '';
if ($settings['show_main_title'] === 'yes') {
echo '' . $settings['service_main_title'] . '';
}
echo '';
}
// 编辑器预览(可选,为空则使用前端渲染逻辑)
protected function content_template() {}
}
?>
三、重点参数单独拆解(新手必看)
上面的示例已经覆盖了所有你要求的参数,这里单独把核心参数拎出来,再详细拆解一遍,方便快速查阅,发表时可作为"重点笔记"部分:
1. condition(条件显示,最常用高级参数)
作用:根据其他控件的取值,动态显示/隐藏当前控件,避免后台控件过多、杂乱。
核心逻辑:'condition' => ['其他控件id' => '目标值'],支持多条件(用数组嵌套),示例:
Plain
'condition' => [
'show_main_title' => 'yes', // 主条件:显示主标题为开启
'service_layout' => ['grid', 'list'] // 多值条件:布局为网格或列表
]
2. options(选项列表,下拉/选择按钮必备)
作用:定义下拉选择器(SELECT)、选择按钮(CHOOSE)等控件的可选内容,key是存储到数据库的值,value是后台显示的文本,建议key用英文,value用中文(适配多语言)。
3. label_block(提升体验,必加参数)
作用:让控件在后台编辑区占满整行,默认情况下,控件标签和输入框在同一行,标签较长时会挤压输入框,设置为true后,标签在上、输入框在下,更美观、更好操作。
4. label_on / label_off(开关控件专属)
作用:自定义开关控件的显示文字,默认是"On/Off",改成中文"显示/隐藏"更符合中文用户习惯,提升后台易用性。
5. rows(多行文本专属)
作用:控制多行文本框(TEXTAREA)的高度,根据输入内容的多少设置合适的行数(一般3-5行),避免文本框过高或过低,提升用户输入体验。
6. show_external(链接控件专属)
作用:显示"在新窗口打开"的勾选框,用户可自主选择链接是否在新窗口打开,无需开发者硬编码,更灵活。
7. prevent_empty(链接控件专属)
作用:控制链接是否允许留空,true表示必须填写,false表示可以留空,根据实际需求设置(如必填链接就设为true)。
四、实战注意事项(发表时补充,提升文章价值)
-
控件id必须唯一:每个
add_control()的第一个参数(control_id),在整个类中不能重复,否则会覆盖之前的控件,建议用"前缀+功能"命名(如service_main_title)。 -
命名空间适配主题:本文示例的命名空间
Travel_Agent\Elementor\Widgets,需和你主题的命名空间一致,若主题无自定义命名空间,可删除命名空间,直接使用全局类。 -
参数按需使用:不是所有参数都要加,比如文本控件不需要
label_on,开关控件不需要rows,根据控件类型和实际需求选择参数。 -
多语言适配:所有显示文本(label、default、description等),建议用
esc_html__()包裹,方便后续做主题多语言翻译。 -
测试验证:添加完控件后,进入Elementor编辑器,拖拽该服务块,检查每个控件是否正常显示、参数是否生效,避免语法错误。
五、总结
Elementor 的 add_control() 看似简单,实则包含很多实用的高级参数,合理运用这些参数(尤其是condition、options),能让你的自定义块更灵活、更易用,适配更多场景。
本文所有示例均基于 ele-themes 主题,路径、命名空间完全匹配,复制到 src/Elementor/Widgets/Services.php 即可直接使用,新手也能快速上手。
如果需要扩展更多控件(如颜色选择、图片上传、富文本等),可在评论区留言,后续将补充更多实战示例。