0

Question edited:

I'm working on an alternative to iframes because WP.org balks at them and tends to reject plugins that have them (I know this from experience) So, here's the code I have to try to replace an iframe:

add_action('wp_ajax_myAction', array($this, 'myAction_ajax_handler'));
public function myAction_ajax_handler() {
   echo time();
   wp_die();
}

When the admin page is displayed, I have this:

   echo '<body onLoad="loadDoc();">';
   echo '<div id=myDiv></div>';
   ?>
        <script>
            function loadDoc() {
                var xhttp = new XMLHttpRequest();
                xhttp.onreadystatechange = function () {
                    if (this.readyState == 4 && this.status == 200) {
                        document.getElementById("myDiv").innerHTML = this.responseText;
                    }
                };
                xhttp.open("GET", ajaxurl + "?action=myAction", true);
                xhttp.send();
                setTimeout("loadDoc()", 1000);
            }
        </script>
     <?php

It works.

Here's my questions.

Is this the proper way to do this?

Is there a better way to do this instead of polling with setTimeout?

Thanks!

4
  • In terms of web technologies there's also websockets you could use to stream the log, but that would also need script on the page to handle new data and add it to the log on the page. (There's an old discussion here about how Apache can't do websockets, but I assume that's out of date.)
    – Rup
    Commented Jun 13, 2021 at 9:05
  • What about server sent events? Will those work within a wp plugin admin panel?
    – uPrompt
    Commented Jun 14, 2021 at 12:59
  • Server sent events with websockets? Yes, everything sent over the web socket will come from the server. I'm not sure what you're asking?
    – Rup
    Commented Jun 14, 2021 at 13:00
  • Oops... Dup: Acceptable WP.org iframe alternative
    – bosco
    Commented Jun 26, 2021 at 20:05

1 Answer 1

1

Use JavaScript to poll for new data at an interval and update the DOM as it comes in. Downloading the complete log file at intervals would be very inefficient and quite likely consume a huge amount of bandwidth. Instead, use some server-side code to determine if new data is available and if so return that in the response.

For instance, the client could send some information about the last lines it received - say the time at which it last received new data, and the largest line number it already has. The server can then check if the file's modified time is greater than the time at which the client last received data, and if so, open the file and send any new lines to the client.

WordPress's AJAX handlers would be a fine way to implement the JS<=>WordPress communications. The Plugin Handbook's page on AJAX, and the Codex's "AJAX in Plugins" page are good places to start.

The Mozilla Developer Network has a nice intro on DOM manipulation via JS (among many other guides), but otherwise the subject matter in isolation is outside the scope of this Stack.

4
  • Thanks. I have seen the WP pages on AJAX. The problem I had was they're a bit hard to follow for those unfamiliar with AJAX. The way I've doing it was to add an even to the WP cron and have it output a log and keep it down to a manageable size then have a JS just load and output the log in an iframe. Seemed a rather clunky way of doing it. I have worked with the dom but mostly just parsing data. I'll take a hard look at that link. Thanks again.
    – uPrompt
    Commented Jun 14, 2021 at 12:11
  • Yeah... Sadly the new AJAX document that's intended to superseded the one from the Codex seems a little disjointed. The general idea is that you create a PHP function to handle the AJAX call, and make WordPress aware of it by hooking it to a wp_ajax_{custom action name} action (for logged in users) or wp_ajax_nopriv_{custom action name} (for logged out visitors). When you send an HTTP request to wp-admin/wp-ajax.php containing action={custom action name} in the query string - or that k/v pair as part of a JSON POST body - WordPress will execute your PHP function.
    – bosco
    Commented Jun 14, 2021 at 14:55
  • Your PHP function can then send whatever data back to the JS with something like wp_send_json( $new_lines ). From the JS side, you could trigger that with a GET request to wp-admin/wp-ajax.php?action={custom action name}&last_line=35&last_query_time=1623682725213. If you're still running into obstacles, I'd be happy to jump into a chat!
    – bosco
    Commented Jun 14, 2021 at 15:00
  • 1
    Thanks @bosco. I've temporarily put that project on the side till I learn more about JS. PHP, I got that down pretty well. JS still pretty confusing at times. Thanks.
    – uPrompt
    Commented Jun 15, 2021 at 18:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.