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

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

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

让钩子(Hook)触发然后在函数内取消是可行的,但函数本身是资源繁重的,指令是完全防止函数被触发。这个想法是内置的钩子(Hook)/函数会触发。

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 但仅触发某些自定义帖子类型的自定义钩子(Hook)?或者有什么方法可以在检查帖子类型的包装器中调用像 setFeaturedImageArtist 这样的函数?
  • Wordpress Hooks on Github
  • Hooks in Wordpress Handbook
  • 最佳答案

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

    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 函数之外。 withSelectpostType 进行了检查,使其返回 null。取而代之的是,我们传递该变量,然后在组件渲染中返回 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
    );
    

    关于wordpress - 防止 wp.hooks.addFilter() 在古腾堡中的某些自定义帖子类型上运行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57828793/

    10-09 23:32