块级主题样式

欢迎来到关于 WordPress 主题样式的课程。

通过本课程,你将能够:

  • 探索样式层级结构,
  • 使用站点编辑器修改主题样式并导出更改,
  • 理解 WordPress 如何利用 JSON 语法在浏览器中生成 CSS,以及
  • 通过 settings 属性配置预设,并在 theme.json 的 styles 属性中应用它们。

WordPress 样式层级结构

在最底层,我们有根元素,例如正文文本。下一层是单个元素,例如标题,比如 H1 标签。最后在顶层,我们有区块,例如按钮区块。因此,任何应用于区块级别的样式都将优先于主题中的所有其他样式。

修改主题样式

让我们使用站点编辑器修改主题样式并导出更改。Create Block Theme 插件对于任何主题开发者来说都是一个宝贵的工具。请务必查看初学者学习路径中为开发者准备的入门课程。

我发现使用 Create Block Theme 插件的最佳功能之一是能够将更改直接保存到主题文件中。如果我现在在全局样式中进行更改,例如向自定义调色板添加一种新颜色,我可以搜索一种颜色,或者输入十六进制代码,然后为颜色命名。我将这种颜色命名为紫色,然后点击完成。如果我点击保存,此更改将保存到数据库中。我们会看到 Create Block Theme 插件侧边栏和保存更改选项。这会将更改从数据库中移除,并将其推送到主题文件中。

现在让我们打开 theme.json 文件,以便搜索新的紫色颜色。你可以在 settings 中看到它,作为可供最终用户使用的新颜色。

WordPress 如何利用 JSON 语法在浏览器中生成 CSS

我们将查看默认的 Twenty Twenty-Four 主题。这是一个区块主题,如果我们检查代码并查看,例如 H1 标签,我们在左侧检查它,在右侧会看到生成的 CSS。

WordPress 获取 settings、color、contrast,然后将其应用于这里的 H1 标题。我们现在来看看这在 theme.json 中是如何完成的。在这里你可以看到在 settings 中我们如何拥有 palette 和 contrast 颜色。然后如果我们向下滚动到 styles 属性,我们会看到 contrast 颜色如何应用于文本。

如何在 theme.json 中编写预设

现在让我们通过另一个示例使用 theme.json 配置预设。这里我们有一个入门主题,我们想通过添加调色板来自定义它。进入 settings,将 WordPress 的默认调色板设置为 false,然后添加属性 palette 并开始添加我们的颜色。请注意,这里我们使用通用的命名约定,而不是为颜色命名。

例如,这是一种深绿色,我们没有使用 green 作为名称和别名,而是使用 contrast。这使得将来进行颜色更改更加容易,然后我们在底部的 styles 下看到它被应用。

现在,让我们仔细看看 Twenty Twenty-Four 主题中的一个示例。我们有包含 color、name 和 slug 的 settings 属性。然后为了应用样式,我们将使用这里的格式,其中 feature 是 color,而 slug 例如是 accent-3。

WordPress 通过创建类 has-slug-feature 来生成 CSS。我们可以通过将颜色应用于这里的文本来查看实际效果,然后如果我们检查该段落,我们会看到 WordPress 如何获取预设并创建类 has-accent-3-color。

下一步

像往常一样,你可以参考 WordPress.org 上提供的主题手册,也可以查看样式参考指南,以找到所有可以添加到 theme.json 文件中的可用样式属性。

全局主题设置

欢迎来到关于 WordPress 主题配置文件 theme.json 以及其中一些可用的主题设置选项的课程。

通过本课程,你将:

  • 了解主题设置的用途,
  • 探索终端用户可用的设置,以及
  • 使用 theme.json 来控制可用的设置。

主题设置的用途是什么?

首先,查看一下 WordPress 核心自带的 theme.json 文件。所有默认设置都在这里配置。

终端用户可以使用哪些设置?

要回答这个问题,我们需要注意到存在一个加载层级。我们从 WordPress 核心开始。然后向上到主题。接下来,如果有子主题且处于激活状态,则轮到子主题。最后,是用户配置。

用户在区块编辑器或站点编辑器中进行的任何更改并保存后,这些更改将优先于层级中的所有其他设置。

使用 theme.json 控制可用设置

我们将首先在站点编辑器中打开一个模板,然后进入并针对站点和区块进行一些更改。如果你打开样式,例如在颜色下,可以看到文本选项,我们可以为文本应用不同的颜色,这是全局生效的。

如果我们想处理某个区块,先选中该区块,然后进入设置,再进入设置中的样式选项卡。你会看到颜色选项,选择文本,就可以更改文本的颜色,但请注意,我们无法更改链接的颜色。要实现这一点,我们需要在 theme.json 中进行配置。

我们有一个属性 Appearance Tools,默认设置为 False。本质上,Appearance Tools 是一个包罗万象的属性。WordPress 默认将其下的所有属性都设置为 False。如果我们正在开发主题,并且想要启用所有这些属性,只需将 Appearance Tools 设置为 True 即可。但在我们的示例中,我们只处理更改链接颜色的功能。

在 Appearance Tools 下,我们将添加属性 Color,然后输入 Link,并将 False 改为 True,然后保存。现在,如果我们返回 WordPress 并刷新页面,这次我们应该能够更改链接的颜色了。

在全局的颜色设置下,我们现在可以看到链接选项;如果我们选中一个区块并进入区块设置中的颜色选项,现在也有了链接选项。

后续步骤

至此,我们对 WordPress 主题设置的简要概述就结束了。你可以随时参考 WordPress.org 上的主题手册,并查看设置参考,以便更好地了解可以在 theme.json 文件中配置哪些设置。

实用的调试插件

虽然 WordPress 内置的调试选项应该能满足大部分需求,但也有一些插件可以帮助你调试代码。

你可以在 WordPress 插件目录中搜索“debug”或“debugging”来找到这些插件。

其中最受欢迎的两个选项是 Debug Bar 和 Query Monitor。

Debug Bar

Debug Bar 是一个由 WordPress 开发者社区构建和维护的插件。它在管理栏中添加了一个调试菜单,显示查询、缓存和其他有用的调试信息。

当启用 WP_DEBUG 常量时,它还会跟踪 PHP 警告和通知,使其更容易被发现;当启用 SAVEQUERIES 时,MySQL 查询会被跟踪并显示。

Query Monitor

另一个选项是 Query Monitor,它也在管理栏中添加了一个调试菜单,并显示当前页面请求的相关信息。

Query Monitor 支持调试许多内容,包括数据库查询、PHP 错误、钩子和动作、区块编辑器区块、已排队的脚本和样式表、HTTP API 调用等。

总结

这两个插件都是调试 WordPress 代码的绝佳选择,可以帮助你更轻松地追踪问题。

检查JavaScript代码的状态

在 JavaScript 开发过程中,在代码的不同位置进行调试以了解运行情况会非常有帮助。

我们来看看几种检查 JavaScript 代码状态的方法。

服务端 vs 客户端

调试 PHP 和 JavaScript 的主要区别之一在于,PHP 是一种服务端语言,因此你可以将消息记录到服务器上的文件中。

而 JavaScript 是一种客户端语言,因此你不能像 PHP 那样轻松地将消息记录到文件中。

幸运的是,我们可以使用浏览器的开发者工具(特别是控制台选项卡)来检查 JavaScript 代码的状态。

打开浏览器的开发者工具

大多数现代浏览器都内置了开发者工具,允许你检查和调试网页元素。

根据你使用的浏览器和操作系统,通常可以通过按下特定键来打开开发者工具,例如 F12Ctrl+Shift+ICmd+Option+I

如果你不确定如何在浏览器中打开开发者工具,可以在 MDN Web Docs 网站上找到便捷的说明,路径为:指南 > 常见问题 > 工具与设置 > 什么是浏览器开发者工具?。

[注意:引导用户完成导航路径,找到该页面]

打开开发者工具后,切换到“控制台”选项卡,页面上的所有错误都会记录在这里。

同时,你也可以在这里从 JavaScript 代码中记录消息,以帮助调试。

console 对象

console 对象允许你将消息记录到浏览器的控制台。它提供了多种方法,用于记录不同类型的消息。

以下是一些最常用的方法:

console.log() 方法是最常用的,因为它几乎可以记录任何内容到控制台。你可以向它传递各种数据类型,例如字符串、数字、数组或对象。

下面是一个将简单字符串变量记录到控制台的示例。

(function() {
    let hello = 'Hello, World!';
    console.log(hello)
})(); 

如果你打开开发者工具并选择“控制台”选项卡,变量的内容就会被记录到控制台中。

控制台输出还包含一个指向源文件中代码位置的链接,这有助于追踪消息是从哪里记录的。

你还可以记录更复杂的数据类型,例如数组或对象。

(function() {
    let fruits = [ 'apple', 'banana', 'orange' ];
    console.log( fruits );

    let person = {
        firstName: "Jane",
        lastName: "Smith",
        age: 30,
        eyeColor: "brown"
    }
    console.log( person );
})();

在控制台中查看时,你会看到数组和对象按预期被记录。你还可以展开数组或对象以查看其属性,以及该数据类型可用的任何 JavaScript 方法。

还有许多其他方法可用于将消息记录到控制台,例如 console.error()console.warn()console.info()

其中一个最被低估的方法是 console.table(),它可以将数组或对象以表格形式记录,使其更易于阅读。

(function() {
    let people = [
        { name: 'Jane', age: 30 },
        { name: 'John', age: 40 },
        { name: 'Alice', age: 25 }
    ];
    console.table( people );
})();

当你有一个对象数组,并且希望以更易读的格式查看数据时,这个方法尤其有用。

延伸阅读

要了解更多关于浏览器 console 对象及其方法的信息,请务必访问 MDN Web Docs 页面。该页面包含了所有 console 方法的完整列表以及有用的示例。

检查PHP代码状态

在调试 PHP 代码时,检查代码在特定时间点的状态会很有帮助。这可以帮助你理解代码中正在发生的事情,并识别可能导致问题的任何错误。

让我们看看一些使用内置 PHP 函数检查 PHP 代码状态的方法。

使用 error_log() 记录消息

正如在关于内置 WordPress 调试选项的课程中所讨论的,你可以使用 error_log() 函数将消息记录到 WordPress 的 debug.log 文件中。

这对于调试目的非常有用,因为它允许你查看代码中正在发生的事情,而无需在屏幕上显示。

error_log() 函数并非 WordPress 特有,它是一个 PHP 函数,你可以在任何 PHP 代码中使用它,将消息记录到服务器上配置的 PHP 错误日志文件中。

但是,一旦你在 wp-config.php 文件中启用了 WordPress 特定的调试选项,传递给 error_log() 的任何内容都将被记录到 WordPressdebug.log 文件中。

<?php
error_log( $some_variable );
?>

这会将 $some_variable 的值记录到 debug.log 文件中,这样你就可以看到它在代码中该点的内容。

使用 error_log() 的好处是,它允许你将消息记录到文件,而无需在屏幕上显示。如果你在屏幕上显示它们,尤其是在生产环境中,你可能会面临向用户暴露敏感信息的风险。

有时,在日志文件中查看输出也比在屏幕上搜索一长串输出更快。

使用 print_r()

另一个用于检查 PHP 代码状态的有用函数是 print_r()。此函数以人类可读的格式输出变量、数组或对象的值,以便你可以查看其内容。

看看这个 PHP 代码示例。

<?php
$some_array = array(
    'name' => 'John',
    'age'  => 30,
    'city' => 'New York'
);
print_r( $some_array );
?>

这段代码将在屏幕上输出以下内容:

Array
(
    [name] => John
    [age] => 30
    [city] => New York
)

开发者通常会将 print_r() 包裹在 <pre> 标签中,以使输出更易于阅读。

<pre>
    <?php print_r( $some_array ); ?>
</pre>

这将在屏幕上输出以下内容:

Array
(
    [name] => John
    [age] => 30
    [city] => New York
)

请注意,默认情况下 print_r() 会输出变量的值,但不会返回它。如果你想将 print_r() 的输出与 error_log() 一起使用,需要将第二个参数设置为 true

<?php
error_log( print_r( $some_array, true ) );
?>

这会将 print_r 调用的输出记录到 debug.log 文件中,这样你就可以看到 $some_array 在代码中该点的内容。

使用 var_dump()

var_dump() 函数是另一个用于检查 PHP 代码状态的有用函数。此函数以人类可读的格式输出变量、数组或对象的值,同时提供关于变量类型和长度的额外信息。

看看这个 PHP 代码示例。

<?php
$some_array = array(
    'name' => 'John',
    'age'  => 30,
    'city' => 'New York'
);
var_dump( $some_array );
?>

这段代码将在屏幕上输出以下内容:

array(3) {
  ["name"]=>
  string(4) "John"
  ["age"]=>
  int(30)
  ["city"]=>
  string(8) "New York"
}

请注意,var_dump() 会输出变量的值,以及关于变量类型和长度的额外信息。这对于调试目的非常有用,因为它提供了比 print_r() 更详细的变量信息。

print_r() 不同,var_dump() 没有将输出返回给变量的选项,因此你不能直接将其与 error_log() 一起使用。

但是,你可以使用一种称为输出缓冲的技术来捕获 var_dump() 的输出,然后将其记录到 debug.log 文件中。

<?php
ob_start();
var_dump( $some_array );
$output = ob_get_clean();
error_log( $output );
?>

开发者通常会将这种代码用于一个特殊的日志记录函数,以便能够同时使用 var_dumperror_log

<?php
if ( ! function_exists( 'var_log' ) ) {
    function var_log( $log ) {
        ob_start();
        var_dump( $log );
        $output = ob_get_clean();
        error_log( $output );
    }
}
?>

进一步阅读

有关本课程中提到的函数的更多信息,请查看 PHP 文档中的以下页面:

PHP var_dump() 函数

PHP error_log() 函数

PHP print_r() 函数

WordPress 内置调试选项

随着你对 WordPress 开发越来越熟练,你会发现有时事情并不像预期那样工作,你需要找出原因。

在本课中,你将了解 WordPress 内置的调试选项。

首先,你将学习调试代码的含义。然后,你将了解默认 WordPress 安装中可用的一些内置调试选项,以及如何启用和使用它们。

什么是调试?

调试是查找并修复代码中错误的过程。

由于 WordPress 的两种主要编程语言是 PHP 和 JavaScript,你需要能够调试这两种语言。

对于在浏览器中执行的 JavaScript 代码,使用 console.log() 向浏览器控制台写入消息以进行测试和调试是相当直接的。

另一方面,PHP 在服务器上执行,因此你需要一些方法来找出问题发生时的情况。

有一些第三方工具可用于高级调试,例如 Xdebug 或 Ray。

然而,就本课而言,你将学习 WordPress 特有的选项,并且不需要额外的软件。

调试 PHP

在 WordPress 中,在任何 WordPress 请求生命周期内,都会运行 wp_debug_mode() 函数来设置调试环境。此函数位于 wp-includes/load.php 文件中。

如果你查看这段代码,你会发现如果 WP_DEBUG 常量设置为 true,那么它会将 PHP 错误报告级别设置为 E_ALL,这意味着开启所有错误报告。

此外,如果 WP_DEBUG_DISPLAY 设置为 true,那么它会将 PHP 的 display_errors 设置设为 1,这意味着在屏幕上显示这些错误。

最后,如果 WP_DEBUG_LOG 设置为 true,那么它会将 PHP 的 error_log 设置设为 wp-content/debug.log 文件。也可以配置自定义的 debug.log 文件位置,而不是默认位置。

如果启用了此日志文件,它会将 PHP 的 log_errors 设置设为 1,并将 error_log 设置设为日志文件的路径,这意味着所有错误都将记录到此文件中。

利用这些知识,你可以配置 wp-config.php 文件来启用 WordPress 调试。

启用调试

要启用调试,请打开 wp-config.php 文件并向下滚动到设置 WP_DEBUG 常量的位置。

你可以将该部分更新为如下所示:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_DISPLAY', false );
define( 'WP_DEBUG_LOG', true );

此配置将:

  1. 启用调试
  2. 禁止在屏幕上显示错误
  3. 启用将错误记录到 wp-content/debug.log 文件

根据你的个人偏好,你可以启用屏幕上显示错误,但这可能导致错误被忽略或覆盖屏幕上的其他重要内容,这并不理想。

此外,如果你曾经在生产站点上调试问题,你不希望将错误显示在屏幕上,因为这可能导致敏感信息向用户显示。

为了实际查看效果,让我们看一个例子。

假设你开发了一个包含以下代码的插件:

<?php
/**
 * Plugin Name: WP Learn Debugging
 * Plugin Description: A plugin to learn about debugging in WordPress.
 * Plugin URI: https://learn.wordpress.org
 * Version: 1.0.0
 */

/**
 * Set up the required form submissions table
 */
register_activation_hook( __FILE__, 'wp_learn_setup_table' );
function wp_learn_setup_table() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'form_submissions';

    $sql = "CREATE TABLE $table_name (
      id mediumint(9) NOT NULL AUTO_INCREMENT,
      name varchar (100) NOT NULL,
      email varchar (100) NOT NULL,
      PRIMARY KEY  (id)
    )";

    require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
    dbDelta( $sql );
}

/**
 * Register the REST API GET route
 */
add_action( 'init', 'wp_learn_register_routes' );
function wp_learn_register_routes() {
    register_rest_route(
        'wp-learn-form-submissions-api/v1',
        '/form-submissions/',
        array(
            'methods'             => 'GET',
            'callback'            => 'wp_learn_get_form_submissions',
            'permission_callback' => '__return_true'
        )
    );
}

/**
 * Fetch the form submissions for the REST API GET Route
 *
 * @return array|object|stdClass[]|null
 */
function wp_learn_get_form_submissions() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'form_submission';

    $results = $wpdb->get_results( "SELECT * FROM $table_name" );

    return $results;
}

这个插件在激活时会在数据库中创建一个表单提交表,然后注册一个 REST API GET 路由来从数据库中获取表单提交。

出于测试目的,你手动在 form_submissions 表中插入了几条记录。

但是,如果你访问 REST API GET 路由,你看不到任何表单提交,因此你需要开始查找代码中的错误。

只需启用调试,代码中的任何错误都会自动记录到 wp-content/debug.log 文件中。所以如果你查看一下,你会看到一些错误已被记录。

[02-Jun-2023 13:51:41 UTC] PHP Notice:  Function register_rest_route was called <strong>incorrectly</strong>. REST API routes must be registered on the <code>rest_api_init action. Please see Debugging in WordPress for more information. (This message was added in version 5.1.0.) in /home/ubuntu/wp-local-env/sites/learnpress/wp-includes/functions.php on line 5865

在这种情况下,报告了两个错误。首先是由 WordPress 触发的 PHP 通知,这是由于将 wp_learn_register_routes 函数挂载到了错误的操作上。其次是与用于获取表单提交的数据库查询相关的错误。

看起来它查询的是 form_submission 表,而不是 form_submissions 表。

一旦你修复了这些错误,并访问 REST API GET 路由,你就会看到表单提交被返回了。

使用 error_log 进行调试

除了将错误记录到 debug.log 文件之外,你还可以使用 PHP 的 error_log 函数将消息或变量记录到 debug.log 文件。

此函数接受一个字符串参数。

例如,如果你想将正在运行的 SQL 查询记录到 debug.log 文件中,可以使用以下代码:

error_log( $wpdb->last_query );

如果你刷新请求并查看 debug.log 文件,就会看到查询被记录到该文件中。

[02-Jun-2023 13:55:35 UTC] SELECT * FROM wp_form_submissions

使用 SAVEQUERIES 常量

除了记录最后一条查询,你还可以记录 WordPress 请求生命周期中运行的所有查询。

要实现这一点,你可以在 wp-config.php 文件中启用 SAVEQUERIES 常量。

define( 'SAVEQUERIES', true );

启用此常量后,你可以使用以下代码记录所有查询:

error_log( print_r( $wpdb->queries, true ) );

这段代码结合使用了 error_log() 函数和 PHP 的 print_r() 函数,将 $wpdb->queries 数组记录到 debug.log 文件中。

该数组包含了 WordPress 请求生命周期中运行的所有查询,并且仅在启用 SAVEQUERIES 常量时才可用。

进一步阅读

有关 WordPress 调试的更多信息,请查看 WordPress 开发者文档中高级管理区域的“WordPress 调试”部分。

构建支持多站点的插件和主题

在为 WordPress 多站点网络开发主题或插件时,需要考虑一些与为单站点 WordPress 安装开发略有不同的事项。

在本课中,你将了解一些需要考虑的差异,以及如何确保你的插件和主题支持多站点。

开发主题和子主题

通常,主题和子主题在多站点网络上的工作方式与在单站点上完全相同。一旦主题或子主题被网络激活,它就可以在网络上的任何单个站点上激活。

你可能想要编码到 functions.php 文件中的所有特定功能都将在当前主题的范围内工作。例如,如果你想要在主题的页脚中显示站点名称,你可以使用标准的 get_bloginfo 函数来检索站点名称。

if ( ! function_exists( 'tt3c_get_site_name' ) ) {
    function tt3c_get_site_name() {
        return get_bloginfo( 'name' );
    }
}

然而,假设你想要在主题的页脚中包含主站点的名称,无论当前正在查看哪个站点。你可以使用 switch_to_blog 函数切换到主站点,检索站点名称,然后恢复当前站点。

if ( ! function_exists( 'tt3c_get_site_name' ) ) {
    function tt3c_get_site_name() {
        $site_name = get_bloginfo( 'name' );
        switch_to_blog( 1 );
        $main_site_name = get_bloginfo( 'name' );
        restore_current_blog();

        return $site_name . ' (part of the ' . $main_site_name . ' network)';
    }
}

更进一步,也许你想要仅将主站点排除在此自定义功能之外。你可以使用 is_main_site 函数来检查当前站点是否为主站点,如果是,则直接返回站点名称。

if ( ! function_exists( 'tt3c_get_site_name' ) ) {
    function tt3c_get_site_name() {
        if ( is_main_site() ) {
            return get_bloginfo( 'name' );
        }

        $current_site = get_bloginfo( 'name' );
        switch_to_blog( 1 );
        $main_site_name = get_bloginfo( 'name' );
        restore_current_blog();
        return $current_site . ' (part of the ' . $main_site_name . ' network)';
    }
}

所有这些都可以通过单个子主题中的一个 functions.php 文件实现。

开发插件

如前所述,大多数插件功能在单站点和多站点上的工作方式相同。像 register_post_typeget_posts 这样的函数将以相同的方式运行,只是在特定站点的范围内。

然而,在为多站点开发插件时,需要考虑两件事。

插件通常有一个设置页面,通常可以从管理仪表板访问。这对于单站点插件来说没问题,但在多站点网络上,你需要考虑设置页面应该位于何处。它应该位于网络管理仪表板上,还是位于单个站点仪表板上?

如果你需要在网络管理仪表板上有一个设置页面,你可以使用 network_admin_menu 钩子向网络管理仪表板添加一个菜单项。如果你需要在单个站点仪表板上有一个设置页面,你可以使用 admin_menu 钩子向单个站点仪表板添加一个菜单项。

插件可能必须添加自定义表来存储自定义数据。如果你使用像 $wpdb->prefix 这样的变量来为你的表名添加前缀,你最终会得到一个以站点 ID 为前缀的表名。因此,如果你需要为每个站点提供此功能的自定义表,你需要提前规划。

让我们看一个例子。

这里我们有来自《安全开发插件入门》教程的示例插件。它有一个在插件激活时创建的 form_submissions 表,用于存储表单提交数据。如果你查看代码,你会看到表名以全局 $wpdb 对象的前缀属性为前缀。

在单站点安装中,这意味着它将使用 wp-config.php 文件中定义的前缀创建一个表,在此示例中为 wp_form_submissions

然而,在多站点网络上,根据插件的安装方式,它将创建不同的表。

如果它在网络上的单个站点上激活,表前缀将包含站点 ID。

因此,对于站点 2,表名将是 wp_2_form_submissions

然而,如果插件是网络激活的,激活过程将在主站点的范围内运行,并且它会创建与在单站点安装上激活时相同的表。

因此,对于网络激活,表名将是 wp_form_submissions

问题出现在你查看存储表单提交数据的代码时。

因为这也使用了全局 $wpdb 对象中的相同前缀属性,当此代码在主站点的范围内运行时,它将查找 wp_form_submissions 表来存储数据,但是,例如,当它在网络上的站点 2 的范围内运行时,它将查找 wp_2_form_submissions 来存储数据,而该表并不存在。

为了解决这个问题,我们需要更新插件激活例程,以考虑到这一点:

首先,将表创建代码移动到一个单独的函数中,然后从激活钩子调用此函数。

function wp_learn_create_table(){
    global $wpdb;
    $table_name = $wpdb->prefix . 'form_submissions';

    $sql = "CREATE TABLE $table_name (
      id mediumint(9) NOT NULL AUTO_INCREMENT,
      name varchar (100) NOT NULL,
      email varchar (100) NOT NULL,
      PRIMARY KEY  (id)
    )";

    require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
    dbDelta( $sql );
}

在 register_activation_hook 钩子的文档中,你会注意到回调函数接受一个 $network_wide 参数。这是一个布尔值,传递给激活钩子回调,指示插件是否正在网络范围内激活。

然后,你可以更新回调函数,首先检查站点是否为多站点网络,以及插件是否正在网络范围内激活。

如果是,则获取并遍历网络中的所有站点,依次切换到每个站点,并为每个站点创建数据表。

或者,如果插件未在网络范围内激活,则只需为当前站点创建数据表即可。

register_activation_hook( __FILE__, 'wp_learn_setup_table' );
function wp_learn_setup_table( $network_wide ) {
    if ( is_multisite() && $network_wide ) {
        $sites = get_sites();
        foreach ( $sites as $site ) {
            switch_to_blog( $site->blog_id );
            wp_learn_create_table();
            restore_current_blog();
        }
    } else {
        wp_learn_create_table();
    }
}

通过在网络上激活插件来测试此功能,您应该会看到所有正确的数据表都已创建。

但是,当创建新站点时会发生什么?在这种情况下,您需要使用像 wp_initialize_site 这样的钩子,为新站点创建数据表。

add_action( 'wp_initialize_site', 'wp_learn_setup_newsite_table' );
function wp_learn_setup_newsite_table( $site ) {
    switch_to_blog( $site->id );
    wp_learn_create_table();
    restore_current_blog();
}

通过创建一个新站点来测试这一点。它应该会在数据库中为该站点的表单提交创建新的数据表。

通过这种方式,您可以让插件在多站点网络上正常工作,无论是在网络上首次激活时(考虑到所有现有站点),还是为将来可能创建的新站点做好准备。

在哪里获取更多信息

除了关于创建网络以及创建网络前需考虑事项的文档外,针对多站点开发的开发者专用文档并不多。

不过,您可以通过浏览 WordPress 代码参考中的多站点包部分,查看所有与多站点相关的功能列表。