EP226. “wp_interactivity_data_wp_context 自动转换属性与 data-wp-each 循环”
🔒 登录后可标记已读开始真正搭建 Quiz 前台界面:先用纯 PHP(不涉及任何 Interactivity API)输出题目文字和背景色——因为这两项数据本身没有任何交互性,没必要绕远路用 JS 处理。真正的核心突破是用 wp_interactivity_data_wp_context() 这个 WordPress 函数,直接把 PHP 的 $attributes 数组转换成 data-wp-context 属性,不需要手写 JSON 字符串——这样一来 attributes 里的 answers 数组自动就变成了 JS 里可用的 context.answers。再用 data-wp-each 这个模板循环属性,把这个数组渲染成一个个 <li> 列表项,并给每个列表项绑定点击事件。这一讲同样验证了「服务器端预渲染」的强大之处:查看网页源代码能看到列表项的文字内容在 JS 执行前就已经真实存在。
涉及文件
wp-content/plugins/interactive-quiz/src/render.php(修改)wp-content/plugins/interactive-quiz/src/view.js(修改)
代码实现
src/render.php(完整文件,含调试用的 print_r):
<?php
/**
* PHP file to use when rendering the block type on the server to show on the front end.
* ...
*/
?>
<?php print_r($attributes) ?>
<div style="background-color: <?php echo $attributes['bgColor'] ?>" class="paying-attention-frontend" data-wp-interactive="create-block" <?php echo wp_interactivity_data_wp_context($attributes) ?>>
<p><?php echo $attributes['question'] ?></p>
<ul>
<template data-wp-each="context.answers">
<li data-wp-on--click="actions.guessAttempt" data-wp-text="context.item"></li>
</template>
</ul>
</div>
src/view.js(完整文件):
import { store, getContext } from "@wordpress/interactivity"
store("create-block", {
actions: {
guessAttempt: () => {
const context = getContext()
console.log(context)
},
toggle: () => {
const context = getContext()
context.isOpen = !context.isOpen
}
},
callbacks: {
logIsOpen: () => {
const { isOpen } = getContext()
// Log the value of `isOpen` each time it changes.
console.log(`Is open: ${isOpen}`)
}
}
})
关键改动点:
- 先用纯 PHP 处理没有交互性的静态数据:题目文字(
$attributes['question'])和背景色($attributes['bgColor'])都是「只需要显示、不需要响应用户操作」的数据,直接用最朴素的echo输出即可,完全不需要绕到 Interactivity API 里处理——这一讲刻意强调「不要看到 Interactivity API 就什么都往上套」 - CSS 直接复用旧插件的
frontend.css:Quiz 前台的视觉样式在插件开发章节早就写好验证过,原样搬进新插件的style.css,不需要重新设计 - 调试技巧:
print_r($attributes):不确定$attributes数组里具体有哪些字段、叫什么名字时,直接在模板任意位置打印出来看——这是比「猜字段名」更可靠的排查方式,能直接看到question/answers/correctAnswer/bgColor这些字段全貌,包括answers是一个数组、correctAnswer是从 0 开始数的下标 wp_interactivity_data_wp_context($attributes)——这一讲的核心发现,作者形容是「近来见过最让人兴奋的 WordPress 函数」:直接传入一个 PHP 数组,这个函数会自动生成一整段格式正确的data-wp-context='{...}'属性字符串(包括外层单引号、内部 JSON 双引号这些容易手写出错的细节),不需要像上一讲那样手动拼接 JSON 字符串——echo这个函数的返回值,直接嵌在<div ...>标签内部- 验证方式:浏览器「检查元素」看生成的 HTML——能看到
data-wp-context属性被自动加到了这个div上,值就是$attributes数组转换后的 JS 对象,字段名(question/answers/correctAnswer/bgColor)跟 PHP 数组完全对应 <template data-wp-each="context.answers">——Interactivity API 的循环写法:用标准 HTML 的<template>标签(浏览器默认不会渲染<template>内部的内容,只有通过 JS 才能激活),配合data-wp-each属性声明「要遍历context.answers这个数组,每一项都用这个模板渲染一次」——效果上类似 PHP 的foreach或 JS 的.map()data-wp-text="context.item"——访问循环当前项的固定写法:在data-wp-each循环体内部,当前遍历到的这一项固定通过context.item访问(不像大多数语言那样可以自己给循环变量取名),这是需要记住的 Interactivity API 特定约定- 列表项同时绑定点击事件:
data-wp-on--click="actions.guessAttempt",这一讲先只是把点击到的context(打印出来能看到item字段是具体点到的哪个答案文字)打印到控制台,验证事件确实触发、且能拿到正确的数据,真正的判分逻辑留到下一讲 - 再次验证「服务器端预渲染」的效果:查看网页源代码(不是检查元素),能看到
<li>标签内部的文字(比如oink/bark/meow)在 JS 完全没有执行的阶段就已经是这些真实答案文字了——不是空的等着 JS 填充,而是服务器端就已经把context.answers遍历完、把对应文字写进了返回给浏览器的原始 HTML;等浏览器加载完 JS,只是「接管」这份已经渲染好的 HTML,继续赋予它点击交互能力(作者形容为「hydrate 化」)——这正是 Interactivity API 让 WordPress 同时具备 SEO/无障碍/速度优势和客户端交互能力的关键 - 这一讲刻意把「判断点击答案对不对」的逻辑留到下一讲:作者提到很多其他教程会在第一小时内讲完更多内容,但更希望先讲透「什么时候该用 Interactivity API 循环,什么时候该用传统 PHP 循环」这类底层判断依据,而不是急着堆功能
[截图:前台 Quiz 区块正确渲染出题目文字和答案列表(oink/bark/meow 等),以及"查看网页源代码"里各 li 标签已带有真实答案文字的原始 HTML]
Hook / Function 速查
| 名称 | 类型 | 用途 |
|---|---|---|
wp_interactivity_data_wp_context($数组) | WP 内建 function | 把 PHP 数组自动转换成格式正确的 data-wp-context 属性字符串 |
<template data-wp-each="context.数组名"> | Interactivity API HTML 写法 | 遍历渲染数组,类似 foreach/.map() |
context.item | Interactivity API 固定约定 | 在 data-wp-each 循环体内访问当前遍历到的这一项 |
print_r($变量) | PHP 内建 function | 打印数组/对象的可读结构,用于排查字段名和数据结构 |
常见坑
- 给完全没有交互性的静态数据(比如题目文字)也强行套用 Interactivity API 的机制——纯 PHP
echo就够用,没必要绕远路 - 手动拼接
data-wp-context的 JSON 字符串,而不是用wp_interactivity_data_wp_context()——容易在引号嵌套上出错(上一讲已经踩过这个坑) - 试图给
data-wp-each循环体内的当前项自己取一个变量名——这个约定是固定的context.item,不能自定义 - 用「检查元素」(经过 JS 处理后的 DOM)而不是「查看网页源代码」(服务器原始返回内容)来验证服务器端预渲染效果——两者会造成误判,因为检查元素看到的已经是 JS 执行完之后的结果
延伸 / 后续讲座会用到
下一讲要讲清楚「什么时候该用 Interactivity API 的循环,什么时候更适合用传统 PHP 循环」,并且真正实现「点击答案后判断对错」的核心逻辑。
Sources
Udemy:
- Become a WordPress Developer: Unlocking Power With Code — Section 30, EP226