Gutenberg Block (PHP) Conditions

Something to scrap the head around.

I’m creating a GB-Block which fetches Reviews (=posts) from a CPT. For some reason I thought it’s a cool Idea to show the posts in a flex/grid Layout on the frontend and to avoid missunderstanding (that something can be edited for example) I thought it would be cool to show a message in the backend (=editor) saying that this block shows dynamically all reviews on the frontend.

So what I did is the following:

  1. Creating my structure and add the Block-Action in PG
  2. Add the “PHP Code” Action to that block calling a function, lets call it showReviews() and ticked “echo” to true
  3. the function looks like the following:
    3.1 If-Condition which returns something like <div class="alert">See on frontend</div>
    3.2 Fetch all Posts from CPT
    3.3 Output them in a Loop

If 3.1 is true the function returns and doesn’t go to 3.2 & 3.3 … However, I found it quite tricky to impossible to check if the User is inside the block_editor or on the frontend!

I think it is about when the block code get’s fired, but I’m not that deep into Block-Development yet to know how to work around that.

What I’ve tried is the following:

if(is_admin()) return //alert-message
if(!is_admin()) {
//regular output
}
return //alert-message

After some research I found out that wp_admin() always returns false in block_editor (so no option)

Current-Screen

Always returned an error (undefined) message.

$_GET
Also tried to workaround with if(isset($_GET['post']))(for example) but that also didn’t work

So my question is:

Does anyone know a condition or faced a similar problem and can help out with the correct way to check inside the PHP-Code Action if I am inside the block-editor or not?

TIA for your help! :wink:

Cheers

That’s the code if someone wants to check it out. I’ve left out the current_screen thing here, but that didn’t work either :smiley:

function createRezContent() {
    $backend = false;


    // Always returns false in Gutenberg (so no option)
    if (!is_admin()) {
        echo '######################### ADMIN';
    }

    // didn't work
    if (isset($_GET['post']) || isset($_GET['post_type'])) {
        $backend = true;
    }

    // message to show if inside block-editor
    if ($backend) {
        return '<h2 class="text-bg-danger p-3">Hier werden im Frontend alle Bewertungen angezeigt!</h2>';
    }


    $args = [
        'post_type' => 'rezension',
        'posts_per_page' => -1
    ];

    
    $rezensionen = get_posts($args);
    $output = "";

    if (count($rezensionen) == 0) return;

    foreach ($rezensionen as $i => $rezension) {
        $icons = createStarIcons();
        $ort = rwmb_meta('rezensionen_ort', '', $rezension->ID);
        $ort = 'aus ' . $ort;

        $name = get_the_title($rezension->ID);
        $firma = rwmb_meta('rezensionen_firma', '', $rezension->ID);
        $content = rwmb_meta('rezensionen_content', '', $rezension->ID);


        $output .= "
        <div class='col-md-6'>
            <div class='bg-dark-lighter p-3'>
                {$icons}
                <p class='fw-bold mb-0 fs-5'>{$name} {$ort}</p>
                <p class='mb-3'>{$firma}</p>
                <p>{$content}</p>
            </div>
        </div>
        ";
    }

    return $output;
}

May be load a custom js in gutenberg block editor that generates a snackbar alert stating these blocks are not editable or something.

// Gutenberg editor customizations
function wolfgang_enqueue() {
    wp_enqueue_script( 'wolfgang-gutenberg-editor', get_template_directory_uri() . '/assets/js/wolfgang-gutenberg-editor.js', [ 'wp-edit-post', 'wp-dom-ready' ] );
}
add_action('enqueue_block_editor_assets', 'wolfgang_enqueue_enqueue');
const { select, subscribe, dispatch } = wp.data;

const closeListener = subscribe( () => {
	const isReady = select( 'core/editor' ).__unstableIsEditorReady();
	if ( ! isReady ) {
        // Editor not ready.
		return;
	}
	
	// Close the listener as soon as we know we are ready to avoid an infinite loop.
	closeListener();
	
  	// Your code is placed after this comment, once the editor is ready.

});

You can get the internal block id this way.

select("core/block-editor").getBlocks().forEach(function(block, blockIndex){
	if (block.name === "wolfgang/thistroublesomeblock"){
		mycustomblock = block['clientId'];
	}
});

Then may be you track interactions with that particular block before generating snackbar alert?Not sure what will be an efficient way to track the particular block.

How about adding a class around the item wrapper and creating an editor stylesheet that just hides it? Then, you can create a div that is hidden on the front-end but viewable in the back-end alerting editors that the block will dynamically pull data.

1 Like

Thanks for your Input @Pinegrow_Learner … I’ve thought about something similar too. My Girlfriend calls me “Toastmaster” since I always have the most imaginable fun implementing and creating different forms of snack/toastbars in my vue apps. But for some reason, I don’t like the approach of having a snackbar here, shame on me, I think the name is not justified! :smiley:

Also thanks to you @adamslowe for your answer. That definitely goes in the right decision. If I’m not able to solve the problem programmatically with the right PHP Hook I will probably give that a try… But I would find it so neat if I could manipulate the output of any PHP Block. That would open the door to soo many use-cases in my opinion!

I may have to revisit this topic when I have more time, but I really appreciate your point of views, many thanks for that!!

2 Likes