## 经典主题中的指令处理 在交互区块中,只要在 `block.json` 文件中添加 `supports.interactivity`,服务器指令处理便会自动进行。但经典主题呢? 经典主题同样可以使用交互性 API,如果希望利用服务器指令处理(推荐这样做),可以通过 `wp_interactivity_process_directives` 函数实现。该函数接收包含未处理指令的 HTML 标记,并根据全局状态、局部上下文及派生状态的初始值返回修改后的 HTML 标记。 ```php // 初始化全局状态与派生状态... wp_interactivity_state( '...', /* ... */ ); // 包含指令的交互式 HTML 标记 $html = '
...
'; // 处理指令,使其准备好发送至客户端 $processed_html = wp_interactivity_process_directives( $html ); ``` 就这样!无需其他操作。 若要在模板文件中使用 `wp_interactivity_process_directives`,可通过 `ob_start` 和 `ob_get_clean` 捕获 HTML 输出并在渲染前进行处理。 ```php
...
添加芒果 ``` 这个新按钮具有指向 `actions.addMango` 的 `data-wp-on-async--click` 指令,该操作在 JavaScript 存储库中定义如下: ```javascript const { state } = store( 'myFruitPlugin', { actions: { addMango() { state.fruits.push( '芒果' ); }, }, } ); ``` 若使用局部上下文,同样能实现相同效果: ```javascript store( 'myFruitPlugin', { actions: { addMango() { const context = getContext(); context.fruits.push( '芒果' ); }, }, } ); ``` 当用户点击“添加芒果”按钮时: 1. 触发 `addMango` 操作 2. 将“芒果”项添加至 `state.fruits`(或 `context.fruits`)数组 3. Interactivity API 自动更新 DOM,为新增水果添加 `
  • ` 元素 ```html ``` 重要提示:当状态已在服务端初始化时,客户端无需重复初始化。 ```javascript store( 'myFruitPlugin', { state: { fruits: [ '苹果', '香蕉', '樱桃' ], // 此处无需重复定义! }, } ); ``` ## 在服务端初始化派生状态 无论派生状态是源自全局状态、局部上下文还是两者结合,均可通过服务端指令处理在服务端进行预处理。 _建议阅读[理解全局状态、局部上下文与派生状态](/docs/reference-guides/interactivity-api/core-concepts/undestanding-global-state-local-context-and-derived-state.md)指南,深入了解 Interactivity API 中派生状态的运作机制。_ ### 可静态定义的派生状态 假设我们需要添加一个删除所有水果的按钮: ```html ``` ```javascript const { state } = store( 'myFruitPlugin', { actions: { // ... deleteFruits() { state.fruits = []; }, }, } ); ``` 接下来,我们希望在无水果时显示特定提示信息。通过使用引用派生状态 `state.hasFruits` 的 `data-wp-bind--hidden` 指令,可以控制提示信息的显示/隐藏: ```html
    暂无水果,敬请谅解!
    ``` 派生状态 `state.hasFruits` 在客户端通过 getter 定义: ```javascript const { state } = store( 'myFruitPlugin', { state: { get hasFruits() { return state.fruits.length > 0; }, }, // ... } ); ``` 至此,客户端运行正常,点击“删除所有水果”按钮后会显示“暂无水果”提示。但问题在于:由于 `state.hasFruits` 未在服务端定义,`hidden` 属性不会出现在初始 HTML 中,这意味着在 JavaScript 加载完成前,提示信息会持续显示。这不仅会造成访客困惑,还会在 JavaScript 加载完成后因提示信息隐藏而产生布局偏移。 解决方案是使用 `wp_interactivity_state` 在服务端定义派生状态的初始值: - 当初始值已知且为静态值时,可直接定义: ```php wp_interactivity_state( 'myFruitPlugin', array( 'fruits' => array( '苹果', '香蕉', '樱桃' ), 'hasFruits' => true )); ``` - 或通过必要计算进行定义: ```php $fruits = array( '苹果', '香蕉', '樱桃' ); $hasFruits = count( $fruits ) > 0; wp_interactivity_state( 'myFruitPlugin', array( 'fruits' => $fruits, 'hasFruits' => $hasFruits, )); ``` 无论采用哪种方式,核心在于 `state.hasFruits` 的初始值现已在服务端定义。这使得服务端指令处理能够操作 `data-wp-bind--hidden` 指令,并根据需要在 HTML 标记中添加 `hidden` 属性。 # 服务器端渲染:在服务器上处理指令 WordPress 始终建立在服务器端渲染的基础之上。传统上,当用户请求一个 WordPress 页面时,服务器会处理 PHP 代码、查询数据库,并生成发送到浏览器的 HTML 标记。 近年来,像 Vue、React 或 Svelte 这样的现代 JavaScript 框架彻底改变了我们构建 Web 应用程序的方式。这些框架提供了响应式和声明式的编程模型,使开发人员能够轻松创建动态、交互式的用户界面。 然而,在服务器端渲染方面,这些框架需要一个基于 JavaScript 的服务器(例如 NodeJS)来执行其代码并生成初始 HTML。这意味着像 WordPress 这样基于 PHP 的服务器无法直接利用这些框架,除非牺牲其原生的 PHP 渲染能力。这一限制给希望利用响应式和声明式编程能力,同时又能受益于 WordPress 传统服务器端渲染优势的开发人员带来了挑战。Interactivity API 通过将[响应式和声明式编程原则](/docs/reference-guides/interactivity-api/core-concepts/the-reactive-and-declarative-mindset.md)引入 WordPress,弥合了这一差距,同时不损害其服务器端渲染的基础。 在本指南中,我们将探讨 Interactivity API 如何在服务器上处理指令,使 WordPress 能够在初始页面加载时提供交互式、状态感知的 HTML,并为无缝的客户端交互奠定基础。 ## 在服务器上处理指令 Interactivity API 的服务器指令处理功能使 WordPress 能够生成具有正确交互状态的初始 HTML,从而提供更快的初始渲染。在初始服务器端渲染之后,Interactivity API 的客户端 JavaScript 会接管,实现动态更新和交互,而无需完全重新加载页面。这种方法结合了两者的优点:传统 WordPress 服务器端渲染的 SEO 和性能优势,以及现代 JavaScript 框架提供的动态、响应式用户界面。 为了理解服务器指令处理的工作原理,让我们从一个使用 `data-wp-each` 指令渲染水果列表的示例开始。 以下是确保指令在 WordPress 服务器端渲染期间被 Interactivity API 的服务器指令处理正确处理的必要步骤: - **1. 将区块标记为交互式** 首先,要启用交互式区块指令的服务器处理,必须在 `block.json` 中添加 `supports.interactivity`: ```json { "supports": { "interactivity": true } } ``` - **2. 初始化全局状态或本地上下文** 然后,必须初始化在页面服务器端渲染期间将使用的全局状态或本地上下文。 如果使用全局状态,必须使用 `wp_interactivity_state` 函数: ```php wp_interactivity_state( 'myFruitPlugin', array( 'fruits' => array( 'Apple', 'Banana', 'Cherry' ) )); ``` 如果使用本地上下文,初始值通过 `data-wp-context` 指令本身定义,可以通过以下方式之一: - 直接添加到 HTML 中。 ```html ``` - 使用 `wp_interactivity_data_wp_context` 辅助函数。 ```php array( 'Apple', 'Banana', 'Cherry' ) ); ?> ``` - **3. 使用指令定义交互式元素** 接下来,需要在 HTML 标记中添加必要的指令。 ```html ``` 在此示例中: - `data-wp-interactive` 指令激活 DOM 元素及其子元素的交互性。 - `data-wp-each` 指令用于渲染元素列表。该指令可以在 `