WordPress源码深度解析之:`Block`的`attributes`:如何定义和验证块的属性。

嘿!各位观众老爷,晚上好!今天咱们来聊聊WordPress Block的attributes,这玩意儿就像咱们盖房子用的砖头,定义得好,房子才结实漂亮。咱们要深入挖掘一下,看看这砖头是怎么定义的,又是怎么保证质量的。

开场白:attributes的重要性

在WordPress Block Editor(古腾堡编辑器)里,attributes是块数据的核心。它们定义了块可以存储哪些信息,比如文本内容、颜色、尺寸等等。一个块的attributes定义得好,就能让用户更方便地控制块的外观和行为。反之,如果定义得不好,用户体验就会很糟糕,甚至可能导致块无法正常工作。所以,attributes的设计是至关重要的!

第一部分:attributes的定义方式

attributes通常在block.json文件中定义,也可以在JavaScript代码中使用registerBlockType函数进行定义。咱们先来看看block.json的定义方式,这比较直观:

{
  "apiVersion": 2,
  "name": "my-custom-block/example",
  "title": "Example Block",
  "category": "common",
  "icon": "smiley",
  "description": "A simple example block.",
  "attributes": {
    "content": {
      "type": "string",
      "default": "Hello, World!"
    },
    "textColor": {
      "type": "string",
      "default": "black"
    },
    "fontSize": {
      "type": "number",
      "default": 16
    },
    "alignment": {
      "type": "string",
      "default": "left",
      "enum": ["left", "center", "right"]
    },
    "bold": {
      "type": "boolean",
      "default": false
    }
  },
  "supports": {
    "align": true
  },
  "textdomain": "my-custom-block",
  "editorScript": "file:./index.js",
  "style": "file:./style-index.css"
}

在这个例子中,我们定义了五个attributes

  • content: 文本内容,类型是string,默认值是"Hello, World!"。
  • textColor: 文本颜色,类型是string,默认值是"black"。
  • fontSize: 字体大小,类型是number,默认值是16。
  • alignment: 对齐方式,类型是string,默认值是"left",并且只能是"left"、"center"或"right"中的一个。
  • bold: 是否加粗,类型是boolean,默认值是false

现在,咱们来解释一下每个attribute的属性:

  • type: 指定attribute的数据类型。常用的类型有stringnumberbooleanarrayobject
  • default: 指定attribute的默认值。当用户没有设置该attribute时,就会使用默认值。
  • enum: 指定attribute的可选值。只有当typestringnumber时才能使用。

除了block.json,还可以在JavaScript代码中定义attributes。使用registerBlockType函数:

import { registerBlockType } from '@wordpress/blocks';

registerBlockType('my-custom-block/example', {
  title: 'Example Block',
  category: 'common',
  icon: 'smiley',
  description: 'A simple example block.',
  attributes: {
    content: {
      type: 'string',
      default: 'Hello, World!'
    },
    textColor: {
      type: 'string',
      default: 'black'
    },
    fontSize: {
      type: 'number',
      default: 16
    },
    alignment: {
      type: 'string',
      default: 'left',
      enum: ['left', 'center', 'right']
    },
    bold: {
      type: 'boolean',
      default: false
    }
  },
  edit: (props) => {
    // 编辑器界面的代码
    return <p>Hello from the editor!</p>;
  },
  save: (props) => {
    // 保存时的代码
    return <p>Hello from the saved content!</p>;
  }
});

这种方式和block.json的定义方式基本相同,只是将attributes的定义放在了JavaScript代码中。

第二部分:attributes的类型详解

咱们再深入一点,看看各种attributes类型的使用场景和一些注意事项:

类型 描述 示例 使用场景 注意事项
string 文本字符串。 json "content": { "type": "string", "default": "Hello, World!" } | 存储文本内容,比如标题、段落、按钮文字等。 | 最好设置一个合理的default值,避免显示空白。 使用source属性可以从HTML元素中提取文本内容。
number 数字。 json "fontSize": { "type": "number", "default": 16 } | 存储数字,比如字体大小、边距、宽度等。 | 最好设置一个合理的default值。 可以使用minimummaximum属性限制数字的范围。
boolean 布尔值(truefalse)。 json "bold": { "type": "boolean", "default": false } | 存储开关状态,比如是否加粗、是否显示等。 | 最好设置一个合理的default值。
array 数组。 json "items": { "type": "array", "default": [] } | 存储列表数据,比如图片URL列表、标签列表等。 | 注意数组元素的类型。 可以使用items属性指定数组元素的类型。
object 对象。 json "style": { "type": "object", "default": {} } 存储复杂数据结构,比如样式配置、动画参数等。 注意对象的属性类型。
null 空值。不建议直接使用,通常结合其他类型使用。 json "image": { "type": ["string", "null"], "default": null } | 表示某个属性可能为空,比如图片URL,如果没有选择图片,则为null 如果属性可能为空,建议使用这种方式。

第三部分:attributes的验证和数据清洗

光定义好attributes还不够,咱们还得保证数据的质量。比如,用户可能输入一个不合法的字体大小,或者上传了一个损坏的图片。这时候,咱们就需要对attributes进行验证和数据清洗。

WordPress Block Editor提供了一些机制来验证和清洗attributes

  1. enum属性: 限制stringnumber类型attribute的可选值。这是一种最简单的验证方式。

    "alignment": {
      "type": "string",
      "default": "left",
      "enum": ["left", "center", "right"]
    }

    如果用户尝试设置一个不在enum列表中的值,WordPress Block Editor会自动将其重置为default值。

  2. 自定义验证函数: 可以编写自定义的JavaScript函数来验证attributes。这需要用到useCallback hook。

    import { registerBlockType } from '@wordpress/blocks';
    import { useCallback } from '@wordpress/element';
    
    registerBlockType('my-custom-block/example', {
      title: 'Example Block',
      category: 'common',
      icon: 'smiley',
      description: 'A simple example block.',
      attributes: {
        fontSize: {
          type: 'number',
          default: 16
        }
      },
      edit: (props) => {
        const { attributes, setAttributes } = props;
        const { fontSize } = attributes;
    
        const onChangeFontSize = useCallback( ( newFontSize ) => {
          // 验证字体大小是否在合理范围内
          if ( newFontSize < 10 || newFontSize > 100 ) {
            alert( '字体大小必须在10到100之间!' );
            return; // 阻止更新
          }
          setAttributes( { fontSize: newFontSize } );
        }, [ setAttributes ] );
    
        // 编辑器界面的代码,包含一个输入框,用于设置字体大小
        return (
          <div>
            <label htmlFor="font-size-input">字体大小:</label>
            <input
              id="font-size-input"
              type="number"
              value={ fontSize }
              onChange={ ( event ) => onChangeFontSize( parseInt( event.target.value ) ) }
            />
          </div>
        );
      },
      save: (props) => {
        const { attributes } = props;
        const { fontSize } = attributes;
    
        return (
          <p style={ { fontSize: fontSize + 'px' } }>
            Hello from the saved content!
          </p>
        );
      }
    });

    在这个例子中,onChangeFontSize函数验证了用户输入的字体大小是否在10到100之间。如果不在这个范围内,会弹出一个警告框,并且阻止attributes的更新。

  3. source属性: 指定从HTML中提取attribute值的方式。

    WordPress 提供多种 source 类型,用于从不同的 HTML 结构中提取数据。常见的 source 类型包括:

    • 'attribute': 从 HTML 元素的属性中提取数据。
    • 'text': 从 HTML 元素的文本内容中提取数据。
    • 'html': 从 HTML 元素的 innerHTML 中提取数据。
    • 'children': 从 HTML 元素的子元素中提取数据。

    例如,从一个链接的href属性中提取URL:

    "linkURL": {
        "type": "string",
        "source": "attribute",
        "selector": "a",
        "attribute": "href"
    }
    • selector: 指定要提取数据的 HTML 元素的选择器。
    • attribute: 指定要从 HTML 元素的哪个属性中提取数据(仅当 source'attribute' 时使用)。
  4. 使用第三方库: 可以使用第三方库,比如validator.js,来进行更复杂的验证。

第四部分:attributes与数据持久化

attributes的值最终会被保存到WordPress数据库中。当用户保存文章时,WordPress Block Editor会将块的attributes序列化成HTML注释,然后保存到文章内容中。

例如,一个块的HTML注释可能是这样的:

<!-- wp:my-custom-block/example {"content":"Hello, World!","textColor":"red","fontSize":20} /-->

当文章被加载时,WordPress Block Editor会解析这些HTML注释,然后将attributes的值传递给块的editsave函数。

第五部分:最佳实践

  1. 明确定义attributes的类型: 避免使用any类型,尽量使用具体的类型,比如stringnumberboolean
  2. 设置合理的default: 这可以提高用户体验,避免显示空白或错误的值。
  3. 使用enum属性限制可选值: 尽可能使用enum属性来限制stringnumber类型attribute的可选值。
  4. 编写自定义验证函数: 对于复杂的验证逻辑,可以编写自定义的JavaScript函数。
  5. 考虑数据持久化: 确保attributes的值可以被正确地序列化和反序列化。
  6. 保持attributes的简洁性: 只定义必要的attributes,避免过度设计。
  7. 使用block.json: 尽量使用block.json文件定义attributes,这可以提高代码的可读性和可维护性。
  8. 利用source属性: 充分利用source属性,可以方便地从HTML元素中提取数据,简化块的开发。

总结

attributes是WordPress Block的核心,定义和验证attributes是构建高质量Block的关键。希望通过今天的讲解,大家对attributes有了更深入的了解。记住,好的attributes设计,能让你的Block更加强大、灵活和易用!

今天的讲座就到这里,谢谢大家!如果还有什么疑问,欢迎提问。下次再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注