0

I need to return all posts that have the value of a specific attribute that is saved in the custom block attributes gutenberg. This value in the query will be according to the endpoint below.

http://idinheiro.local/wp-json/idinheiro/v1/blocks-posts/id-here-attribute-gutenberg-block

below my callback function. In short, how do I look for this attribute and put it there in get_posts?

Register routers

public function register_routes() {
        $namespace = 'idinheiro/v1';
        $path = 'blocks-posts';

        register_rest_route( $namespace, '/' . $path . '/(?P<id>[A-Za-z0-9_-]+)', [
            [
                'methods'             => 'GET',
                'callback'            => [$this, 'get_items'],
                'permission_callback' => [$this, 'get_items_permissions_check'],
            ],
        ]); 
    }

Response data

public function get_items($request) {
        $args = [
            'post_status' => 'publish',
            'post_type' => 'post',
            's' => 'cgb/block-idinheiro-blocks',
        ];

        $posts = get_posts($args);

        if (empty($posts)) {
            return new WP_Error( 'empty_post', 'there is no blocks inside on posts', [ 'status' => 404 ] );
        }

        $data = [];
        $i = 0;

        foreach ($posts as $post) {
            $data[$i]['id'] = $request['id'];
            $data[$i]['post_id'] = $post->ID;
            $data[$i]['post_name'] = $post->post_title;
            $data[$i]['post_url'] = get_permalink($post->ID);
            $i++;
        }

        wp_reset_postdata();

        return new WP_REST_Response($data, 200);
    }

I thought of something that went something like this. Or if you have another solution on how to get this, I'll be grateful

$args = [
            'post_status' => 'publish',
            'post_type' => 'post',
            's' => 'cgb/block-idinheiro-blocks',
            'value_attribute_my_block' = $request['id']
        ];

        $posts = get_posts($args);
1
  • what are you trying to achieve that requires this? This particular approach is a dead end that will not work, block attributes can't be queried like this, they're not supposed to. But perhaps there's an easier alternative
    – Tom J Nowell
    Aug 2, 2021 at 20:35

1 Answer 1

1

You don't. That's not how block attributes work, and it's not what they're for.

A blocks attributes belong to that block, and are used by the editor to generate that blocks HTML, but once they're saved in the database, they're just HTML. There's no block table, no mapping/index of block attributes in the database, post content is just post content.

For this reason, querying posts by the attributes on their blocks is equivalent to querying posts by the parameters on their shortcodes, or the attributes on a hyperlink. It doesn't make sense, it's not what they were intended for, you've made a mistake.

Instead, if you want to query for posts with X or Y or Z, you need a taxonomy. Post meta works too but has major performance costs. Block attributes don't.


The best you can do, the closest you can get, is to fetch all posts, load them all into memory at the same time, parse their post content into blocks, process those blocks to find the block type you're looking for, check it's attributes, and add it to a list.

This will be very slow, limit the number of concurrent visitors to less than a handful, and will cap the maximum number of posts on your site to less than 100. Any more and major performance and scaling issues will occur, you run the risk of out of memory errors, or out of time errors.

Your Answer

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

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