分析 WordPress `get_block_wrapper_attributes()` 函数的源码:如何为区块容器添加动态属性。

各位好,今天咱们来聊聊WordPress区块编辑器的“变形金刚”——get_block_wrapper_attributes()。这玩意儿就像区块的化妆师,能让你的区块容器穿上各种各样的“衣服”,也就是动态属性。

一、什么是区块容器?为什么要给它化妆?

首先,我们要搞清楚什么是区块容器。简单来说,每个区块在前端渲染的时候,都会被一个HTML元素包裹起来,这个元素就是区块容器。默认情况下,这个容器可能就是一个简单的<div>

为什么要给它化妆呢?原因很简单:

  • 样式控制: 你想让某些区块拥有特殊的边框、背景色、内边距等等,但又不想直接写在区块的内容里,这时候就可以通过给区块容器添加 class 来实现。
  • 交互行为: 你可能需要给某些区块容器添加data属性,以便 JavaScript 可以根据这些属性来控制区块的行为。
  • SEO优化: 某些场景下,你可能需要修改区块容器的语义化标签,比如将<div>改成<article>,以便更好地被搜索引擎识别。
  • 无障碍性(Accessibility):添加ARAI属性,提升区块的无障碍访问。

总之,给区块容器添加动态属性,能让你的区块更加灵活、可定制,也更能满足各种各样的需求。

二、get_block_wrapper_attributes():区块容器化妆师的工作原理

get_block_wrapper_attributes()函数是WordPress 5.5版本引入的,专门用来给区块容器添加属性的。它的工作原理很简单:

  1. 接收属性数组: 它接收一个数组作为参数,这个数组包含了你想要添加到区块容器上的所有属性。这个数组的键是属性名,值是属性值。
  2. 过滤属性: WordPress会对这些属性进行一定的过滤,确保安全性。
  3. 生成HTML属性字符串: 它将这些属性转换成一个HTML属性字符串,例如class="my-class" data-id="123"
  4. 返回属性字符串: 最后,它将这个属性字符串返回,你就可以在区块模板中使用这个字符串了。

三、get_block_wrapper_attributes()的用法:从入门到精通

接下来,我们通过一些例子来演示get_block_wrapper_attributes()的用法。

1. 最简单的用法:添加一个class

假设你想给你的区块容器添加一个名为my-custom-block的class,你可以这样做:

<?php
/**
 * Registers the block using the metadata loaded from the `block.json` file.
 * Behind the scenes, it registers also all assets so they can be enqueued
 * through the block editor in the corresponding context.
 *
 * @see https://developer.wordpress.org/reference/functions/register_block_type/
 */
function create_my_block_init() {
    register_block_type( __DIR__ . '/build', array(
        'render_callback' => 'render_my_block'
    ) );
}
add_action( 'init', 'create_my_block_init' );

function render_my_block( $attributes, $content, $block ) {
    $wrapper_attributes = get_block_wrapper_attributes( [ 'class' => 'my-custom-block' ] );
    return '<div ' . $wrapper_attributes . '>' . $content . '</div>';
}

在这个例子中,我们创建了一个名为render_my_block的回调函数,这个函数会在前端渲染区块的时候被调用。

render_my_block函数中,我们调用了get_block_wrapper_attributes()函数,并传入了一个包含class属性的数组。

最后,我们将get_block_wrapper_attributes()函数返回的属性字符串插入到区块容器的HTML代码中。

效果:区块容器会变成<div class="wp-block-my-block my-custom-block">。(注意,wp-block-my-block是WordPress自动添加的class,用于标识这个区块。)

2. 添加多个属性

你可以同时添加多个属性:

function render_my_block( $attributes, $content, $block ) {
    $wrapper_attributes = get_block_wrapper_attributes( [
        'class' => 'my-custom-block',
        'data-id' => '123',
        'data-type' => 'my-block'
    ] );
    return '<div ' . $wrapper_attributes . '>' . $content . '</div>';
}

效果:区块容器会变成<div class="wp-block-my-block my-custom-block" data-id="123" data-type="my-block">

3. 根据区块属性动态生成属性值

get_block_wrapper_attributes()的强大之处在于,它可以根据区块的属性动态生成属性值。

例如,假设你的区块有一个名为alignment的属性,用于控制区块的对齐方式,你可以这样做:

function render_my_block( $attributes, $content, $block ) {
    $alignment = isset( $attributes['alignment'] ) ? $attributes['alignment'] : 'left'; // 默认左对齐

    $wrapper_attributes = get_block_wrapper_attributes( [
        'class' => 'my-custom-block align-' . $alignment
    ] );

    return '<div ' . $wrapper_attributes . '>' . $content . '</div>';
}

在这个例子中,我们首先获取了区块的alignment属性。如果alignment属性存在,我们就使用它的值;否则,我们就使用默认值left

然后,我们将alignment属性的值拼接成一个class名,并将这个class名添加到区块容器的class属性中。

效果:如果alignment属性的值是center,那么区块容器会变成<div class="wp-block-my-block my-custom-block align-center">

4. 与useBlockProps()结合使用

如果你使用JavaScript来编写区块,那么你可能已经熟悉了useBlockProps()这个hook。useBlockProps()会自动添加一些默认的属性,例如class属性。

你可以将get_block_wrapper_attributes()useBlockProps()结合使用,以便在JavaScript中控制区块容器的属性。

首先,在PHP中,你需要将get_block_wrapper_attributes()函数返回的属性字符串传递给JavaScript:

function render_my_block( $attributes, $content, $block ) {
    $wrapper_attributes = get_block_wrapper_attributes( [
        'class' => 'my-custom-block',
    ] );

    $block_props = wp_json_encode( $wrapper_attributes ); // 将属性字符串转换为JSON格式

    return '<div data-block-props="' . esc_attr( $block_props ) . '">' . $content . '</div>';
}

在这个例子中,我们将get_block_wrapper_attributes()函数返回的属性字符串转换为JSON格式,并将这个JSON字符串存储在一个名为data-block-props的data属性中。

然后,在JavaScript中,你可以使用useBlockProps() hook来获取这些属性,并将它们添加到区块容器上:

import { useBlockProps } from '@wordpress/block-editor';

export default function Edit() {
    const blockProps = useBlockProps();
    const wrapperAttributes = JSON.parse( document.querySelector( '[data-block-props]' ).dataset.blockProps );
    const combinedProps = { ...blockProps, ...wrapperAttributes };

    return (
        <div { ...combinedProps }>
            Hello World!
        </div>
    );
}

表格总结:常用属性及用法

属性名 作用 示例
class 添加CSS类名。用于控制区块的样式。 'class' => 'my-custom-block align-center'
id 添加HTML ID。用于唯一标识一个区块,方便JavaScript操作。 'id' => 'my-unique-block'
data-* 添加自定义data属性。用于存储与区块相关的数据,方便JavaScript访问。 'data-id' => '123', 'data-type' => 'my-block'
aria-* 添加 ARIA 属性。 用于提升区块的无障碍性,让屏幕阅读器等辅助技术能够更好地理解区块的内容。 'aria-label' => 'My Custom Block'
role 添加 role 属性。 用于定义区块的角色,进一步提升区块的无障碍性。 'role' => 'article'
style 添加内联样式。不推荐使用,因为它会降低代码的可维护性。建议使用CSS类名来控制样式。 'style' => 'background-color: red;'
title 添加title属性。鼠标悬停时显示的提示文字。 'title' => 'This is a custom block'
tabindex 添加tabindex属性。控制区块的tab顺序,通常用于需要键盘操作的区块。 'tabindex' => '0'
其他HTML属性 几乎所有HTML属性都可以添加到区块容器上,例如langdironclick等等。 'lang' => 'zh-CN', 'onclick' => 'alert("Hello!")'

四、进阶技巧:自定义过滤属性

WordPress会对get_block_wrapper_attributes()函数接收的属性进行一定的过滤,以确保安全性。如果你想自定义过滤规则,可以使用block_wrapper_attributes过滤器。

例如,假设你想允许在区块容器上使用data-custom-attribute属性,你可以这样做:

add_filter( 'block_wrapper_attributes', 'allow_custom_data_attribute', 10, 2 );

function allow_custom_data_attribute( $attributes, $block_name ) {
    if ( isset( $attributes['data-custom-attribute'] ) ) {
        return $attributes;
    }
    return $attributes;
}

五、注意事项:安全第一!

在使用get_block_wrapper_attributes()函数时,一定要注意安全性。

  • 转义属性值: 如果属性值来自用户输入,一定要使用esc_attr()函数进行转义,以防止XSS攻击。
  • 过滤属性名: 尽量只允许使用预定义的属性名,以防止恶意用户添加任意属性。
  • 谨慎使用style属性: 尽量不要使用style属性,因为它会降低代码的可维护性,也容易导致安全问题。

六、总结:get_block_wrapper_attributes(),让你的区块更上一层楼

get_block_wrapper_attributes()函数是WordPress区块编辑器中一个非常强大的工具。它可以让你轻松地给区块容器添加动态属性,从而实现各种各样的功能。

只要你掌握了它的用法,并注意安全性,就能让你的区块更上一层楼,为用户带来更好的体验。

好了,今天的讲座就到这里。希望大家有所收获,下次再见!

发表回复

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