2

I am new to wordpress development so i am struggling with the following problem:

We want to create a custom block in wordpress that gets data from an api endpoint and displays it inside of a richtext by replacing placeholders with the data from that api.

You can assume that we know how to do these things:

  • How to replace the placeholders in the text with data.
  • How to write a shortcode plugin in wordpress (we already did that and it works)
  • The shortcode always returns an associative array

The data should be fetched everytime the blog article is rendered. The text needs to be server side rendered for SEO purposes so we want to call the api on the php server. In other words: it always needs to be up to date.

The block should have two fields to customize it:

  1. a text field expecting a shortcode which will be executed to get the data everytime that block is rendered on the server.
  2. a richtext field, that expects a richtext which will be rendered on the page and use the data provided by executing the shortcode.

First I tried to create a dynamic block in wordpress, because i think this is the way to get data everytime the block is requested. For that i used the npm package @wordpress/create-block (v 4.22.0) with the option dynamic-block. I now have an edit component that looks like this

export default function Edit({attributes, setAttributes }) {
 const setText = (val) => setAttributes({text:val});
 const setShortCode = (val) => setAttributes({apiShortcode:val});
    return (
        <div { ...useBlockProps() }>
   <h3>My Comp</h3>
            <PlainText onChange={setShortCode} value={attributes.apiShortcode}/>
   <RichText onChange={setText} value={attributes.text}/>
        </div>
    );
}

In my block.json i defined them like this:

"attributes": {
    "apiShortcode": {
        "type": "string",
        "source": "text"
    },
    "text": {
        "type": "string",
        "source": "html"
    }
},

Now i need to get the shortcode from the attributes and execute it on the server. However i am stuck on this. My problems combine so many wordpress concepts that it is too much too handle for my brain the first time.

My php code is still the default generated php code:

<?php
function my_block_text_block_init() {
    register_block_type( __DIR__ . '/build' );
}
add_action( 'init', 'my_block_text_block_init' );

How can i access the two attributes from the edit function?

Also - does this approach make sense or did i overlook something? Or is there something better?

Christian
  • 31
  • 4
  • Do you want to hit your API endpoint from your Javascript block code running in your users' browsers, or from php code running on your server? Please [edit] your question to explain further. If the latter is true you could implement an old-school non-block plugin with a straightforward shortcode. – O. Jones Aug 24 '23 at 11:14
  • I updated the description and yes i need it to be rendered on the server. I needed a block so the editors can write a long text with multiple paragraphs. I could not find a way on how to do this with a short code. Getting the data via shortcode is not a problem (that already works) but i somehow need to get that data into an editable richtext. – Christian Aug 24 '23 at 12:07

1 Answers1

1

To fix this, I added a render_callback function and registered it to the block. The $block_attributes parameter only is filled when I provide my attributes in php code too - not only in the blocks.json file.

function render_callback( $block_attributes, $content ) {
    $apiCode = $block_attributes["apiShortcode"];
    $data = do_shortcode($apiCode);
    $richText = $block_attributes["text"];
    return sprintf(
        '<div class="data-wrapper" >
                    <p>My Block</p>
                    <div class="my-data" >%s</div>
                    <div>data: %s</div>
                </div>',$richText, $data
    );
}

function my_plugin_text_block_init() {
    register_block_type_from_metadata(
        __DIR__ . '/build',
        [
            'render_callback' => 'render_callback',
            'attributes'        => [
                'apiShortcode'   => ['type' => 'string' ],
                'text' => ['type' => 'string' ],
            ],

        ]
    );
}

add_action( 'init', 'my_plugin_text_block_init' );
FluffyKitten
  • 13,824
  • 10
  • 39
  • 52
Christian
  • 31
  • 4