咳咳,各位观众老爷,大家好!今天咱们来聊聊 WordPress 定制器背后的男人—— WP_Customize_Manager
类。这哥们儿,掌管着整个定制器的生杀大权,你的主题选项是美是丑,全看他心情(当然,更准确地说,是看你代码写得好不好)。咱们今天就扒开他的裤衩,啊不,源码,看看他是怎么通过 $settings
和 $controls
这两个左膀右臂来管理定制器选项的。
一、 WP_Customize_Manager
:定制器的幕后大佬
首先,咱们得认识一下 WP_Customize_Manager
这个类。 简单来说,它就是 WordPress 定制器的核心管理器。 你在后台看到的定制器界面,以及你能修改的各种选项,都是通过这个类来组织和控制的。 当你在 functions.php
或者插件里使用 WP_Customize_Manager
的实例(通常是 $wp_customize
全局变量)来添加 section、setting、control 时,实际上就是在跟这位大佬打交道。
二、 $settings
:选项的“户口本”
WP_Customize_Manager
的 $settings
属性,是一个关联数组,存储了所有定制器选项的 WP_Customize_Setting
对象。 每个选项(比如主题颜色、logo 图片)都有一个对应的 WP_Customize_Setting
对象,它就像是这个选项的“户口本”,记录了选项的各种信息,比如:
id
(string): 选项的唯一标识符,就像选项的身份证号。default
(mixed): 选项的默认值,就像选项的出生时的初始状态。transport
(string): 选项的传输方式,决定了选项值的更新方式(refresh
还是postMessage
)。type
(string): 选项的数据类型,默认是theme_mod
,表示主题选项。capability
(string): 拥有修改这个选项的权限。sanitize_callback
(callable): 用于清理和验证选项值的回调函数,确保数据的安全性。validate_callback
(callable): 用于验证选项值的回调函数。dirty
(bool): 标记选项是否被修改过。
$settings
数组的键就是选项的 id
,值就是对应的 WP_Customize_Setting
对象。 我们可以用以下代码来获取某个选项的 WP_Customize_Setting
对象:
global $wp_customize;
$setting = $wp_customize->get_setting( 'blogname' );
if ( $setting ) {
echo '选项 ID: ' . $setting->id . '<br>';
echo '默认值: ' . $setting->default . '<br>';
echo '传输方式: ' . $setting->transport . '<br>';
echo '数据类型: ' . $setting->type . '<br>';
}
这段代码会尝试获取 blogname
选项的 WP_Customize_Setting
对象,如果找到了,就输出它的 id
、default
和 transport
属性。
三、 $controls
:选项的“展示台”
WP_Customize_Manager
的 $controls
属性,也是一个关联数组,存储了所有定制器控件的 WP_Customize_Control
对象。 每个控件(比如文本框、颜色选择器、图片上传器)都负责在定制器界面上展示一个选项,并允许用户修改它的值。 控件和选项之间存在着紧密的联系:一个控件通常会关联到一个选项,用于控制该选项的值。
WP_Customize_Control
对象也有一堆属性,其中比较重要的有:
id
(string): 控件的唯一标识符,就像控件的身份证号。label
(string): 控件的标签,显示在定制器界面上,告诉用户这个控件是干嘛的。section
(string): 控件所属的 section 的 ID,决定了控件在定制器界面上的位置。settings
(string|array): 控件关联的选项的 ID,或者是一个包含多个选项 ID 的数组。priority
(int): 控件的优先级,决定了控件在 section 中的显示顺序。active_callback
(callable): 一个回调函数,用于控制控件是否显示,可以根据其他选项的值来动态地显示或隐藏控件。
$controls
数组的键就是控件的 id
,值就是对应的 WP_Customize_Control
对象。 我们可以用以下代码来获取某个控件的 WP_Customize_Control
对象:
global $wp_customize;
$control = $wp_customize->get_control( 'blogname' );
if ( $control ) {
echo '控件 ID: ' . $control->id . '<br>';
echo '标签: ' . $control->label . '<br>';
echo '所属 section: ' . $control->section . '<br>';
echo '关联的选项: ' . $control->settings . '<br>';
}
这段代码会尝试获取 blogname
控件的 WP_Customize_Control
对象,如果找到了,就输出它的 id
、label
、section
和 settings
属性。
四、 $settings
和 $controls
的关系:相辅相成,缺一不可
$settings
和 $controls
就像一对好基友,一个负责存储选项的数据,一个负责展示选项的界面。 没有 $settings
,$controls
就失去了控制的对象,就像没了灵魂的躯壳。 没有 $controls
,$settings
就无法被用户修改,就像藏在深闺的千金小姐。
它们之间的关系可以用下图简单表示:
+---------------------+ +---------------------+
| WP_Customize_Setting|----| WP_Customize_Control|
| (选项数据) | | (界面控件) |
+---------------------+ +---------------------+
| setting_id | | settings |
| (选项 ID) | | (关联的选项 ID) |
+---------------------+ +---------------------+
可以看到,WP_Customize_Control
对象通过 settings
属性关联到 WP_Customize_Setting
对象。 当用户在定制器界面上修改控件的值时,WP_Customize_Control
对象会将新的值传递给对应的 WP_Customize_Setting
对象,然后 WP_Customize_Setting
对象会负责清理、验证和保存这个值。
五、 如何使用 $settings
和 $controls
添加定制器选项
现在,咱们来演示一下如何使用 $settings
和 $controls
来添加一个定制器选项。 假设我们要添加一个选项,让用户可以修改网站的背景颜色。
首先,我们需要在 functions.php
或者插件里添加以下代码:
add_action( 'customize_register', 'my_theme_customize_register' );
function my_theme_customize_register( $wp_customize ) {
// 1. 添加一个 section
$wp_customize->add_section( 'my_theme_background_section', array(
'title' => __( '背景设置', 'my-theme' ),
'priority' => 30,
) );
// 2. 添加一个 setting
$wp_customize->add_setting( 'my_theme_background_color', array(
'default' => '#ffffff',
'sanitize_callback' => 'sanitize_hex_color', // 使用 WordPress 内置的清理函数
'transport' => 'postMessage', // 使用 postMessage 方式实时预览
) );
// 3. 添加一个 control
$wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'my_theme_background_color', array(
'label' => __( '背景颜色', 'my-theme' ),
'section' => 'my_theme_background_section',
'settings' => 'my_theme_background_color',
) ) );
// 4. 添加 JavaScript 代码,实现实时预览
?>
<script type="text/javascript">
( function( $ ) {
wp.customize( 'my_theme_background_color', function( value ) {
value.bind( function( newval ) {
$( 'body' ).css( 'background-color', newval );
} );
} );
} )( jQuery );
</script>
<?php
}
这段代码做了以下几件事:
- 添加一个 section: 使用
$wp_customize->add_section()
方法添加一个名为my_theme_background_section
的 section,用于组织背景相关的选项。 - 添加一个 setting: 使用
$wp_customize->add_setting()
方法添加一个名为my_theme_background_color
的 setting,用于存储背景颜色值。 这里指定了默认值为#ffffff
,并使用了sanitize_hex_color
函数来清理用户输入的值,确保它是一个有效的十六进制颜色值。transport
设置为postMessage
,表示使用 JavaScript 通过postMessage
API 来实时预览背景颜色。 - 添加一个 control: 使用
$wp_customize->add_control()
方法添加一个名为my_theme_background_color
的 control,用于在定制器界面上展示颜色选择器。 这里使用了WP_Customize_Color_Control
类,它是 WordPress 内置的颜色选择器控件。section
设置为my_theme_background_section
,表示将这个控件放在背景设置 section 中。settings
设置为my_theme_background_color
,表示这个控件控制的是my_theme_background_color
选项。 - 添加 JavaScript 代码: 添加了一段 JavaScript 代码,用于实现实时预览。 这段代码使用
wp.customize()
API 监听my_theme_background_color
选项的变化,当选项值发生变化时,就将body
元素的背景颜色设置为新的值。
完成以上步骤后,你就可以在定制器界面上看到一个新的 section,里面有一个颜色选择器,可以用来修改网站的背景颜色。 而且,当你修改颜色时,网站的背景颜色会实时更新,让你立刻看到效果。
六、 一些高级技巧和注意事项
- 使用
active_callback
动态显示/隐藏控件: 你可以使用active_callback
属性来动态地显示或隐藏控件。active_callback
是一个回调函数,它接受一个WP_Customize_Control
对象作为参数,并返回一个布尔值。 如果返回true
,则显示控件,否则隐藏控件。 例如,你可以根据某个选项的值来决定是否显示另一个选项的控件。
$wp_customize->add_control( 'my_theme_show_header', array(
'label' => __( '显示头部', 'my-theme' ),
'section' => 'my_theme_header_section',
'settings' => 'my_theme_show_header',
'type' => 'checkbox',
) );
$wp_customize->add_control( 'my_theme_header_text', array(
'label' => __( '头部文字', 'my-theme' ),
'section' => 'my_theme_header_section',
'settings' => 'my_theme_header_text',
'active_callback' => function( $control ) use ( $wp_customize ) {
return $wp_customize->get_setting( 'my_theme_show_header' )->value();
},
) );
这段代码中,my_theme_header_text
控件的 active_callback
函数会检查 my_theme_show_header
选项的值。 如果 my_theme_show_header
选项的值为 true
(即显示头部),则显示 my_theme_header_text
控件,否则隐藏 my_theme_header_text
控件。
-
使用
WP_Customize_Setting
的sanitize_callback
和validate_callback
确保数据的安全性:sanitize_callback
用于清理和转换用户输入的值,validate_callback
用于验证用户输入的值。 你应该始终使用这两个回调函数来确保数据的安全性,防止恶意代码注入。 -
合理使用
transport
属性:transport
属性决定了选项值的更新方式。refresh
表示刷新整个页面来更新选项值,postMessage
表示使用 JavaScript 通过postMessage
API 来实时预览。 一般来说,对于简单的选项(比如颜色、文本),可以使用postMessage
来实现实时预览,对于复杂的选项(比如布局、样式),可以使用refresh
来刷新整个页面。 -
避免过度使用定制器: 虽然定制器很强大,但也不要过度使用它。 对于一些复杂的选项,最好还是使用主题选项页面来实现,而不是把所有的选项都放在定制器里。
七、 总结
今天咱们聊了 WP_Customize_Manager
类的 $settings
和 $controls
属性,以及如何使用它们来添加定制器选项。 $settings
负责存储选项的数据,$controls
负责展示选项的界面。 它们之间的关系是相辅相成,缺一不可。 通过合理使用这两个属性,你可以轻松地为你的主题添加各种各样的定制器选项,让用户可以自由地定制他们的网站。
希望今天的讲座对大家有所帮助。 如果大家还有什么问题,欢迎提问。 咱们下期再见!