WP DEVELOP

EP226. “wp_interactivity_data_wp_context 自动转换属性与 data-wp-each 循环”

首页 WordPress 开发课程 INTERACTIVITY API · EP226
约 14 分钟· #EP226#INTERACTIVITY API
🔒 登录后可标记已读

开始真正搭建 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.itemInteractivity 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