咳咳,各位观众老爷,晚上好!欢迎来到今天的“WordPress主题定制内幕”讲座。我是今天的讲师,老司机带你飞~
今天咱们要聊的是WordPress主题定制里一个非常核心的东西:WP_Customize_Setting
类。这玩意儿就像主题选项和数据库之间的一根神奇的线,把它们紧紧地绑在一起,实现了双向绑定。听起来有点抽象?别怕,咱们一步步来,保证你听完之后,也能自己捏一个出来。
一、WP_Customize_Setting
是个啥?
首先,咱们得知道 WP_Customize_Setting
到底是干什么的。简单来说,它是WordPress Customizer(主题定制器)里用来表示一个设置项的类。这个设置项可以是主题颜色、Logo、字体大小等等,任何你想让用户自定义的东西,都可以用它来表示。
更重要的是,它负责:
- 定义设置项的属性: 比如设置项的ID、类型、默认值、传输方式等等。
- 与数据库交互: 读取设置项的值,并把用户修改后的值保存到数据库里。
- 验证和过滤: 对用户输入的值进行验证,确保数据的合法性,并进行过滤,防止恶意代码注入。
- 实时预览: 把用户修改后的值实时地反映到主题预览中。
可以把它想象成一个中间人,夹在主题选项和数据库之间,负责传递信息,确保一切都井井有条。
二、WP_Customize_Setting
的核心属性
WP_Customize_Setting
类有很多属性,但最核心的几个是:
属性名 | 类型 | 描述 |
---|---|---|
$id |
string | 设置项的唯一ID,就像人的身份证号一样。 |
$transport |
string | 设置项的传输方式,可以是 postMessage (实时预览)或 refresh (刷新页面)。 |
$capability |
string | 用户需要具备的权限才能修改这个设置项。 |
$default |
mixed | 设置项的默认值,如果用户没有自定义,就使用这个值。 |
$type |
string | 设置项的类型,可以是 theme_mod (主题选项)或 option (普通选项)。 theme_mod 会存储在 wp_options 表中,键名为 theme_mods_{主题名} ,而 option 则是直接存储在 wp_options 表中,键名为 $id 。 |
$sanitize_callback |
callable | 用于清理和验证用户输入的回调函数。 |
$validate_callback |
callable | 用于验证用户输入的回调函数(在sanitization之前执行)。 |
$dirty |
boolean | 标记设置是否已更改。 自定义器在初始化时会设置为 false ,当设置值被更改时,会设置为 true 。 这对于判断是否需要执行某些操作非常有用,例如在保存设置之前执行某些清理工作。 |
这些属性决定了 WP_Customize_Setting
的行为,咱们后面会详细讲解。
三、WP_Customize_Setting
是如何工作的?(源码剖析)
现在咱们来深入源码,看看 WP_Customize_Setting
是如何实现双向绑定的。
- 实例化
WP_Customize_Setting
首先,你需要在 Customizer 里注册一个 WP_Customize_Setting
实例。比如:
<?php
add_action( 'customize_register', 'my_theme_customize_register' );
function my_theme_customize_register( $wp_customize ) {
$wp_customize->add_setting(
'my_theme_primary_color',
array(
'default' => '#007bff',
'transport' => 'postMessage',
'sanitize_callback' => 'sanitize_hex_color',
)
);
$wp_customize->add_control(
new WP_Customize_Color_Control(
$wp_customize,
'my_theme_primary_color',
array(
'label' => __( 'Primary Color', 'my-theme' ),
'section' => 'colors',
'settings' => 'my_theme_primary_color',
)
)
);
}
?>
这段代码做了几件事:
add_action( 'customize_register', 'my_theme_customize_register' )
:在 Customizer 初始化时,执行my_theme_customize_register
函数。$wp_customize->add_setting( 'my_theme_primary_color', ... )
:注册一个名为my_theme_primary_color
的设置项。default
:设置默认值为#007bff
。transport
:设置传输方式为postMessage
(实时预览)。sanitize_callback
:设置清理回调函数为sanitize_hex_color
(确保用户输入的是合法的十六进制颜色值)。
$wp_customize->add_control( new WP_Customize_Color_Control( ... ) )
:添加一个颜色选择控件,让用户可以修改这个设置项的值。
add_setting()
内部会创建一个 WP_Customize_Setting
对象,并把它添加到 $wp_customize
对象的 $settings
属性中。
- 从数据库读取值
当 Customizer 加载时,WP_Customize_Setting
会从数据库读取设置项的值。这个过程通常发生在 WP_Customize_Setting::value()
方法中。
<?php
/**
* Get the current value of the setting.
*
* @return mixed The setting value.
*/
public function value() {
if ( isset( $this->value ) ) {
return $this->value;
}
$this->value = $this->default; // Start with the default.
if ( 'theme_mod' === $this->type ) {
$theme_mod_value = get_theme_mod( $this->id );
if ( false !== $theme_mod_value ) {
$this->value = $theme_mod_value;
}
} elseif ( 'option' === $this->type ) {
$option_value = get_option( $this->id );
if ( false !== $option_value ) {
$this->value = $option_value;
}
}
/**
* Filters the return value of WP_Customize_Setting::value().
*
* @since 4.2.0
*
* @param mixed $value The setting value.
* @param WP_Customize_Setting $this WP_Customize_Setting instance.
*/
$this->value = apply_filters( 'customize_value_' . $this->id, $this->value, $this );
return $this->value;
}
?>
这个方法做了几件事:
- 首先,检查
$this->value
是否已经存在,如果存在,直接返回。这是为了避免重复读取数据库。 - 如果
$this->value
不存在,就把它初始化为$this->default
(默认值)。 - 然后,根据
$this->type
的值,从数据库读取设置项的值:- 如果
$this->type
是theme_mod
,就调用get_theme_mod( $this->id )
从wp_options
表中读取theme_mods_{主题名}
选项的值。 - 如果
$this->type
是option
,就调用get_option( $this->id )
从wp_options
表中读取$this->id
选项的值。
- 如果
- 最后,应用一个过滤器
customize_value_{$this->id}
,允许其他代码修改设置项的值。
- 用户修改值
当用户在 Customizer 里修改设置项的值时,Customizer 会通过 AJAX 请求把新的值发送到服务器。服务器端的 WP_Customize_Setting::sanitize()
方法会被调用,对新的值进行清理和验证。
<?php
/**
* Sanitize a value.
*
* @param mixed $value Raw value.
* @return mixed Sanitized value.
*/
public function sanitize( $value ) {
if ( is_callable( $this->sanitize_callback ) ) {
$value = call_user_func( $this->sanitize_callback, $value, $this );
}
return $value;
}
?>
这个方法很简单,就是判断 $this->sanitize_callback
是否是一个可调用的函数,如果是,就调用它来清理和验证 $value
。
- 保存到数据库
如果清理和验证通过,Customizer 会调用 WP_Customize_Setting::update()
方法把新的值保存到数据库。
<?php
/**
* Update the setting's value.
*
* @since 4.2.0
*
* @param mixed $value The value to update.
* @return bool Whether the value was updated.
*/
public function update( $value ) {
$value = $this->sanitize( $value );
if ( 'theme_mod' === $this->type ) {
$success = set_theme_mod( $this->id, $value );
} elseif ( 'option' === $this->type ) {
$success = update_option( $this->id, $value );
} else {
$success = false;
}
if ( $success ) {
$this->value = $value;
$this->dirty = true; // Mark the setting as dirty.
$this->manager->saved_changes = true; // Mark that there are changes to save.
$this->manager->trigger( 'customize_save_' . $this->id, $this );
/**
* Fires after a customize setting has been updated.
*
* @since 4.2.0
*
* @param WP_Customize_Setting $this WP_Customize_Setting instance.
*/
do_action( 'customize_update_' . $this->id, $this );
}
return $success;
}
?>
这个方法做了几件事:
- 首先,调用
WP_Customize_Setting::sanitize()
对$value
进行清理和验证。 - 然后,根据
$this->type
的值,把新的值保存到数据库:- 如果
$this->type
是theme_mod
,就调用set_theme_mod( $this->id, $value )
把值保存到wp_options
表中,键名为theme_mods_{主题名}
。 - 如果
$this->type
是option
,就调用update_option( $this->id, $value )
把值保存到wp_options
表中,键名为$this->id
。
- 如果
- 如果保存成功,就更新
$this->value
的值,并触发customize_save_{$this->id}
和customize_update_{$this->id}
两个 action。 - 将
$this->dirty
设置为true
,表示此设置项已被修改。 - 将
$this->manager->saved_changes
设置为true
,表示有更改需要保存。
- 实时预览
如果 $this->transport
的值是 postMessage
,Customizer 会通过 JavaScript 把新的值发送到主题预览页面,实现实时预览。这个过程涉及到 WP_Customize_Control
和 JavaScript API,咱们这里就不深入讲解了。
四、双向绑定的奥秘
现在咱们来总结一下 WP_Customize_Setting
是如何实现双向绑定的:
- 读取: 当 Customizer 加载时,
WP_Customize_Setting
从数据库读取设置项的值,并把它存储在$this->value
属性中。 - 修改: 当用户在 Customizer 里修改设置项的值时,Customizer 会把新的值发送到服务器,
WP_Customize_Setting::sanitize()
方法会被调用,对新的值进行清理和验证。 - 保存: 如果清理和验证通过,
WP_Customize_Setting::update()
方法会把新的值保存到数据库,并更新$this->value
属性。 - 预览: 如果
$this->transport
的值是postMessage
,Customizer 会通过 JavaScript 把新的值发送到主题预览页面,实现实时预览。
通过这些步骤,WP_Customize_Setting
把主题选项和数据库紧紧地绑在一起,实现了双向绑定。无论用户在 Customizer 里修改设置项的值,还是直接修改数据库里的值,都能保证两者的同步。
五、WP_Customize_Setting
的应用场景
WP_Customize_Setting
可以应用到各种各样的场景中,比如:
- 主题颜色: 让用户自定义主题的颜色,包括背景色、文字颜色、链接颜色等等。
- Logo: 让用户上传自己的 Logo。
- 字体: 让用户选择自己喜欢的字体。
- 布局: 让用户选择不同的布局,比如单栏布局、双栏布局、三栏布局等等。
- 社交媒体链接: 让用户添加自己的社交媒体链接。
- 自定义CSS: 让用户添加自己的 CSS 代码。
只要你想让用户自定义的东西,都可以用 WP_Customize_Setting
来实现。
六、自定义 WP_Customize_Setting
有时候,WordPress 提供的 WP_Customize_Setting
可能不能满足你的需求,你需要自定义一个 WP_Customize_Setting
类。
自定义 WP_Customize_Setting
类很简单,只需要继承 WP_Customize_Setting
类,并重写你想要修改的方法即可。
比如,你可以自定义一个 WP_Customize_Range_Setting
类,让用户可以输入一个范围内的数字。
<?php
class WP_Customize_Range_Setting extends WP_Customize_Setting {
public $type = 'range';
public function __construct( $manager, $id, $args = array() ) {
parent::__construct( $manager, $id, $args );
// Set default value if not set.
if ( ! isset( $this->default ) ) {
$this->default = 0;
}
// Set transport to refresh if not set.
if ( ! isset( $this->transport ) ) {
$this->transport = 'refresh';
}
}
public function sanitize( $value ) {
$value = intval( $value ); // Convert to integer.
$value = max( $this->min, min( $this->max, $value ) ); // Limit to range.
return $value;
}
}
?>
然后,你就可以在 Customizer 里使用这个自定义的 WP_Customize_Setting
类了。
七、总结
今天咱们深入剖析了 WP_Customize_Setting
类的源码,讲解了它是如何与数据库中的主题选项进行双向绑定的。希望通过今天的讲座,你对 WP_Customize_Setting
类有了更深入的理解,也能自己灵活运用它,打造出更加强大的 WordPress 主题定制功能。
记住,WP_Customize_Setting
就像一根神奇的线,把主题选项和数据库紧紧地绑在一起,实现了双向绑定。掌握了它,你就掌握了 WordPress 主题定制的钥匙。
好了,今天的讲座就到这里,感谢大家的观看!如果有什么问题,欢迎在评论区留言。下次再见!