Support

Account

Home Forums Gutenberg Get data from block in different page

Solving

Get data from block in different page

    • mattkr

    • March 16, 2019 at 1:45 am

    Hi,
    is it possible to get a data from registering block field (5.8-4beta) on any page?

    For example:

    • I’ve created Block “Contact” with fields email, phone, address
    • Create page template “Contact page” and add block “Contact” and fill fields.
    • I would like to add exactly the same data to the footer (on all pages)

    Is there any option to use get_field() function and retrieve data from “Contact page”, from first block “Contact”.

    I understand I can do that by get block ID.
    get_field('contact_block', 'block_5c8b98f36c5c7');

    But if someone remove this block and add again the same block type that my code won’t work.
    Is it any way to get block ID based on page ID? (Get first block from Contact page).

  • I’m also interested in an answer to this question.

    • dmchale

    • November 19, 2020 at 2:15 pm

    I know this is an older post but I was trying to do something similar this evening and had to figure it out myself, so I thought I’d share what I did. Hopefully it can help someone else, but apologies in advance for the lack of brevity.

    Before I go any further, I also want to clarify that this is a PARTIAL reply since it only addresses the OP’s primary question… “how do I find the block ID of a particular block in a specified post?” It’s important to note that get_field('contact_block', 'block_5c8b98f36c5c7'); is NOT valid ACF code and will NOT return ACF data from a specified block ID.

    Down to business.

    What I did was utilize the parse_blocks() function in order to return an object of blocks from a particular other post. The function takes the CONTENT of a page to parse, so I did this in one line like so.

    $post_blocks = parse_blocks( get_the_content( '', false, 166 ) );

    From there you can loop through the object and look at the information you have about each block. You can quickly short-circuit based on blocks that aren’t of the type you care about, or you can look at any other information about them. For example, I made an “intro-content” block and created a single ACF field of “color” which is a simple colorpicker.

    foreach ( $post_blocks as $block ) {
        if ( 'acf/intro-content' != $block['blockName'] ) {
            continue;   // Skip this block if it's not the right block type
        }
    
        if ( isset( $block['attrs']['id'] ) ) {
            $my_block_id = $block['attrs']['id'];
            break;  // Found a hit, get out of the loop
        }
    }

    This is what the individual block object looked like according to a var_dump(), to show what WordPress knows about that block and how/why I targeted things the way I did.

    array (size=5)
      'blockName' => string 'acf/intro-content' (length=17)
      'attrs' => 
        array (size=5)
          'id' => string 'block_5fb5d249c67e8' (length=19)
          'name' => string 'acf/intro-content' (length=17)
          'data' => 
            array (size=2)
              'color' => string '#1800d3' (length=7)
              '_color' => string 'field_5fb5d169b6174' (length=19)
          'align' => string '' (length=0)
          'mode' => string 'edit' (length=4)
      'innerBlocks' => 
        array (size=0)
          empty
      'innerHTML' => string '' (length=0)
      'innerContent' => 
        array (size=0)
          empty

    Putting it all together, this was a quick function that I wrote for getting back an array of block IDs which I could filter based on block type. It also lets you choose how many you want back (so you can tell it to stop after the first one, if you wanted).

    function custom_get_acf_block_ids_from_post( $post_id, $return_count = -1, $arr_block_types = array() ) {
        // If the post object doesn't even have any blocks, abort early and return an empty array
        if ( ! has_blocks( $post_id ) ) {
            return array();
        }
    
        // If $arr_block_types is not an array, add the param as the only element of an array. This lets us pass a string if we wanted
        if ( ! is_array( $arr_block_types ) ) {
    	    $arr_block_types = array( $arr_block_types );
        }
    
        // Only check the size of $arr_block_types once. Set a boolean so we know if we're filtering by block type or not
        $filter_block_types = ( 0 == count( $arr_block_types ) ) ? false : true;
    
        // Get our blocks from the post content of the post we're interested in
        $post_blocks = parse_blocks( get_the_content( '', false, $post_id ) );
    
        // Initialize some vars before we get into the loop
        $arr_return = array();
        $found_count = 0;
    
        // Loop through all the blocks
        foreach ( $post_blocks as $block ) {
    
            // Skip this item in the loop if the current block isn't one of the block types we're interested in
            if ( $filter_block_types && ! in_array( $block['blockName'], $arr_block_types ) ) {
                continue;
            }
    
            // Confirm the block we're looking at has an ID to return in the first place
            if ( isset( $block['attrs']['id'] ) ) {
    
                // Add this block ID to the return array
                $arr_return[] = $block['attrs']['id'];
    
                // Increment our found count, and see if we've found as many results as we wanted. Return early if so
                    $found_count++;
                    if ( $found_count == $return_count ) {
                        return $arr_return;
                    }
            }
        }
    
        // If we made it all the way here, return whatever we've found
        return $arr_return;
    
    }

    Which in my case, gave me back an array with just a single result based on the page I was looking at.

    array (size=1)
      0 => string 'block_5fb5d249c67e8' (length=19)

    So there you go! How to find block ID’s from a specified post/page ID.

    • dmchale

    • November 19, 2020 at 2:38 pm

    I wanted to post some additional information which would actually assist in how to accomplish the original intent… “how do I query for ACF fields attached to a specific block, by block ID?” I’ve written another function which can do exactly that for you, as long as you know the block ID AND THE POST ID that you’re querying. You can use it very similar to get_field(), but with a different 3rd (and in this case, required) parameter.

    function get_field_from_block( $selector, $post_id, $block_id ) {
        // If the post object doesn't even have any blocks, abort early and return false
        if ( ! has_blocks( $post_id ) ) {
            return false;
        }
    
        // Get our blocks from the post content of the post we're interested in
        $post_blocks = parse_blocks( get_the_content( '', false, $post_id ) );
    
        // Loop through all the blocks
        foreach ( $post_blocks as $block ) {
    
            // Only look at the block if it matches the $block_id
            if ( isset( $block['attrs']['id'] ) && $block_id == $block['attrs']['id'] ) {
    
                if ( isset( $block['attrs']['data'][$selector] ) ) {
                    return $block['attrs']['data'][$selector];
                } else {
                    break;  // If we found our block but didn't find the selector, abort the loop
                }
    
            }
    
        }
    
        // If we got here, we either didn't find the block by ID or we didn't find the selector by name
        return false;
    
    }
    • goldhat

    • November 26, 2020 at 5:04 am

    Very nice function @dmchale we have run into situations where we need this with some of the more advanced block types (that use templates made from Gutenberg blocks) for the ACF Engine project https://github.com/eatbuildplay/acfengine/.

    • goldhat

    • November 26, 2020 at 5:10 am

    I wonder if we could use this same approach but instead of 1 block to get the same field from all instances of a given block type, like get_field_block_type( $fieldKey, $blockType );

    It would look over the blocks, but then check for block type and when matching construct an array of the data like:

    function get_field_block_type( $fieldKey, $blockType ) {
      $data = [];
    
      // PARSE BLOCKS
    
      // LOOP OVER BLOCKS...
    
      if( $blockType == $block['type'] ) {
        $data[] = get_field( $fieldKey, $block['id'] );
      }
    
      // END BLOCK LOOP
    
      return $data;
    }
Viewing 6 posts - 1 through 6 (of 6 total)

You must be logged in to reply to this topic.

We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Cookie Policy. If you continue to use this site, you consent to our use of cookies.