查询循环块是一个强大的工具,它允许用户循环浏览确定的帖子列表,并显示一组块,这些块将继承列表中每个帖子的上下文。例如,可以将其设置为循环浏览特定类别的所有帖子,并且对于每个帖子,都会显示其特色图像。当然还有更多!

但正是因为查询循环块是如此强大,并且可以进行出色的自定义,所以它也可能令人生畏。大多数用户不想呈现查询循环块的全部功能,因为大多数用户都不熟悉“查询”及其相关的技术术语的概念。取而代之的是,大多数用户可能会喜欢该块的预设版本,并更少的设置可以调整和清晰。默认情况下提供的帖子列表变化是此实践的一个很好的例子:用户将使用查询循环块而不会暴露于其技术性,也将更有可能发现和理解该块的目的。

以相同的方式,许多扩展器可能需要一种方法来呈现该块的定制版本,具有自己的预设,附加设置以及与其用例无关的自定义选项(例如,通常,他们的自定义邮政类型)。查询循环块提供了创建此类变体的非常有力的方法。

扩展块有变化

通过使用一些特定的查询循环块设置注册自己的块变体,您可以对其显示方式具有更精美的控制,同时仍然能够使用查询循环块在下面提供的完整功能。如果您不熟悉块变体,请了解更多有关它们的信息 这里

使用块变化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' ]变化,所有选定模式的属性都将用于除postTypeinherit查询属性,这可能会导致冲突和非功能变化。

为了绕过这一点,有两条路线,第一个是添加您的默认值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 */
    }
);

而且,就这样,您将创建了查询循环块的功能性较高!

By zhuon

发表回复

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