查询循环块是一个强大的工具,它允许用户循环浏览确定的帖子列表,并显示一组块,这些块将继承列表中每个帖子的上下文。例如,可以将其设置为循环浏览特定类别的所有帖子,并且对于每个帖子,都会显示其特色图像。当然还有更多!
但正是因为查询循环块是如此强大,并且可以进行出色的自定义,所以它也可能令人生畏。大多数用户不想呈现查询循环块的全部功能,因为大多数用户都不熟悉“查询”及其相关的技术术语的概念。取而代之的是,大多数用户可能会喜欢该块的预设版本,并更少的设置可以调整和清晰。默认情况下提供的帖子列表变化是此实践的一个很好的例子:用户将使用查询循环块而不会暴露于其技术性,也将更有可能发现和理解该块的目的。
以相同的方式,许多扩展器可能需要一种方法来呈现该块的定制版本,具有自己的预设,附加设置以及与其用例无关的自定义选项(例如,通常,他们的自定义邮政类型)。查询循环块提供了创建此类变体的非常有力的方法。
扩展块有变化
通过使用一些特定的查询循环块设置注册自己的块变体,您可以对其显示方式具有更精美的控制,同时仍然能够使用查询循环块在下面提供的完整功能。如果您不熟悉块变体,请了解更多有关它们的信息 这里。
使用块变化API,您可以提供对用例最有意义的默认设置。
让我们继续旅程,例如,为插件设置一个插件的变化book
自定义帖子类型。
提供明智的默认值
您的第一步是创建一个变体,该变体将以一种提供块变体的方式进行设置,默认情况下显示书籍列表而不是博客文章。完整的变体代码将看起来像这样:
const MY_VARIATION_NAME = 'my-plugin/books-list';
registerBlockVariation( 'core/query', {
name: MY_VARIATION_NAME,
title: 'Books List',
description: 'Displays a list of books',
isActive: ( { namespace, query } ) => {
return (
namespace === MY_VARIATION_NAME
&& query.postType === 'book'
);
},
icon: /** An SVG icon can go here*/,
attributes: {
namespace: MY_VARIATION_NAME,
query: {
perPage: 6,
pages: 0,
offset: 0,
postType: 'book',
order: 'desc',
orderBy: 'date',
author: '',
search: '',
exclude: [],
sticky: '',
inherit: false,
},
},
scope: [ 'inserter' ],
}
);
如果听起来很多,请不要担心,让我们在这里浏览每个属性,看看他们为什么在那里以及他们在做什么。
本质上,您将从这样的开始:
registerBlockVariation( 'core/query', {
name: 'my-plugin/books-list',
attributes: {
query: {
/** ...more query settings if needed */
postType: 'book',
},
},
} );
这样,用户无需选择自定义postType
从下拉菜单中,并已获得正确的配置。但是,您可能会问,用户将如何找到和插入此变体?好问题!为了实现这一点,您应该添加:
{
/** ...variation properties */
scope: [ 'inserter' ],
}
这样,您的块将像用户在编辑器中并搜索它时一样出现。此时,您可能还需要在您的变体中添加自定义图标,标题和描述,就像这样:
{
/** ...variation properties */
title: 'Books List',
description: 'Displays a list of books',
icon: /* Your svg icon here */,
}
在这一点上,您的自定义变化几乎与独立块无法区分。完全贴上您的插件,易于发现,并直接直接向用户使用。
自定义您的变化布局
请注意,查询循环块支持'block'
作为字符串scope
财产。从理论上讲,这就是允许在插入块本身后拾取变体。阅读有关块变异器的更多信息 这里。
但是,是 不建议 要目前使用此信息,这是由于带有模式的查询循环设置,scope: [ 'block' ]
变化,所有选定模式的属性都将用于除postType
和inherit
查询属性,这可能会导致冲突和非功能变化。
为了绕过这一点,有两条路线,第一个是添加您的默认值innerBlocks
,这样:
innerBlocks: [
[
'core/post-template',
{},
[ [ 'core/post-title' ], [ 'core/post-excerpt' ] ],
],
[ 'core/query-pagination' ],
[ 'core/query-no-results' ],
],
有了innerBlocks
在您的变体中,您本质上跳过了使用建议的模式的查询循环块的设置阶段,并且将这些内部块作为其起始内容插入块。
另一种方法是注册特定于您的变体的模式,这些模式将在设置中建议,并替换块的流量。
查询循环块确定是否存在自身的活动变化,以及是否有特定模式可用于此变化。如果有的话,这些模式将是向用户建议的唯一模式,而不包括原始查询循环块的默认模式。否则,如果没有这样的模式,则将建议提出默认模式。
为了使模式与查询循环变化“连接”,您应该添加带有查询循环名称的变化名称(例如,core/query/$variation_name
)图案的blockTypes
财产。有关注册模式的更多详细信息 看这里。
如果您没有提供innerBlocks
在您的变化中,当用户选择时,还有一种建议“连接”变体Start blank
在设置阶段。通过检查查询循环是否有主动变化以及是否存在任何连接的变化,以类似的方式处理此操作。
为了将变体连接到另一个查询循环变化,我们需要定义scope
属性['block']
作为价值和namespace
定义为数组的属性。此数组应包含名称(name
他们想连接的任何变体的属性)。
例如,如果我们对插入器的查询循环变化scope: ['inserter']
)名字products
,我们可以连接一个范围block
通过设置其变化namespace
属性为['products']
。如果用户单击后选择此变化Start blank
,名称空间属性将被主要的插入器变化所覆盖。
使古腾堡认识到您的变化
实施此变化后,您可能会意识到一个微小的问题:虽然它对用户插入它是透明的,但Gutenberg仍然会识别该变体是其核心的查询环块,因此,在其插入后,它将是例如,在编辑器的树视图中显示为查询循环块。
我们需要一种方法来告诉编辑器这个块确实是您的特定变化。这就是isActive
属性是为:这是确定基于块的属性是否有效的一种方法。您可以这样使用:
{
/** ...variation properties */
isActive: ( { namespace, query } ) => {
return (
namespace === MY_VARIATION_NAME
&& query.postType === 'book'
);
},
}
您可能只想比较postType
因此,Gutenberg随时都会将块视为您的变化postType
火柴book
。但是,这使网络太宽了,因为其他插件可能希望根据book
帖子类型也是如此,或者我们可能不希望每当用户将类型设置为book
手动通过编辑器设置。
这就是为什么查询循环块暴露了一个特殊属性称为namespace
。它确实没有在块实现内部执行任何操作,它是一种简单且一致的方法,用于延长器识别和范围范围。此外,isActive
还接受了一系列的字符串,并具有要比较的属性。经常,namespace
足够了,因此您会这样使用:
{
/** ...variation properties */
attributes: {
/** ...variation attributes */
namespace: 'my-plugin/books-list',
},
isActive: [ 'namespace' ],
}
像这样,Gutenberg只有在与您的自定义名称空间匹配的情况下,这是您的特定变体!很方便!
扩展查询
即使所有这些,您的自定义帖子类型也可能有唯一的要求:它可能支持您可能想要过滤和查询的某些自定义属性,或者可能是无关紧要的,甚至可能完全不支持的其他查询参数!我们已经牢记了这样的用例构建查询循环块,因此让我们看看如何解决此问题。
禁用无关或不支持的查询控件
假设您根本不使用sticky
书籍中的属性,这与您的块的定制完全无关。为了不将用户混淆设置可能会做什么,而只能向他们展示清晰的UX,我们希望该控件不可用。此外,假设您不使用author
字段完全,通常表示已将该帖子添加到数据库的人,而是使用自定义bookAuthor
场地。因此,不仅保持author
过滤器会令人困惑,它会直接“打破”您的查询。
因此,查询循环块变化支持一个称为的属性allowedControls
,它接受我们要在检查员侧边栏上显示的控件键。默认情况下,我们接受所有控件,但是一旦我们提供了该属性的数组,我们只想指定将与我们相关的控件!
从Gutenberg版本14.2开始,可以使用以下控件:
inherit
– 显示允许查询直接从模板继承的切换开关。postType
– 显示可用帖子类型的下拉。order
– 显示一个下拉列表以选择查询的顺序。sticky
– 显示一个下拉列表,以选择如何处理粘性帖子。taxQuery
– 显示当前选定的邮政类型的可用分类法滤波器。author
– 显示一个输入字段以通过作者过滤查询。search
– 显示了通过关键字过滤查询的输入。
就我们而言,该物业看起来像这样:
{
/** ...variation properties */
allowedControls: [ 'inherit', 'order', 'taxQuery', 'search' ],
}
如果要隐藏上述所有可用控件,则可以将空数组设置为allowedControls
。
请注意,我们也禁用了postType
控制。当用户选择我们的变化时,为什么要向他们展示令人困惑的下拉列表以更改帖子类型?最重要的是,正如我们将在不久的将来看到的,它可能会破坏块。
添加其他控件
由于我们的插件使用我们需要查询的自定义属性,因此我们要添加自己的控件,以允许用户选择这些控件,而不是我们刚刚从核心Inspector控件中禁用的控件。我们可以通过 React Hoc 挂在一个 块过滤器,这样:
import { InspectorControls } from '@wordpress/block-editor';
export const withBookQueryControls = ( BlockEdit ) => ( props ) => {
// We only want to add these controls if it is our variation,
// so here we can implement a custom logic to check for that, similar
// to the `isActive` function described above.
// The following assumes that you wrote a custom `isMyBooksVariation`
// function to handle that.
return isMyBooksVariation( props ) ? (
<>
<BlockEdit key="edit" { ...props } />
<InspectorControls>
<BookAuthorSelector /> { /** Our custom component */ }
</InspectorControls>
</>
) : (
<BlockEdit key="edit" { ...props } />
);
};
addFilter( 'editor.BlockEdit', 'core/query', withBookQueryControls );
当然,您将负责实施控制的逻辑(您可能想看看 @wordpress/components
为了使您的控件无缝拟合在Gutenberg UI中)。您在query
块中的对象可用于根据您的需求创建自定义查询,并付出一些额外的努力。
当前,您可能必须实现略有不同的路径,以使查询在前端侧正确地表现正确(即在最终用户方面),并在编辑器侧显示正确的预览。
{
/** ...variation properties */
attributes: {
/** ...variation attributes */
query: {
/** ...more query settings if needed */
postType: 'book',
/** Our custom query parameter */
bookAuthor: 'J. R. R. Tolkien'
}
}
}
使您的自定义查询在前端
查询循环块主要通过接收属性并从那里构建查询的邮政模板块功能。查询循环块的其他一流儿童(例如分页块)的行为相同。他们构建查询,然后通过过滤器暴露结果 query_loop_block_query_vars
。
您可以将其连接到该过滤器中并相应地修改查询。只要确保您不会至少检查是否仅将过滤器应用于变体,就不会对其他查询循环块造成副作用!
if( 'my-plugin/books-list' === $block[ 'attrs' ][ 'namespace' ] ) {
add_filter(
'query_loop_block_query_vars',
function( $query ) {
/** You can read your block custom query parameters here and build your query */
},
);
}
(在上面的代码中,我们假设您有某种访问该块的方法,例如 pre_render_block
过滤器,但是特定的解决方案可能会不同,具体取决于用例,因此这不是牢固的建议)。
使您的自定义查询在编辑器侧工作
为了完成我们的自定义变化,我们可能希望编辑器对自定义查询的更改做出反应,并相应地显示适当的预览。这对于功能障碍不是必需的,但是它可以为您的块消费者提供完全集成的用户体验。
查询循环块获取其帖子以使用 WordPress REST API。添加到query
对象将作为查询参数传递给API。这意味着这些额外的参数应由REST API支持,或者由自定义过滤器(例如 rest_{$this->post_type}_query
允许您将自定义发布类型的任何API请求挂钩的过滤器。像这样:
add_filter(
'rest_book_query',
function( $args, $request ) {
/** We can access our custom parameters from here */
$book_author = $request->get_param( 'bookAuthor' );
/** ...your custom query logic */
}
);
而且,就这样,您将创建了查询循环块的功能性较高!