admin管理员组

文章数量:1317906

Ok, I've tried to find a solution to this problem but so far, no luck.

I've been trying to find a way to do incremental output using a shortcode. I've got several functions that take up to 30 seconds to finish. Rather than have a blank page until it's completely finished, I'm trying to output each function as it completes.

So far, the only idea I've come up with is to use the shortcode to spit out a template with JS similar to this:

echo '<div id="location1"></div>';
echo "<script>
const thiselement = document.querySelector('#location1');
</script>";

Then, have each function's output fill in the template by doing something like this:

echo '<script>element.thiselement  = "<div>' . $value . '</div>";</script>';
ob_flush();
flush();

What I need now is a way to call or hook into those functions after the page with the specific shortcode finishes displaying.

Does such a hook, filter, etc. even exist?

Thanks.

Ok, I've tried to find a solution to this problem but so far, no luck.

I've been trying to find a way to do incremental output using a shortcode. I've got several functions that take up to 30 seconds to finish. Rather than have a blank page until it's completely finished, I'm trying to output each function as it completes.

So far, the only idea I've come up with is to use the shortcode to spit out a template with JS similar to this:

echo '<div id="location1"></div>';
echo "<script>
const thiselement = document.querySelector('#location1');
</script>";

Then, have each function's output fill in the template by doing something like this:

echo '<script>element.thiselement  = "<div>' . $value . '</div>";</script>';
ob_flush();
flush();

What I need now is a way to call or hook into those functions after the page with the specific shortcode finishes displaying.

Does such a hook, filter, etc. even exist?

Thanks.

Share Improve this question asked Oct 27, 2020 at 18:57 uPromptuPrompt 1729 bronze badges 5
  • 2 What are you doing in shortcodes that's needing this? Note that shortcodes do not echo their output, they cannot echo their output, they have to return it as a string. A progressively rendered shortcode as you're suggesting would cripple the REST API, RSS feeds, other shortcodes, etc. I'm surprised your shortcodes haven't already caused broken behaviour – Tom J Nowell Commented Oct 27, 2020 at 19:18
  • you can delay execution of javascript using javascript setTimeout: window.setTimeout( function(){ alert('wait 2 seconds then hello world') }, 2000 ) – admcfajn Commented Oct 27, 2020 at 19:55
  • Scanning websites entered by the user for vulnerabilities. Which means, result times can widely vary. – uPrompt Commented Oct 27, 2020 at 19:58
  • i'm not sure what you mean @uPrompt maybe this would help? developer.wordpress/block-editor/packages/packages-hooks – admcfajn Commented Oct 27, 2020 at 23:14
  • With a shortcode I have to wait for the return value of a function before the page will display. What I want to do is display the page and as the function retrieves information, displays it. Imagine a for loop that counts to some astronomical number. I want the user to see the numbers being counted and not stare at a blank page until that number is reached. – uPrompt Commented Oct 28, 2020 at 13:26
Add a comment  | 

1 Answer 1

Reset to default 1

Thanks for the downvote. Found the answer myself anyway using the shutdown action.

What this does:

The init action clears any output buffers and starts a new one. The Add_JS_Shortcode is added to a page and creates a location for something to be shown. The shutdown action, from the API reference, runs just before PHP shuts down execution. It replaces the output of the shortcode with the contents of $output 30 seconds later.

The net result of this is $output 'magically' appears after the page is fully loaded.

It's purpose in my case: Users enter a URL to examine on my website. Various PHP scripts run that check the Whois, fetches the header, checks for various files and directories, parses the page for details... etc. I did not want the end user staring at a browser loading symbol while these tasks were performed. This solved that problem.

 add_action('init', array($this, 'Setup_Output_Buffer'));
 add_action('shutdown', array($this, 'Shutdown_Callback' ));
 add_shortcode('Add_JS', array($this, 'Add_JS_Shortcode'));

 public function Setup_Output_Buffer() {
    $this->Clear_Buffers();
    ob_start();
 }

 public function Clear_Buffers() {
    $buffers = ob_get_status(true);
    if (count($buffers) > 1) {
        for ($i = 0; $i < count($buffers) - 1; $i++) {
            ob_end_flush();
        }
    }
 }

public function Add_JS_Shortcode($atts) {
    $output = '<div id="thisdivid"></div>';
    $output .= "<script>const tobeshownlater = document.querySelector('#thisdivid');</script>";
    return $output;
}

public function Shutdown_Callback() {
   if (basename(get_permalink()) == 'pagewithshortcode') {
      sleep(30);
      $output = "This is shown 30 sec after the page loads.";
      echo '<script>tobeshownlater.innerHTML = "<div>' . $output . '</div>";</script>';
      ob_flush();
      flush();   
   }
}

本文标签: pluginsAny way to hook into WP after a page displays