阐述 `get_theme_mod()` 和 `set_theme_mod()` 函数的源码,它们如何与主题自定义选项进行交互?

各位观众老爷们,大家好!今天老衲要给大家讲讲WordPress主题自定义选项背后的两大护法:get_theme_mod()set_theme_mod()。 别害怕,虽然名字听起来像武林秘籍,但其实它们简单得很,理解了它们,你就掌握了控制主题外观的钥匙。

一、get_theme_mod():主题设置“读心术”

首先,我们来看看get_theme_mod() 这个函数,它可以从数据库中读取主题的自定义选项值,就像一个读心术大师,能知道主题作者或用户在后台设置了什么。

1.1 函数原型

先上干货,看看get_theme_mod() 的庐山真面目:

get_theme_mod( string $name, mixed $default = false ) : mixed
  • $name (string): 这是你要读取的主题自定义选项的名称,就像给读心术大师提供目标人物的名字。
  • $default (mixed): 这是一个可选参数,表示如果该选项没有设置过,返回的默认值。 如果没设置默认值,那没找到就返回 false

1.2 源码剖析 (简化版)

为了让大家看得更明白,我们简化一下 get_theme_mod() 的源码(实际源码更复杂,包含各种过滤和安全检查):

function my_simplified_get_theme_mod( $name, $default = false ) {
  global $wp_customize; // 获取全局的自定义选项对象

  // 1. 检查是否在自定义预览中
  if ( isset( $wp_customize ) && $wp_customize->is_preview() ) {
    // 如果在自定义预览中,直接从自定义管理器中获取
    $setting = $wp_customize->get_setting( $name );
    if ( $setting ) {
      return $setting->value(); // 返回当前预览的值
    }
  }

  // 2. 从数据库中获取主题选项
  $theme = get_stylesheet(); // 获取当前主题的stylesheet (主题名称)
  $mods  = get_option( "theme_mods_$theme" ); // 从数据库中获取所有主题选项

  // 3. 检查选项是否存在
  if ( isset( $mods[ $name ] ) ) {
    return $mods[ $name ]; // 如果存在,返回选项值
  } else {
    return $default; // 如果不存在,返回默认值
  }
}

流程解释:

  1. 自定义预览优先: 首先检查是否在主题自定义预览界面。如果在,它会直接从 WordPress 的自定义管理器($wp_customize) 获取值。 这是因为在预览界面,选项的值可能还没保存到数据库,而是保存在自定义管理器里。
  2. 从数据库获取: 如果不在预览界面,它会从数据库中读取名为 theme_mods_$theme 的选项。 $theme 是当前主题的目录名。 这个选项存储了该主题的所有自定义选项。
  3. 查找选项: 在获取到的所有选项里,根据 $name 查找对应的选项值。
  4. 返回结果: 如果找到了,就返回该选项的值;否则,返回你提供的默认值,或者 false

1.3 代码示例

假设你的主题有一个自定义选项叫做 header_background_color,允许用户设置页眉的背景颜色。

// 获取 header_background_color 选项的值,如果没设置,默认返回 #FFFFFF (白色)
$header_bg_color = get_theme_mod( 'header_background_color', '#FFFFFF' );

// 在页眉区域应用背景颜色
echo '<header style="background-color: ' . esc_attr( $header_bg_color ) . ';">';
// ... 页眉内容 ...
echo '</header>';

注意事项:

  • esc_attr() 函数: 在输出任何从数据库获取的值(尤其是用于 HTML 属性的值)时,一定要使用 esc_attr() 函数进行转义,防止 XSS 攻击。 这是一种安全措施,不要偷懒!
  • 性能优化: 如果需要在多个地方使用同一个主题选项,最好将其值缓存到一个变量中,避免多次调用 get_theme_mod(),提高性能。

二、set_theme_mod():主题设置“遥控器”

现在,我们来看看 set_theme_mod() 函数,它负责将主题的自定义选项值保存到数据库中,就像一个遥控器,可以改变主题的各种设置。

2.1 函数原型

set_theme_mod( string $name, mixed $value ) : void
  • $name (string): 要保存的主题自定义选项的名称。
  • $value (mixed): 要保存的选项值。 可以保存任何数据类型,比如字符串、数字、数组等等。

2.2 源码剖析 (简化版)

同样,我们简化一下set_theme_mod() 的源码:

function my_simplified_set_theme_mod( $name, $value ) {
  $theme = get_stylesheet(); // 获取当前主题的stylesheet (主题名称)
  $mods  = get_option( "theme_mods_$theme" ); // 获取当前所有主题选项

  if ( $value ) {
    // 如果值不为空,则更新或添加选项
    $mods[ $name ] = $value;
  } else {
    // 如果值为空,则删除选项
    unset( $mods[ $name ] );
  }

  update_option( "theme_mods_$theme", $mods ); // 更新数据库中的主题选项
}

流程解释:

  1. 获取现有选项: 首先,它会从数据库中读取当前主题的所有自定义选项,存储在 $mods 数组中。
  2. 更新或删除选项:
    • 如果 $value 不为空,它会将 $name 对应的选项值更新为 $value,或者如果该选项不存在,则添加该选项。
    • 如果 $value 为空,它会从 $mods 数组中删除 $name 对应的选项。 这相当于重置该选项为默认值(如果代码中使用了默认值的话)。
  3. 保存到数据库: 最后,它会将更新后的 $mods 数组保存回数据库中,使用 update_option() 函数。

2.3 代码示例

假设你在主题的自定义设置面板中提供了一个选项,允许用户上传自定义的 logo 图片。

// 在主题自定义设置面板中,用户上传了 logo 图片,图片的 URL 存储在 $logo_url 变量中
$logo_url = $_POST['logo_url']; // 假设通过 POST 请求获取用户上传的 logo URL

// 保存 logo URL 到主题选项中
set_theme_mod( 'custom_logo_url', $logo_url );

// 在主题模板中显示 logo
$logo_url = get_theme_mod( 'custom_logo_url' );
if ( $logo_url ) {
  echo '<img src="' . esc_url( $logo_url ) . '" alt="Logo">';
} else {
  // 显示默认 logo
  echo '<img src="' . get_template_directory_uri() . '/images/default-logo.png" alt="Default Logo">';
}

注意事项:

  • 安全性: 在保存任何用户输入的数据之前,一定要进行验证和清理,防止恶意代码注入。 尤其是通过 POST 或 GET 请求获取的数据!
  • 用户体验: set_theme_mod() 通常在主题自定义设置面板中使用。 确保在保存选项后,及时刷新预览,让用户看到修改后的效果。

三、get_theme_mod()set_theme_mod() 的交互

get_theme_mod()set_theme_mod() 就像一对好基友,一个负责读取,一个负责写入,它们共同协作,实现了 WordPress 主题自定义选项的功能。

交互流程:

  1. 用户操作: 用户在 WordPress 后台的 "外观" -> "自定义" 界面中,修改主题的各种选项,例如颜色、布局、logo 等。
  2. set_theme_mod() 发力: 当用户点击 "保存并发布" 按钮时,WordPress 会调用 set_theme_mod() 函数,将用户修改后的选项值保存到数据库中。
  3. get_theme_mod() 读取: 在主题的模板文件中,使用 get_theme_mod() 函数读取这些已保存的选项值。
  4. 动态渲染: 根据读取到的选项值,动态地渲染主题的各个部分,例如修改颜色、显示 logo、调整布局等。

用表格总结一下:

函数 功能 参数 返回值 使用场景
get_theme_mod() 从数据库读取主题自定义选项值 $name (选项名称), $default (默认值,可选) 选项值 (如果存在), 默认值 (如果选项不存在且提供了默认值), false (如果选项不存在且没有提供默认值) 在主题模板文件中,根据主题选项的值动态渲染页面内容
set_theme_mod() 将主题自定义选项值保存到数据库中 $name (选项名称), $value (选项值) void (无返回值) 在主题自定义设置面板中,当用户保存选项时,将选项值保存到数据库中

四、实际案例:创建一个简单的颜色选择器

为了更好地理解这两个函数,我们来创建一个简单的颜色选择器,允许用户自定义主题的背景颜色。

1. 在 functions.php 文件中添加自定义设置:

function my_theme_customize_register( $wp_customize ) {

  // 添加一个设置
  $wp_customize->add_setting( 'background_color', array(
    'default'   => '#f0f0f0', // 默认颜色
    'transport' => 'refresh', // 刷新整个页面以更新预览
  ) );

  // 添加一个控制
  $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'background_color', array(
    'label'   => __( 'Background Color', 'mytheme' ), // 控制的标签
    'section' => 'colors', // 将控制添加到 "colors" 部分
    'settings' => 'background_color', // 将控制与 "background_color" 设置关联
  ) ) );
}
add_action( 'customize_register', 'my_theme_customize_register' );

代码解释:

  • my_theme_customize_register() 函数: 这是一个自定义函数,用于向 WordPress 的自定义管理器注册自定义设置和控制。
  • $wp_customize->add_setting(): 这个函数用于添加一个设置。
    • 'background_color': 设置的名称,也就是我们以后在 get_theme_mod()set_theme_mod() 中使用的 $name
    • 'default' => '#f0f0f0': 设置的默认值。
    • 'transport' => 'refresh': 指定更新预览的方式。 'refresh' 表示刷新整个页面, 'postMessage' 表示使用 JavaScript 异步更新预览。
  • $wp_customize->add_control(): 这个函数用于添加一个控制,也就是用户在自定义界面中看到的颜色选择器。
    • new WP_Customize_Color_Control(): 创建一个颜色控制。
    • 'label': 控制的标签,显示在自定义界面中。
    • 'section' => 'colors': 将控制添加到 "colors" 部分,也就是 WordPress 默认的颜色设置部分。
    • 'settings' => 'background_color': 将控制与我们之前创建的 "background_color" 设置关联起来。

2. 在主题模板文件中使用 get_theme_mod()

<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
  <meta charset="<?php bloginfo( 'charset' ); ?>">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title><?php wp_title( '|', true, 'right' ); ?></title>
  <?php wp_head(); ?>
  <style>
    body {
      background-color: <?php echo esc_attr( get_theme_mod( 'background_color', '#f0f0f0' ) ); ?>;
    }
  </style>
</head>
<body <?php body_class(); ?>>
  <div id="page">
    <header id="masthead" class="site-header" role="banner">
      </header>
    <div id="content" class="site-content">
      </div>
  </div>
  <?php wp_footer(); ?>
</body>
</html>

代码解释:

  • <style> 标签中,我们使用 get_theme_mod( 'background_color', '#f0f0f0' ) 获取用户设置的背景颜色。 如果用户没有设置,则使用默认值 #f0f0f0
  • esc_attr() 函数用于转义输出的颜色值,确保安全性。

现在,当你进入 WordPress 后台的 "外观" -> "自定义" 界面时,你会在 "颜色" 部分看到一个背景颜色选择器。 当你选择一个颜色并保存时,主题的背景颜色就会随之改变。

五、总结

get_theme_mod()set_theme_mod() 是 WordPress 主题自定义选项的核心函数。 理解了它们的原理和用法,你就可以轻松地创建各种各样的主题自定义设置,让你的主题更加灵活和个性化。记住,安全第一,永远要对用户输入进行验证和清理!

好了,今天的讲座就到这里。 希望老衲的讲解能帮助大家更好地理解 WordPress 主题自定义选项。 下次再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注