教你使用Theme Customizer添加设置
Theme Customizer(主题定制器)从 WordPress 3.4 引入至今,已经成了绝大多数主题开发者绕不开的一项功能。但根据 2023 年一项针对 WooCommerce 商店的调查,仍有大约 37% 的付费主题在后台使用传统的主题选项页面,而不是利用 Customizer 的原生能力。这个数据说明一个问题:很多人还在用旧办法,要么是不熟悉,要么是觉得 Customizer 写起来太麻烦。
如果你正在维护或开发一个 WordPress 主题,千万不要把 Customizer 当成一个可有可无的附加组件。它的实时预览机制是传统选项页无法替代的——用户在修改颜色、布局或文字时,能立刻看到前端效果,而不是等到保存后再刷新页面。这种体验不仅减少了用户反复保存、刷新的摩擦,也大大降低了误操作带来的页面崩溃风险。
今天我们就用最直白的方式,带你一步一步弄清楚怎么用 Customizer 添加一个真正能用的设置项。我会拿一个实际场景说话:假设你的小企业客户要求能在后台自由修改公司地址,并且地址要实时显示在页脚。我们就拿“公司地址”这个例子从头到尾走一遍。
所有 Customizer 相关的代码都要挂在 `customize_register` 这个 action 上。很多新手直接把代码扔在 functions.php 里,什么都没包,结果页面直接白屏。正确做法是:
add_action( 'customize_register', 'mytheme_customize_register' );
function mytheme_customize_register( $wp_customize ) {
// 这里写所有设置和控件
}
`$wp_customize` 是一个 `WP_Customize_Manager` 对象,所有添加 section、setting、control 的操作都通过它来完成。记住这个命名习惯:`mytheme_` 前缀能帮你避免函数冲突。
有些人一上来就创建十几个 section,把控制面板塞得密密麻麻。实际上,如果你的设置项只有一两个,完全可以放进 WordPress 自带的 section 里,比如 `title_tagline`(站点标识)、`colors`(颜色)、`static_front_page`(首页设置)。不过为了符合“公司地址”这个案例,我们新建一个专门的 section 会更清晰:
$wp_customize->add_section( 'mytheme_footer_section', array(
'title' => __( '页脚设置', 'mytheme' ),
'priority' => 80,
) );
`priority` 参数决定 section 在 Customizer 侧边栏里的排序位置,值越大越靠后。一般 80 左右放在“附加 CSS”前面,比较合理。
很多教程把 setting 和 control 混在一起讲,导致新手以为它们是一个东西。其实它们是两个独立的对象:
– **Setting**:负责存储数据到数据库的 `wp_options` 表(或 theme mod)。
– **Control**:负责在 Customizer 面板里展示 UI 控件(输入框、颜色选择器、下拉菜单等)。
一个 setting 可以对应多个 control(但很少这么做),一个 control 必须绑定唯一一个 setting。我们添加公司地址:
// 1. 先注册 setting
$wp_customize->add_setting( 'mytheme_footer_address', array(
'default' => '',
'sanitize_callback' => 'sanitize_text_field',
'transport' => 'refresh', // 或 'postMessage'
) );
// 2. 再注册 control
$wp_customize->add_control( 'mytheme_footer_address', array(
'label' => __( '公司地址', 'mytheme' ),
'section' => 'mytheme_footer_section',
'settings' => 'mytheme_footer_address',
'type' => 'text',
) );
看到没?`add_setting` 里 `sanitize_callback` 必须写上,否则等于把用户输入直接存进数据库,这是非常危险的做法。`sanitize_text_field` 是最基础的字符串过滤,如果你要存富文本,就得用 `wp_kses_post`。
`transport` 参数决定用户修改这个设置后,Customizer 前端如何更新预览。默认 `refresh` 会刷新整个预览窗口,比较慢但最兼容;而 `postMessage` 需要用 JavaScript 手动更新,功能更流畅但代码量增加。对初学者,先写 `refresh` 完全没问题。
光在后台存了数据没用,你得在前端输出。回到主题的 `footer.php`(或者你自定义的模板部分),写:
$address = get_theme_mod( 'mytheme_footer_address', '' );
if ( ! empty( $address ) ) {
echo '
' . esc_html( $address ) . '
';
}
注意:这里用的是 `get_theme_mod()` 而不是 `get_option()`,因为 `add_setting` 默认把数据存到了 theme mod 里(即 `wp_options` 表中以 `theme_mods_主题名` 为 key 的选项组)。如果你希望数据独立存储,可以在 `add_setting` 里指定 `’type’ => ‘option’`,但那样需要额外管理默认值,一般不推荐。
如果你希望用户修改地址时不需要刷新就能看到新地址,就要用 `postMessage` 配合 JavaScript。在 `add_setting` 中设置 `’transport’ => ‘postMessage’`,然后在主题文件夹下新建一个 `customizer.js`(或者把代码加到已有的 JS 文件里),通过 `wp.customize` API 监听变化:
(function( $ ) {
wp.customize( 'mytheme_footer_address', function( value ) {
value.bind( function( newval ) {
$( '.footer-address' ).text( newval );
} );
} );
})( jQuery );
然后记得在 `functions.php` 里注册这个脚本:
add_action( 'customize_preview_init', 'mytheme_customize_preview_js' );
function mytheme_customize_preview_js() {
wp_enqueue_script( 'mytheme-customizer', get_template_directory_uri() . '/js/customizer.js', array( 'jquery', 'customize-preview' ), '1.0', true );
}
这样一来,客户在输入框里打字,页脚的地址就立刻跟着变化,体验直接上一个档次。
除了 `text` 类型,Customizer 还内置了 `textarea`、`checkbox`、`select`、`radio`、`color`、`image` 等控件。很多人写 `add_control` 的时候直接抄网上的代码,比如上面那个例子用了标准 `WP_Customize_Control`,如果想用下拉菜单,就需要实例化 `WP_Customize_Control` 的子类。更常见的是使用 `WP_Customize_Color_Control` 来做颜色选择器:
$wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'mytheme_link_color', array(
'label' => __( '链接颜色', 'mytheme' ),
'section' => 'colors',
'settings' => 'mytheme_link_color',
) ) );
注意这里把 `type` 参数去掉了,因为子类自己定义了控件样式。
如果你添加了五六个设置却全扔在一个 section 里,侧边栏会变成一列密密麻麻的控件。适当使用 `priority` 和 `description` 能让界面清爽很多。比如在 section 里加一段说明文字:
$wp_customize->add_section( 'mytheme_footer_section', array(
'title' => __( '页脚设置', 'mytheme' ),
'description' => __( '修改页脚显示的地址、电话等信息,修改后自动保存。', 'mytheme' ),
'priority' => 80,
如本文"对您有用",欢迎随意打赏,让我们坚持创作!~
暂无目录
