0

I've implemented a PJAX (push-state AJAX) library on my Wordpress site to handle page transitions, when the page content is updated everything is loading as expected except for Wordpress plugins.

This is because I have reinitialised everything else using jS but I am stuck on how to reinitialise Wordpress plugins on demand without hard reloading the page.

When changing between pages, the PJAX library calls:

reinitWPPlugins();

Which triggers this function:

function reinitWPPlugins(){
   // reinit Wordpress Plugins <- this is what I need help with
}

Is there a way I can force certain plugins to reinitialise? Maybe a WP ajax hook? Or even a call to a PHP snippet in functions.php?

12
  • I'm not clear what you think needs to be re-initialised? Are you talking about the JavaScript? What's not working? If you are loading the HTML for a page and it contains a button that does something with JavaScript then that's not going to work because the script that attaches the functionality to the element has already run. The solution for this mostly depends on how the original scripts are written, and won't involve WordPress. A generic solution that works for all plugins is very unlikely. You mention this function is from a library, have you read its documentation? Commented Feb 7, 2022 at 12:17
  • @JacobPeattie hey, Barba.js is the PJAX library, I have successfully implemented this on several sites which are not built on Wordpress. I am struggling to reinit plugins in Wordpress via PJAX. This means if I navigate around the site using the menu, I am able to seamlessly replace static content in each page by reinitialising the divs and other page content, but because Wordpress loads plugins on 'hard' page load, if I navigate from /page1 to /page2 and then back to /page1, the plugin content is no longer visible - so I need to reinit WP plugins inside Barba
    – van
    Commented Feb 7, 2022 at 12:24
  • How are you reinitialising the divs and page content? Where are you getting the markup? Commented Feb 7, 2022 at 12:28
  • @JacobPeattie reiniting in jS which is outside of the PJAX container, the markup for the static content is in the page itself as HTML, whereas the plugin content is loaded in via shortcode. I have noticed that any content that comes from plugins do not render correctly when the page is reloaded. Really what I need to know is how Wordpress initialises plugins on a regular page load (i.e with WP_ENQUEUE_SCRIPT or otherwise) and then to reverse engineer that so I can simulate a reload event for the plugins when required. I don't come from a Wordpress or PHP background though hence the blind spot
    – van
    Commented Feb 7, 2022 at 12:53
  • 1
    What you're attempting to figure out is not how WordPress works. You can't "initialise" shortcodes in JavaScript after loading the HTML. That's not how any of this works. I think you've underestimated the work that will be involved here. But you haven't actually answered my question, where are you getting the HTML? Commented Feb 7, 2022 at 13:02

2 Answers 2

0

Figured it out, for anyone else who runs into this issue here is the top to bottom of it. The plugin itself was using DOMContentLoaded (as pointed out by @JacobPeattie), in the initialisation script of the plugin.

So I created a clone of the initialisation script without the DOMContentLoaded function wrapper and dumped it on the server in a permanent folder under a different file name (reinitPlugin.js).

Then when reinitGallery(); was fired from the Barba.js transition, I removed the CSS and jS from the DOM using .remove() and reappended the core style and script tags only on the page where the plugin content needed to be rendered (/gallery).

Simply doing the same 'swap/replacement' with the initialisation script didn't work correctly, no console errors it just didn't fire at all, the file itself was updated in the DOM just no dice. Due to Barba.js being PJAX, I decided to try an .ajax() function to load the script instead and to wrap it in setTimeout() to ensure it loaded after the other scripts had been rendered and voilà.

Working Code:

function reInitGallery() {
    jQuery("#plugin-css").remove();
    jQuery("#plugin-js").remove();
    jQuery("#plugin-js-after").remove();
    if (window.location.href.indexOf("gallery") > -1) {
      // reinit css
      jQuery('head').append('<link rel="stylesheet" id="plugin-css" href="/plugins/plugin/css/plugin.css" type="text/css" media="all" />');
      // reinit js
      var pluginReplacementScript = document.createElement('script');
      fwds3dcovReplacementScript.type = 'text/javascript';
      fwds3dcovReplacementScript.id = 'plugin-js';
      fwds3dcovReplacementScript.src = '/wp-content/plugins/plugin/js/plugin.js';    
      document.body.appendChild(pluginReplacementScript);
      // reinit js after
      setTimeout(function() {
        jQuery.ajax({
          url: '/wp-content/plugins/plugin/js/reinitPlugin.js',
          dataType: "script"
        });
      }, 300);
    }
}
0

Thanks you so much @van for sharing this. I was struggling with this for a while to use a WP Plugin with Barba page transition.

I would also like to share my implementation.

Before you try this, make a note of the #IDs that you want to remove and their URL or code, as this will be different for different applications/plugins.

    function reInitFormidableForms() {
    var domain = window.location.origin; // Dynamically gets the domain

    // Remove existing Formidable Forms CSS and JavaScript
    // jQuery('#formidable-css').remove(); // Uncomment this line if you need to remove CSS. I did not need to remove it.
    // Add any of trhe scripts you need to remove
    jQuery('#formidable-js-extra').remove();
    jQuery('#formidable-js').remove();
    jQuery('#formidable-js-after').remove();
    jQuery('#formidable_chat-js').remove();

    // Delayed re-adding of the scripts and styles
    setTimeout(function () {
        // Reinitialize CSS
        // jQuery('head').append('<link rel="stylesheet" id="formidable-css" href="' + domain + '/wp-content/plugins/formidable/css/formidableforms.css" type="text/css" media="all" />');

        // Reinitialize inline JavaScript
        // Keep them in the original order
        jQuery('body').append('<script id="formidable-js-extra">' +
            'var frm_js = {"ajax_url":"' + domain + '\/wp-admin\/admin-ajax.php","images_url":"' + domain + '/wp-content\/plugins\/formidable\/images","loading":"Loading\u2026","remove":"Remove","offset":"4","nonce":"937e963b0f","id":"ID","no_results":"No results match","file_spam":"That file looks like Spam.","calc_error":"There is an error in the calculation in the field with key","empty_fields":"Please complete the preceding required fields before uploading a file.","focus_first_error":"1","include_alert_role":"1"};' +
            'var frm_password_checks = {"eight-char":{"label":"Eight characters minimum","regex":"\/^.{8,}$\/","message":"Passwords require at least 8 characters"},"lowercase":{"label":"One lowercase letter","regex":"#[a-z]+#","message":"Passwords must include at least one lowercase letter"},"uppercase":{"label":"One uppercase letter","regex":"#[A-Z]+#","message":"Passwords must include at least one uppercase letter"},"number":{"label":"One number","regex":"#[0-9]+#","message":"Passwords must include at least one number"},"special-char":{"label":"One special character","regex":"\/(?=.*[^a-zA-Z0-9])\/","message":"password is invalid"}};' +
            '</script>');

        jQuery('body').append('<script src="' + domain + '/wp-content/plugins/formidable-pro/js/frm.min.js" id="formidable-js"></script>');
        jQuery('body').append('<script id="formidable-js-after">window.frm_js.repeaterRowDeleteConfirmation = "Are you sure you want to delete this row?";</script>');
        jQuery('body').append('<script src="' + domain + '/wp-content/plugins/formidable-chat/js/chat.min.js" id="formidable_chat-js"></script>');
    }, 300); // Delay in milliseconds, adjust as needed
}

Then Add the function to the Barba hook as necessary:

barba.hooks.after(() => {

    reInitFormidableForms();

});
2
  • note that the jQuery code here is very insecure as a result of constructing HTML by joining strings. Instead it should be using DOM construction to create the elements, rather than parsing HTML, e.g. jQuery( '<a>', { href: url } ) not jQuery( '<a href="' + url '">. Also note that nothing in the code will undo the previous state of the JS files, and that for some plugins there is no answer to this question without modifying the plugin on a case by case basis
    – Tom J Nowell
    Commented Nov 23, 2023 at 10:17
  • also reconstructing a script tag that assigns global variables is not necessary and introduces security issues, instead it would be easier to simply assign the variables directly, e.g. remove the jQuery('body').append(' and use window.frm_js = {..... and window.frm_password_checks = directly
    – Tom J Nowell
    Commented Nov 23, 2023 at 10:20

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.