WP DEVELOP

EP155. “新插件起步:用 Starter 模板跳过样板代码”

首页 WordPress 开发课程 新 BLOCK 类型练习 · EP155
约 16 分钟· #EP155#新 BLOCK 类型练习
🔒 登录后可标记已读

开始做第二个 Block 类型练习项目——Featured Professor(教授推荐卡):在文章里选一位 Professor 文章类型的实例,插入一张实时拉取该 Professor 最新数据渲染出来的推荐卡片,且这个关联是双向的(Professor 详情页也会反过来列出「被哪些文章提到」)。因为前几个插件已经把「注册脚本/样式、注册 Block、创建插件类」这套样板代码写过很多遍,这一讲用课程提供的 Starter 压缩包直接跳过这些没有新概念的重复劳动,规定插件文件夹要重命名成 featured-professor。这一讲的实际内容是先跑通 npm init -y + 安装 @wordpress/scripts、把 build/start 脚本写进 package.json,再动手搭出一个先用假数据(1/2/3)硬编码的下拉选择框,新增 profId 字符串属性存储选中值,验证「选完之后刷新页面还记得选择」这条数据链路先通了,再在下一讲换成真正查询 Professor 文章列表。


涉及文件

  • wp-content/plugins/featured-professor/featured-professor.php (课程提供的 Starter 模板,未修改,直接使用)
  • wp-content/plugins/featured-professor/src/index.scss (课程提供的 Starter 模板,未修改,直接使用)
  • wp-content/plugins/featured-professor/package.json (新建)
  • wp-content/plugins/featured-professor/src/index.js (修改,基于 Starter 模板)

代码实现

featured-professor.php(Starter 模板原样,插件基础骨架)

<?php

if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

class FeaturedProfessor {
  function __construct() {
    add_action('init', [$this, 'onInit']);
  }

  function onInit() {
    wp_register_script('featuredProfessorScript', plugin_dir_url(__FILE__) . 'build/index.js', array('wp-blocks', 'wp-i18n', 'wp-editor'));
    wp_register_style('featuredProfessorStyle', plugin_dir_url(__FILE__) . 'build/index.css');

    register_block_type('ourplugin/featured-professor', array(
      'render_callback' => [$this, 'renderCallback'],
      'editor_script' => 'featuredProfessorScript',
      'editor_style' => 'featuredProfessorStyle'
    ));
  }

  function renderCallback($attributes) {
    return '<p>We will replace this content soon.</p>';
  }

}

$featuredProfessor = new FeaturedProfessor();

终端命令:初始化 npm 项目、安装官方构建工具

npm init -y
npm install @wordpress/scripts

package.jsonscripts 里新增 build/start

"scripts": {
  "build": "wp-scripts build",
  "start": "wp-scripts start",
  "test": "echo \"Error: no test specified\" && exit 1"
}

src/index.js:把占位文字换成硬编码假数据的下拉选择框,接上 profId 属性

import "./index.scss"

wp.blocks.registerBlockType("ourplugin/featured-professor", {
  title: "Professor Callout",
  description: "Include a short description and link to a professor of your choice",
  icon: "welcome-learn-more",
  category: "common",
  attributes: {
    profId: {type: "string"}
  },
  edit: EditComponent,
  save: function () {
    return null
  }
})

function EditComponent(props) {
  return (
    <div className="featured-professor-wrapper">
      <div className="professor-select-container">
        <select onChange={e => props.setAttributes({profId: e.target.value})}>
          <option value="">Select a professor</option>
          <option value="1" selected={props.attributes.profId == 1}>1</option>
          <option value="2" selected={props.attributes.profId == 2}>2</option>
          <option value="3" selected={props.attributes.profId == 3}>3</option>
        </select>
      </div>
      <div>
        The HTML preview of the selected professor will appear here.
      </div>
    </div>
  )
}

关键改动点:

  • Starter 压缩包只提供插件骨架,不含任何新概念:PHP 类、init 钩子里注册脚本/样式/Block(写法跟之前几个插件完全一致)、render_callback 先返回一段占位文字;JS 端的 EditComponent 先返回两个占位 <div>(一个给下拉框用、一个给预览卡片用),registerBlockType 也先不带 attributes
  • 用 Starter 模板时要注意:EditComponent 原本没有声明 props 参数(因为还没接任何属性),这一讲第一次用到 props.setAttributes()/props.attributes 时要记得把这个参数补上——这是作者特别提醒的一个「Starter 模板本该带上但漏掉」的细节
  • npm init -y-y 让命令行跳过所有交互式提问,直接用默认值生成 package.json
  • npm install @wordpress/scripts:这个插件项目还没有像 Quiz Block 插件那样用过任何第三方 npm 包,所以这是这个新插件资料夹里第一次跑 npm install
  • attributes: {profId: {type: "string"}}:即使 Professor 文章的 ID 本质是数字,属性类型依然选 string——作者说这是自己长期实践下来的经验:WordPress 从数据库读出来的数据、以及做字符串比较时,用 string 类型更省心、更少踩坑
  • <select onChange={e => props.setAttributes({profId: e.target.value})}>:下拉框整体绑定 onChange,从事件对象 e.target.value 拿到用户选中的那个 <option>value
  • 第一个 <option value="">Select a professor</option>:没有默认必选值时的占位选项,value 是空字符串
  • <option value="1" selected={props.attributes.profId == 1}>1</option>:每个选项都要单独判断「当前保存的 profId 是否等于这个选项的值」来决定要不要标记 selected,这样刷新页面后下拉框才能正确回显之前选过的值——这里先用硬编码的 1/2/3 三个假选项验证这条「选择 → 存属性 → 刷新回显」的链路,下一讲会换成真正从数据库查出来的 Professor 列表

[截图:Gutenberg 编辑器里插入 Featured Professor Block,下拉框只有硬编码的 1/2/3 三个占位选项]


Hook / Function 速查

名称类型用途
npm init -ynpm 命令跳过交互式提问,用默认值快速生成 package.json
<option selected={布尔表达式}>JSX/HTML 写法用布尔表达式动态决定某个下拉选项是否默认选中

常见坑

  • 用 Starter 模板时 EditComponent 函数忘记补上 props 参数——一旦要用 props.setAttributes()/props.attributes 就会报错,因为函数体内根本没有这个变量
  • profId 属性类型设成 number——作者建议统一用 string,跟 WordPress 数据库读出来的值、字符串比较逻辑更兼容,减少后续踩坑
  • 每个 <option> 各自判断 selected,如果拿错比较的属性名或者漏了某个选项没写 selected 判断——刷新页面后下拉框不会正确回显之前的选择

延伸 / 后续讲座会用到

下一讲要把这几个硬编码的假选项换成真正查询数据库里所有 Professor 文章、动态生成选项列表。


Sources

Udemy:

  • Become a WordPress Developer: Unlocking Power With Code — Section 26, EP155