在古腾堡的某些自定义 Post 类型上防止 wp.hooks.addFilter() 从 运行

Prevent wp.hooks.addFilter() from Running on Certain Custom Post Types in Gutenberg

我的任务是防止 addFilter() 使用新的 Gutenberg API 而不是任何 WP PHP 在某些自定义 post 类型上 运行 .它目前被送入 editor.PostFeaturedImage 挂钩,这意味着每次古腾堡编辑器加载特色图片框时都会触发它。

过滤器调用一个函数,在特色图像框下方添加一个下拉菜单,以允许用户选择贡献者(它们本身是自定义 post 类型)来归功于图像。

过滤器不应 运行 贡献者自定义 post 类型,但应 运行 其他自定义 post 类型。贡献者自定义 post 类型应该仍然有一个特色图片框,但没有下拉菜单。

让钩子触发然后在函数内取消是可行的,但函数本身占用大量资源,指令是为了防止函数触发。这个想法是内置 hook/function 会触发。

Borrowing from this ticket,我试图将主函数 setFeaturedImageArtist 放在一个匿名函数中,该匿名函数还打印 post 类型到 addFilter() 中的控制台。我能够打印 post 类型,但调用 setFeaturedImageArtist 函数没有按预期工作。

wp.hooks.addFilter( 'editor.PostFeaturedImage', 'blocks/featured-image-artist', function() {
    console.log(wp.data.select("core/editor").getCurrentPostType())
    return setFeaturedImageArtist()
});

像这样将 setFeaturedImageArtist 放在包装函数中也不起作用。我假设这是因为它是同一件事。

function checkPostType() {
   console.log(wp.data.select("core/editor").getCurrentPostType())
   return setFeaturedImageArtist()
}

wp.hooks.addFilter( 'editor.PostFeaturedImage', 'blocks/featured-image-artist', checkPostType);

这是过滤器触发的组件:

function setFeaturedImageArtist( OriginalComponent ) {
  return ( props ) => {

    const artistSelect = compose.compose(

        withDispatch( function( dispatch, props ) {
            return {
                setMetaValue: function( metaValue ) {
                    dispatch( 'core/editor' ).editPost(
                        { meta: { 'featured-image-artist': metaValue } }
                    );
                }
            }
        } ),

        withSelect( function( select, props ) {
           let query = {
              per_page    : 20,
              metaKey    : '_author_type',
              metaValue  : 'artist'
            };

            let postType = select("core/editor").getCurrentPostType();
            if ( postType === 'contributor' ) {
                return null
            }

            // Please see below
            // if ( postType === 'contributor' ) {
            //  return {
            //     postType
            //   }
            // }

            return {
                posts: select( 'core' ).getEntityRecords( 'postType', 'contributor', query ),

                metaValue: select( 'core/editor' ).getEditedPostAttribute( 'meta' )[ 'featured-image-artist' ],
            }
        } ) )( function( props ) {
            var options = [];

            // This works in removing the dropdown for authors/artists
            // if (props.postType === 'contributor'){
            //   return null
            // }

            if( props.posts ) {
                options.push( { value: 0, label: __( 'Select an artist', 'blocks' ) } );
                props.posts.forEach((post) => {
                    options.push({value:post.id, label:post.title.rendered});
                });
            } else {
                options.push( { value: 0, label: __( 'Loading artists...', 'blocks' ) } )
            }

            return el( SelectControl,
                {
                    label: __( 'Art Credit:', 'blocks' ),
                    options : options,
                    onChange: ( content ) => {
                        props.setMetaValue( content );
                    },
                    value: props.metaValue,
                }
            );
        }
    );

    return (
      el( 'div', { }, [
        el( OriginalComponent, props ),
        el( artistSelect )
      ] )
    );
  }
}

wp.hooks.addFilter( 'editor.PostFeaturedImage', 'blocks/featured-image-artist', setFeaturedImageArtist  );

这是过滤器触发的编辑组件:

function setFeaturedImageArtist( OriginalComponent ) {
  return ( props ) => {

      const artistSelect = compose.compose(
          ...
      )( function( props ) {
          ... // Cancelling out here works, but resources are loaded by this point.
      });

      return (
          el( 'div', { }, [
              el( OriginalComponent, props ),
              el( artistSelect )
          ])
      );
  }
}

wp.hooks.addFilter( 'editor.PostFeaturedImage', 'blocks/featured-image-artist', setFeaturedImageArtist  );

这是 React error being received:

Element type is invalid: expected a string (for built-in components) or
a class/function (for composite components) but got: undefined.

我不确定最好的方法是什么,文档是 scant/barely 适用的。是否可以创建一个模仿 editor.PostFeaturedImage 但仅在某些自定义 post 类型上触发的自定义挂钩?或者有什么方法可以在检查 post 类型的包装器中调用像 setFeaturedImageArtist 这样的函数?

我尝试重新创建脚本并修复了一些问题:

const { createElement: el } = wp.element;
const { compose } = wp.compose;
const { withSelect, withDispatch } = wp.data;
const { SelectControl } = wp.components;
const { __ } = wp.i18n;

const ArtistSelect = compose(
    withDispatch(function(dispatch, props) {
        return {
            setMetaValue: function(metaValue) {
                dispatch("core/editor").editPost({
                    meta: { "featured-image-artist": metaValue }
                });
            }
        };
    }),

    withSelect(function(select, props) {
        let query = {
            per_page: 20,
            metaKey: "_author_type",
            metaValue: "artist"
        };

        return {
            postType: select("core/editor").getCurrentPostType(),
            posts: select("core").getEntityRecords("postType", "contributor", query),

            metaValue: select("core/editor").getEditedPostAttribute("meta")[
                "featured-image-artist"
            ]
        };
    })
)(function(props) {
    var options = [];

    // This works in removing the dropdown for authors/artists
    if (props.postType === "contributor") {
        return null;
    }

    if (props.posts) {
        options.push({ value: 0, label: __("Select an artist", "blocks") });
        props.posts.forEach(post => {
            options.push({ value: post.id, label: post.title.rendered });
        });
    } else {
        options.push({ value: 0, label: __("Loading artists...", "blocks") });
    }

    return el(SelectControl, {
        label: __("Art Credit:", "blocks"),
        options: options,
        onChange: content => {
            props.setMetaValue(content);
        },
        value: props.metaValue
    });
});

function setFeaturedImageArtist(OriginalComponent) {
    return props => {
        return el("div", {}, [el(OriginalComponent, props), el(ArtistSelect)]);
    };
}

wp.hooks.addFilter(
    "editor.PostFeaturedImage",
    "blocks/featured-image-artist",
    setFeaturedImageArtist
);

ArtistSelect 是一个组件,所以我们把它放在 setFeaturedImageArtist 函数之外。 withSelect 检查了 postType 使其 return 为空。取而代之的是,我们传递该变量,然后在组件渲染中传递 return null。另一种方法是检查 setFeaturedImageArtist 内部。这是一个使用 JSX 的固定版本。希望它清楚:

const { compose } = wp.compose;
const { withSelect, withDispatch, select } = wp.data;
const { SelectControl } = wp.components;
const { __ } = wp.i18n;
const { addFilter } = wp.hooks;

const ArtistSelect = compose(
    withDispatch(dispatch => {
        return {
            setMetaValue: metaValue => {
                dispatch("core/editor").editPost({
                    meta: { "featured-image-artist": metaValue }
                });
            }
        };
    }),
    withSelect(select => {
        const query = {
            per_page: 20,
            metaKey: "_author_type",
            metaValue: "artist"
        };

        return {
            posts: select("core").getEntityRecords("postType", "contributor", query),
            metaValue: select("core/editor").getEditedPostAttribute("meta")[
                "featured-image-artist"
            ]
        };
    })
)(props => {
    const { posts, setMetaValue, metaValue } = props;
    const options = [];

    if (posts) {
        options.push({ value: 0, label: __("Select an artist", "blocks") });

        posts.forEach(post => {
            options.push({ value: post.id, label: post.title.rendered });
        });
    } else {
        options.push({ value: 0, label: __("Loading artists...", "blocks") });
    }

    return (
        <SelectControl
            label={__("Art Credit:", "blocks")}
            options={options}
            onChange={content => setMetaValue(content)}
            value={metaValue}
        />
    );
});

const setFeaturedImageArtist = OriginalComponent => {
    return props => {
        const post_type = select("core/editor").getCurrentPostType();

        if (post_type === "contributor") {
            return <OriginalComponent {...props} />;
        }

        return (
            <div>
                <OriginalComponent {...props} />
                <ArtistSelect />
            </div>
        );
    };
};

wp.hooks.addFilter(
    "editor.PostFeaturedImage",
    "blocks/featured-image-artist",
    setFeaturedImageArtist
);