如何使用服务器端过滤器修改theme.json数据
近年来,theme.json 彻底改变了主题在 WordPress 中定义样式和设置的方式,为设计和编辑器功能带来了集中控制。并且 theme.json 在每次发布中都会获得新功能。
然而,仅通过主题的 theme.json 文件来配置数据可能具有挑战性,特别是当您需要动态功能或不受支持的高级编辑器自定义时。为了克服这些限制,WordPress 项目引入了强大的工具,如服务器端 theme.json 过滤器,提供了更大的灵活性。
在本指南中,您将:
- 探索 theme.json 数据层的复杂性
- 查看这些过滤器在实际使用中的示例
- 学习如何根据您的需求定制编辑器功能
从动态修改调色板到根据用户权限限制块控件,您将发现这些服务器端过滤器可以提供的众多选项。
理解 theme.json 数据层
当使用包含 theme.json 文件的 WordPress 主题时,有四个层(来源)的 theme.json 数据共同构成整体配置:
default– 包含 WordPress 自带的默认设置和样式的数据。block– 来自块的数据。theme– 来自主题的数据。custom– 来自全局样式的用户生成数据。每当您在站点编辑器中更改颜色、字体、块样式等时,这些都会存储为自定义(用户)数据。
所有这些层组合起来创建最终的 theme.json 数据对象,它控制着编辑器的工作方式以及您网站的最终外观。
WordPress 6.1 引入了四个服务器端过滤器,允许您修改这些不同的 theme.json 数据层:
wp_theme_json_data_default– 挂钩到 WordPress 提供的默认数据。wp_theme_json_data_blocks– 挂钩到块提供的数据。wp_theme_json_data_theme– 挂钩到主题提供的数据。wp_theme_json_data_user– 挂钩到用户(自定义)提供的数据。
这些层有自己的层次结构:custom(用户)层优先级最高。最低的是 default 层。
例如,您可以使用 wp_theme_json_data_default 过滤器定义默认的 theme.json 设置和样式,并仍然允许块、主题或用户覆盖此数据。另一方面,如果您想完全覆盖所有其他潜在数据源,可以使用 wp_theme_json_data_user 过滤器应用特定的 theme.json 设置。
现在,让我们深入一些实际示例。
开始使用 theme.json 过滤器
过滤 theme.json 数据的工作方式与任何其他 PHP 钩子非常相似。
您使用 add_filter() 函数注册一个回调。该回调函数将接收一个 WP_Theme_JSON_Data 类的实例,其中包含您正在过滤的层的数据。然后您可以修改该数据并返回更新后的 theme.json。
以下是一个简单的示例,它更改了当前主题的调色板并禁用了编辑器中的文本颜色控制:
<?php
/**
* 此函数通过将主题的调色板更新为仅黑白并禁用文本颜色来修改 theme JSON 数据。
*
* @param object $theme_json 原始的 theme JSON 数据。
* @return object 修改后的 theme JSON 数据。
*/
function example_filter_theme_json_theme( $theme_json ){
$new_data = array(
'version' => 2,
'settings' => array(
'color' => array(
'text' => false,
'palette' => array(
array(
'slug' => 'base',
'color' => 'white',
'name' => __( 'Base', 'theme-domain' ),
),
array(
'slug' => 'contrast',
'color' => 'black',
'name' => __( 'Contrast', 'theme-domain' ),
),
),
),
),
);
return $theme_json->update_with( $new_data );
}
add_filter( 'wp_theme_json_data_theme', 'example_filter_theme_json_theme' );
使用服务器端过滤器时,请记住几件重要的事情:
- 要使用您的修改更新原始 theme.json 数据,请使用
update_with( $new_data )方法,并确保您的自定义数据遵循有效的 theme.json 结构。 - 新数据还需要一个版本号。如果您的数据版本与过滤层的数据版本不同,WordPress 将在运行时正确迁移它——即使 theme.json 的结构在未来发生变化。
上面的代码设计为放置在您主题的 functions.php 文件中。
如果您想使用工具插件,则需要等待主题加载后才能运行过滤器。在这种情况下,您需要使用 after_setup_theme 钩子。使用 wp_theme_has_theme_json() 函数检查主题是否具有 theme.json 文件也是一个好习惯。
修改后的代码将如下所示:
// 为了使过滤器正常工作,必须在主题设置后运行。
function example_apply_theme_json_theme_filters() {
// 检查以确保主题具有 theme.json 文件。
if ( wp_theme_has_theme_json() ) {
add_filter( 'wp_theme_json_data_theme', 'example_filter_theme_json_theme' );
}
}
add_action( 'after_setup_theme', 'example_apply_theme_json_theme_filters' );
现在您已经了解了基础知识,让我们探索一些更有趣的示例。
基于登录状态修改 theme.json
假设您想根据用户是否登录来更改主题的颜色。这或许可以作为一种视觉提示,让客户知道他们正在享受忠诚度折扣。
服务器端过滤的好处之一是它可以与标准的 WordPress PHP 函数(如 is_user_logged_in())很好地配合使用。此函数允许您快速确定用户的登录状态。然后,您可以将此信息与 wp_theme_json_data_theme 过滤器结合使用来更改 theme.json 设置。
以下示例展示了如何更改 Twenty Twenty-Three 主题的调色板和几个按钮样式。此代码专门针对 Twenty Twenty-Three 使用的颜色命名约定设计,因此您需要为其他主题进行相应调整。
<?php
/**
* 此函数根据用户的登录状态更新主题的调色板来修改 theme JSON 数据。
*
* @param object $theme_json 原始的 theme JSON 数据。
* @return object 修改后的 theme JSON 数据。
*/
function example_modify_color_palette_if_logged_in( $theme_json ) {
if ( is_user_logged_in() ) {
$new_data = array(
'version' => 2,
'settings' => array(
'color' => array(
'palette' => array(
array(
'color' => '#ffffff',
'name' => __( 'Base' ),
'slug' => 'base',
),
array(
'color' => '#00131C',
'name' => __( 'Contrast' ),
'slug' => 'contrast',
),
array(
'color' => '#3858E9',
'name' => __( 'Primary' ),
'slug' => 'primary',
),
array(
'color' => '#1D35B4',
'name' => __( 'Secondary' ),
'slug' => 'secondary',
),
array(
'color' => '#ECF6FA',
'name' => __( 'Tertiary' ),
'slug' => 'tertiary',
),
),
),
),
'styles' => array(
'elements' => array(
'button' => array(
'color' => array(
'background' => 'var(--wp--preset--color--primary)',
'text' => 'var(--wp--preset--color--base)',
),
),
),
),
);
// 返回修改后的 theme JSON 数据。
return $theme_json->update_with( $new_data );
}
// 返回原始的 theme JSON 数据。
return $theme_json;
}
// 为了使过滤器正常工作,必须在主题设置后运行。
function example_apply_theme_json_theme_filters() {
// 检查以确保主题具有 theme.json 文件。
if ( wp_theme_has_theme_json() ) {
add_filter( 'wp_theme_json_data_theme', 'example_modify_color_palette_if_logged_in' );
}
}
add_action( 'after_setup_theme', 'example_apply_theme_json_theme_filters' );
请注意,此代码同时修改了样式和设置。在 Twenty Twenty-Three 主题中,按钮在浅色背景上有深色文本。过滤器将调色板更改为使 primary 颜色变为蓝色,因此按钮文本需要更改为 base。
服务器端和客户端过滤器之间最重要的区别之一是,服务器端过滤器在服务器级别更新 theme.json 数据。然后处理此数据并用于创建 CSS 变量。
您可以检查页面的 HTML 和 CSS 以查看显式更改。调色板的 CSS 变量已更新,然后用于设置页面样式。
此功能有许多含义。例如,您可以添加或修改自定义 theme.json 设置。这些设置会生成自定义 CSS 变量,您可以使用这些变量来创建复杂的设计系统或为主题或块提供特定功能。
以下是一个回调函数示例,可用于添加自定义设置,为视口、媒体或其他断点输出 CSS 变量。变量将采用 --wp--custom--breakpoint--[size] 形式,可用于根据每个断点调整主题的外观。
/**
* 此函数通过为各种断点创建自定义 CSS 变量来修改 theme JSON 数据。
*
* @param object $theme_json 原始的 theme JSON 数据。
* @return object 修改后的 theme JSON 数据。
*/
function example_create_custom_breakpoint_variables( $theme_json ) {
$new_data = array(
'version' => 2,
'settings' => array(
'custom' => array(
'breakpoint' => array(
'small' => '360px',
'medium' => '780px',
'large' => '1080px',
),
),
),
);
// 返回修改后的 theme JSON 数据。
return $theme_json->update_with( $new_data );
}
接下来,让我们看看如何使用服务器端过滤器来限制编辑器中的用户功能。
根据用户权限限制 theme.json 设置
默认情况下,theme.json 文件允许您控制编辑器对站点上每个人的工作方式。但是,如果您想给用户不同的权限怎么办?也许您想为内容创作者禁用颜色控制,但允许管理员在全站范围内修改颜色。您无法通过 theme.json 文件做到这一点,但可以使用服务器端或客户端过滤器。
客户端和服务器端过滤器各有优缺点。客户端过滤器提供了更大的灵活性,可以直接在编辑器内调整设置。服务器端过滤器在服务器上更改 theme.json 数据,让您可以配置设置和样式,甚至创建 CSS 变量,如上一节所述。
现在,假设您使用不同的主题管理多个网站,这些主题具有未知的 theme.json 文件配置。
您的目标是使用工具插件在所有站点上保持一致的编辑器体验。为了简单起见,假设您想为除管理员(他们应该有权访问所有内容)之外的所有人关闭颜色控制。由于您不知道主题在全站范围内启用或禁用了哪些功能,因此还需要确保对管理员没有任何限制。
您可以使用与上述示例相同的过滤器,但让我们使用 wp_theme_json_data_user,以确保自定义设置始终优先于任何主题配置。
<?php
/**
* 此函数通过为所有用户禁用颜色设置,然后专门为具有 edit_theme_options 权限的用户(管理员)启用设置来修改 theme JSON 数据。
*
* @param object $theme_json 原始的 theme JSON 数据。
* @return object 修改后的 theme JSON 数据。
*/
function example_restrict_color_settings_to_administrators( $theme_json ) {
// 首先为所有人禁用颜色设置。这将覆盖主题可能提供的任何设置。
$default_settings = array(
'version' => 2,
'settings' => array(
'color' => array(
'text' => false,
'background' => false,
'link' => false,
),
),
);
$theme_json->update_with( $default_settings );
// 如果当前用户具有正确的权限,则启用颜色设置。
if ( current_user_can( 'edit_theme_options' ) ) {
$administrator_settings = array(
'version' => 2,
'settings' => array(
'color' => array(
'text' => true,
'background' => true,
'link' => true,
),
),
);
$theme_json->update_with( $administrator_settings );
}
// 返回修改后的 theme JSON 数据。
return $theme_json;
}
// 为了使过滤器正常工作,必须在主题设置后运行。
function example_apply_theme_json_user_filters() {
// 检查以确保主题具有 theme.json 文件。
if ( wp_theme_has_theme_json() ) {
add_filter( 'wp_theme_json_data_user', 'example_restrict_color_settings_to_administrators' );
}
}
add_action( 'after_setup_theme', 'example_apply_theme_json_user_filters' );
通过应用此过滤器,只有具有 edit_theme_options 权限的用户才能在编辑器中查看颜色控件。除非您对 WordPress 安装进行了自定义,否则这通常仅包括管理员。
现在您已经知道如何使用这四个服务器端过滤器修改 theme.json 数据,您可以开始思考此功能的其他应用。
假设您正在使用 Twenty-Three,但希望避免为一些小的更改创建和管理子主题。您可以编写一个小的工具插件,使用 wp_theme_json_data_theme 过滤器覆盖 theme.json 的设置和样式。
或者,您可以使用 wp_theme_json_data_block 过滤器将样式应用到您的自定义块。这将提供更好的默认体验,同时允许主题和用户覆盖此配置。
可能性几乎是无限的。
有关更多信息以及探索本文示例的工作插件,您可以在 GitHub 上查看 Editor Curation Examples 插件。区块编辑器手册还包括一个关于其他定制方法的绝佳资源,并且每个 WordPress 版本都会添加更多内容。
那么,您将使用服务器端 theme.json 过滤器构建什么?是否有您希望看到但缺失的功能?请在评论中添加您的想法。