# 关于传统小工具区块 传统小工具区块允许用户添加、编辑和预览由插件注册的第三方小工具,以及使用经典小工具编辑器添加的小工具。 可通过区块插入器添加传统小工具区块,并从该区块的下拉菜单中选择小工具来添加第三方小工具。 也可通过在区块插入器中搜索小工具名称并选择该小工具来添加第三方小工具。系统将插入一个传统小工具区块的变体。 ## 与传统小工具区块的兼容性 ### `widget-added` 事件 传统小工具区块将以类似于定制器的方式显示小工具的表单,因此与大多数第三方小工具兼容。 如果小工具在其表单中使用 JavaScript,则必须在 `document` 上触发 `'widget-added'` jQuery 事件后,将事件添加到 DOM 中。 例如,当“更改密码”复选框被勾选时,小工具可能希望显示一个“密码”字段。 ```js ( function ( $ ) { $( document ).on( 'widget-added', function ( $event, $control ) { $control.find( '.change-password' ).on( 'change', function () { var isChecked = $( this ).prop( 'checked' ); $control.find( '.password' ).toggleClass( 'hidden', ! isChecked ); } ); } ); } )( jQuery ); ``` 请注意,所有小工具的事件处理程序都在 `widget-added` 回调中添加。 ### 显示“无预览可用” 当未选择传统小工具区块时,该区块将显示小工具的预览。 当小工具的 `widget()` 函数未呈现任何内容或仅呈现空的 HTML 元素时,传统小工具区块会自动显示“无预览可用”的消息。 小工具可以通过在不应显示预览时从 `widget()` 提前返回来利用这一点。 ```php class ExampleWidget extends WP_Widget { ... public function widget( $instance ) { if ( ! isset( $instance['name'] ) ) { // 名称为必填项,如果没有则什么都不显示。 return; } ?>

名称:

... true, // ...其他选项 ); parent::__construct( 'example_widget', 'ExampleWidget', $widget_ops ); } ... } ``` 这允许区块编辑器和其他 REST API 客户端通过访问 REST API 响应中的 `instance.raw` 来查看您的小工具的实例数组。 请注意,[WordPress 5.8.0 之前的版本允许您通过在扩展 `WP_Widget` 的类中将 `$show_instance_in_rest` 设置为 `true`](https://core.trac.wordpress.org/ticket/53332) 来启用此功能。 ```php class ExampleWidget extends WP_Widget { ... public $show_instance_in_rest = true; ... } ``` 现在已不推荐使用此方法,建议改用小工具选项方法。 #### 2) 添加区块转换 现在,我们可以定义一个[区块转换](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-transforms/),告诉区块编辑器用什么替换包含您小工具的传统小工具区块。 这是通过向区块定义中添加 JavaScript 代码来实现的。在此示例中,我们定义了一个转换,将 ID 为 `'example_widget'` 的小工具转换为名称为 `'example/block'` 的区块。 ```js transforms: { from: [ { type: 'block', blocks: [ 'core/legacy-widget' ], isMatch: ( { idBase, instance } ) => { if ( ! instance?.raw ) { // 如果原始实例未在 REST API 中显示,则无法转换。 return false; } return idBase === 'example_widget'; }, transform: ( { instance } ) => { return createBlock( 'example/block', { name: instance.raw.name, } ); }, }, ] }, ``` #### 3) 在传统小工具区块中隐藏小工具 最后,我们可以告诉传统小工具区块在“选择小工具”下拉列表和区块插入器中隐藏您的小工具。这鼓励用户使用替换您小工具的区块。 可以使用 `widget_types_to_hide_from_legacy_widget_block` 过滤器来实现这一点。 ```php function hide_example_widget( $widget_types ) { $widget_types[] = 'example_widget'; return $widget_types; } add_filter( 'widget_types_to_hide_from_legacy_widget_block', 'hide_example_widget' ); ``` ## 在其他区块编辑器中使用传统小工具区块(高级) 您可以选择允许在其他区块编辑器(例如 WordPress 文章编辑器)中使用传统小工具区块。默认情况下,此功能未启用。 首先,确保页面上加载了传统小工具所需的任何样式和脚本。一种便捷的方法是手动执行用户浏览小工具 WP 管理屏幕时通常运行的所有钩子。 ```php add_action( 'admin_print_styles', function() { if ( get_current_screen()->is_block_editor() ) { do_action( 'admin_print_styles-widgets.php' ); } } ); add_action( 'admin_print_scripts', function() { if ( get_current_screen()->is_block_editor() ) { do_action( 'load-widgets.php' ); do_action( 'widgets.php' ); do_action( 'sidebar_admin_setup' ); do_action( 'admin_print_scripts-widgets.php' ); } } ); add_action( 'admin_print_footer_scripts', function() { if ( get_current_screen()->is_block_editor() ) { do_action( 'admin_print_footer_scripts-widgets.php' ); } } ); add_action( 'admin_footer', function() { if ( get_current_screen()->is_block_editor() ) { do_action( 'admin_footer-widgets.php' ); } } ); ``` 然后,使用 `@wordpress/widgets` 包中定义的 `registerLegacyWidgetBlock` 注册传统小工具区块。 ```php add_action( 'enqueue_block_editor_assets', function() { wp_enqueue_script( 'wp-widgets' ); wp_add_inline_script( 'wp-widgets', 'wp.widgets.registerLegacyWidgetBlock()' ); } ); ```