当AJAX在Gutenberg中保存时,在SAVE_POST后发出管理员通知

时间:2020-04-01 作者:helle

如何显示管理员通知?

我想对save\\u post\\u post操作执行一些操作,并想在之后通知管理员操作的成功和详细信息。

到目前为止,我尝试过:

add_action(\'save_post_post\', "do_Stuff");

function do_stuff( $postId ){

     session_start();
    //do stuff and create some $msg;

     set_transient( \'temporary_message\', $msg, 60*60*12 );
     add_action( \'admin_notices\', \'show_notice\');

}

function show_notice(){
    ?>
    <div class="notice notice-error">
        <p>Fehler: <?=get_transient( \'temporary_message\' )?></p>
    </div>
    <?php
}
问题是,不会显示此通知,因为浏览器在保存后不会重新加载,因为保存是通过ajax进行的。。。调用了我的save\\u post\\u post挂钩。

我已经尝试创建和输出一些JSON,因为如果我输出任何文本,就会收到一个错误管理通知,表明我的JSON无效。但是当我发送JSON并在Chrome中检查网络流量时,我没有看到任何响应,并且。。之前的错误仍然存在。

如何显示管理员通知?

1 个回复
SO网友:bosco

提交通知古腾堡提供了一种以以下形式显示通知的机制the Notices Data package. 在古腾堡的编辑中,软件包的选择者和动作创造者在core/notices 存储,并可通过其中的任何标准方式访问,例如:

  • useDispatch( \'core/notices\' ) 钩入功能部件(包括edit() 块类型的函数,以及render() 使用注册的块编辑器插件的功能@wordpress/plugins\' registerPlugin() 函数)
  • withDispatch() 基于类的组件的HOC工厂
  • dispatch( \'core/notices\' ) 对于任何其他代码
    import { useState } from \'@wordpress/element\';
    import { useDispatch } from \'@wordpress/data\';
    
    const MyComponent = props => {
      const [ error, setError ] = useState( null );
    
      if( error ) {
        useDispatch( \'core/notices\' ).createNotice( {
          status: \'error\',
          content: error,
        } );
    
        setError( null );
      }
    
      // ...
    }
    


    订阅保存操作

我不确定这是否是实现这一点的最佳机制,并且它是否适合您的代码实际上取决于您的特定用例,但通常我们会实现;倾听事件”;在Gutenberg和Redux中,通过订阅应用程序状态更新和测试特定更改。

按照这种逻辑,在保存操作完成时执行代码的一种方法是观察isPostSaving() 上的选择器core/editor 存储:

import { useState } from \'@wordpress/element\';
import { useSelect } from \'@wordpress/data\';

const MyComponent = props => {
  const is_saving = useSelect( select => select( \'core/editor\' ).isSavingPost() );
  const [ was_saving, setWasSaving ] = useState( is_saving );

  if( was_saving ) {
    // If state transitioned from saving -> not saving, execute post-save logic.
    if( ! is_saving ) {
      setWasSaving( false );

      console.log( \'Post Save Finished\' );
    }
  }
  else if( is_saving ) {
    // If state transitioned from not saving -> saving, set was_saving.
    setWasSaving( true );
  }

  // ...
}
我们还可以将该逻辑提取到自定义挂钩中,以使其更具可移植性:

const usePostSaved = () => {
  const is_saving = useSelect( select => select( \'core/editor\' ).isSavingPost() );
  const [ was_saving, setWasSaving ] = useState( is_saving );

  if( was_saving ) {
    if( ! is_saving ) {
      setWasSaving( false );

      return true;
    }
  }
  else if( is_saving ) {
    setWasSaving( true );
  }

  return false;
}

const MyComponent = props => {
  const saved = usePostSaved();

  if( saved )
    console.log( \'Post Save Finished\' );

  // ...
}
<从后端获取通知如果您有生成通知的后端代码,那么在编辑器中显示通知的一种解决方案是在瞬态中对它们进行排队,然后通过实现自定义REST API端点或wp_ajax_ 处理程序。在任何一种情况下@wordpress/api-fetch 包可以帮助您简洁地执行网络请求。

也可以利用Heartbeat API 为此,或者以一种可以通过古腾堡内置选择器访问的方式公开通知(例如,将其添加到post meta)。

示例:AJAX处理程序/块编辑器插件提供通知的保存操作挂钩和AJAX处理程序可能如下所示:

function wpse36297_handle_post_save( $post_id, $post, $update ) {
  // ...
  if( $a_critical_error ) {
    $notice = [
      \'status\'        => \'error\',
      \'message\'       => __( \'Things done blew up :/\', \'wpse36297\' ),
      \'isDismissable\' => true,
    ];
  }
  else {
    $notice = [
      \'status\'        => \'success\',
      \'message\'       => __( \'This was a triumph! \\\\o/\', \'wpse36297\' ),
      \'isDismissable\' => true,
    ];
  }

  set_transient( \'wpse36297-notice-post_\' . $post_id, $notice, 60*60 );
}
add_action( \'save_post_post\', \'wpse36297_handle_post_save\', 10, 3 );

function wpse36297_ajax_get_post_notice() {
  $post_id = (int) $_GET[\'post_id\'];

  if( ! current_user_can( \'edit_post\', $post_id ) ) {
    wp_send_json_error(
      [
        \'msg\' => __( \'User is not permitted to edit this post.\', \'wpse36297\' ),
      ],
      403
    );
  }

  $notice = get_transient( \'wpse36297-notice-post_\' . $post_id );

  if( $notice )
    delete_transient( \'wpse36297-notice-post_\' . $post_id );

  wp_send_json_success( $notice );
}
add_action( \'wp_ajax_wpse36297-get-post-notice\', \'wpse36297_ajax_get_post_notice\' );
一旦状态更新表明保存刚刚完成,我们就可以向该处理程序发出请求。

旁白:下面的代码使用wp.ajax.settings.url 由提供wp-util 剧本如果您正在使用@wordpress/scripts/@wordpress/create-block, 此脚本不会自动添加到中的脚本依赖项.asset.php 文件,因为它不是Gutenberg包。

import apiFetch from \'@wordpress/api-fetch\';
import { registerPlugin } from \'@wordpress/plugins\';
import { useState, useEffect } from \'@wordpress/element\';
import { useSelect, useDispatch } from \'@wordpress/data\';

const fetchPostNotice = async ( post_id ) => {
  const url = new URL( window.location.origin + wp.ajax.settings.url );

  url.searchParams.append( \'action\', \'wpse36297-get-post-notice\' );
  url.searchParams.append( \'post_id\', post_id );

  const res = await apiFetch( { url: url.toString() } );

  if( ! res.success )
    return { status: \'error\', message: res.data.msg };

  return res.data;
};

registerPlugin(
  \'wpse362975\',
  {
    render: () => {
      const { createNotice } = useDispatch( \'core/notices\' );
      const { getCurrentPostId } = useSelect( \'core/editor\' );
      const is_saving = useSelect( select => select( \'core/editor\' ).isSavingPost() );
      const [ was_saving, setWasSaving ] = useState( is_saving );

      useEffect(
        async () => {
          if( was_saving && ! is_saving ) {
            setWasSaving( false );

            const notice = await fetchPostNotice( getCurrentPostId() );

            if( ! notice )
              return;

            const { status, message, ...options } = notice;
            createNotice( status, message, options );
          }
          else if( is_saving && ! was_saving ) {
            setWasSaving( true );
          }
        },
        [ is_saving, was_saving ]
      );

      return null;
    }
  }
);

相关推荐

Bad Request in AJAX

我在一个WordPress插件中工作。我需要以下AJAX代码的帮助。// On change division $(\'body\').on( \'change\', \'.division\', function() { $.ajax({ type: \"POST\", url:localData.statesurl, //http://localhost/wordpress/wp-admin/