2

I'm developing a wordpress plugin and looking to save data entered in a block to a mySQL table. That's it. But how can data be sent from the block editor to the server side? I've spent two weeks looking for the appropriate technique and no joy.

The scenario is simple:

    registerBlockType("bla/quote-block", {   //...
        attributes: { quoteAtt: { type: 'string' } },
        edit: function(props) {
            props.setAttributes( { quoteAtt: getQuote() } );
            // ?? Send props.quoteAtt to the server ??
        }

I've found how to use AJAX + jQuery + wp_localize_script but that method apparently is only suitable for sending data from the front end (eg form data). The REST API is horrendously complex and all the documentation is about reading post [meta] data, not about saving data into a table.

Thank you!

7
  • blocks shouldn't contact the REST API themselves, that's not how it's meant to work. They update a data store that represents the post, then the editor uses that to save the post. To have a block that changes a custom table when it changes is very unusual, and probably not the ideal way to do things. Can you provide some background context so we know why you're doing this and how t's meant to work? Why do you need to change the custom table? What does the block do?
    – Tom J Nowell
    Commented Aug 11, 2020 at 22:43
  • Thanks for looking at this Tom. My blocks store quotes, names, dates, URLs, and other data. The data should be made available to other blocks in other pages. I've looked into other solutions, but keeping the data in the SQL database seems to be the least convoluted way. I'm open to other suggestions, but imho accessing the server from the blocks editor shouldn't be THAT hard. Commented Aug 12, 2020 at 0:43
  • If your data needs to be available on other pages, then I don't think your approach makes the most sense. Wether it's a CPT or rows in a table, you need to treat it more as an embed if you're going to take that approach. Making an editable block in a post that doesn't store its data in the post is not how it's meant to work. Look at how reusable blocks work ( reusable blocks would be a better way to implement this ). As for the REST API, I don't see why it's more complex, you make an AJAX request, but instead of sending it to an archaic admin-ajax.php you send it to a pretty wp-json/... url
    – Tom J Nowell
    Commented Aug 12, 2020 at 8:58
  • For saving data into a custom table though, you'll have to build it all from scratch. Aside from a handful of functions such as dbDelta and ways to make raw queries like wpdb, WP provides nothing for custom tables, no endpoints, no UI, etc, by choosing a custom table instead of a CPT you've chosen to do everythng from scratch
    – Tom J Nowell
    Commented Aug 12, 2020 at 9:00
  • Thanks Tom. I don't know what CPT or 'an embed' are. I've found the solution written below for the benefit of others. Is this the best solution? I don't know, but it works. Isn't this needlessly complex and horrendously low-level and error prone? Doesn't this ignore every principle of abstraction, encapsulation, and elegance learned through about 7 decades of programming languages? Sure but not more than everything else in WordPress. Which as a CMS, it sucks, but for many of us, we have no other choice. Commented Aug 14, 2020 at 13:20

1 Answer 1

0

I've found a solution using Ajax with native Javascript as follows:

// Filename send2server.js
const sendToServer = function() {
   /* Prepare the object to be sent: ********************************************************************/
   var params = new FormData();
   params.append('action',   'update_sql');                // update_sql is implemented in PHP (see below)
   params.append('quoteAtt', props.attributes.quoteAtt);   // The actual data

   /* Create the Ajax connection object: ****************************************************************/
   var request = new XMLHttpRequest();
   request.open('POST', ajax_object.ajax_url, true);       // ajax_object.ajax_url defined in PHP (below)
   request.send(params);                                   // Send request to server
}

On the server side, the following functions receive the request in the following manner:

// File plugin.php
function load_ajax_script() {
    wp_enqueue_script(
        'send2server',
        plugins_url( 'send2server.js', __FILE__ ),
        array(),
        filemtime( plugin_dir_path( __FILE__ ) . 'send2server.js' )
    );

    wp_localize_script(                                // make ajaxurl available to Javascript
        'send2server', 
        'ajax_object', 
        array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) 
    );  
}
add_action('init', 'load_ajax_script');


function update_sql() {                                // Invoked by request.send()
    $received = $_POST["quoteAtt"];                    // Contents of quoteAtt
    // ...
}
add_action('wp_ajax_update_sql', 'update_sql');        // 'update_sql' matches the 'action' in params

Is this the best solution? I don't know, but it works.

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.