阻止wp.hooks.addFilter()在古腾堡中的某些自定义帖子类型上运行

时间:2019-09-06 21:37:26

标签: wordpress wordpress-gutenberg gutenberg-blocks

我的任务是使用新的Gutenberg API(而不是任何WP PHP)阻止addFilter()在某些自定义帖子类型上运行。当前已将其输入到editor.PostFeaturedImage挂钩中,这意味着它会在Gutenberg编辑器每次加载“特色图像”框时触发。

过滤器调用一个函数,该函数会在“特色图片”框下方添加一个下拉菜单,以允许用户选择一个贡献者(它们本身是自定义帖子类型)以将该图片存入图片。

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

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

Borrowing from this ticket,我试图将主函数setFeaturedImageArtist放在匿名函数内,该匿名函数也将帖子类型打印到addFilter()的控制台中。我可以打印帖子的类型,但是调用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.

我不确定最好的方法是什么,并且该文档很少/几乎不适用。是否可以创建模仿editor.PostFeaturedImage但仅在某些自定义帖子类型上触发的自定义挂钩?还是有某种方法可以在包装器中调用setFeaturedImageArtist之类的函数来检查帖子类型?

1 个答案:

答案 0 :(得分:1)

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

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,使其返回null。取而代之的是,我们传递该变量,然后在组件render中返回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
);