Skip to content

Commit

Permalink
Merge pull request #78 from alleyinteractive/feature/issue-64/extract…
Browse files Browse the repository at this point in the history
…-pre-render-block-logic

Issue-64: extract pre_render_block logic
  • Loading branch information
anubisthejackle authored May 16, 2024
2 parents 88ca43d + 3151524 commit 8080928
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 81 deletions.
35 changes: 7 additions & 28 deletions blocks/is-false/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
* @package wp-conditional-blocks
*/

use function Alley\WP\WP_Conditional_Blocks\is_active_block;
use function Alley\WP\WP_Conditional_Blocks\is_active_parent_block;
use function Alley\WP\WP_Conditional_Blocks\on_bool;
use function Alley\WP\WP_Conditional_Blocks\pre_render_on_bool;

/**
* Registers the block using the metadata loaded from the `block.json` file.
* Behind the scenes, it registers also all assets so they can be enqueued
Expand All @@ -27,36 +32,10 @@ function wp_conditional_blocks_is_false_block_init(): void {
* Short-circuit the display of blocks inside if the outer condition isn't false.
*
* @param string|null $pre_render The pre-rendered content. Default null.
* @param WP_Block $parsed_block The block being rendered.
* @param mixed[] $parsed_block The block being rendered.
* @param WP_Block|null $parent_block If this is a nested block, a reference to the parent block.
*/
function wp_conditional_blocks_pre_render_is_false_block( $pre_render, $parsed_block, $parent_block ): string|null {
/*
* Previously, the condition block added 'conditionResult' as context to this block. However,
* limitations in the context API meant that the context didn't get passed to child blocks when
* the condition block was itself a child block. We now pass the condition block back to a
* separate function that lives outside the context API and evaluates the result.
*/
if (
isset( $parsed_block['blockName'] )
&& 'wp-conditional-blocks/is-false' === $parsed_block['blockName']
&& $parent_block instanceof WP_Block
&& isset( $parent_block->parsed_block['blockName'] )
&& 'wp-conditional-blocks/condition' === $parent_block->parsed_block['blockName']
) {
$context = [];

if ( isset( $parent_block->context['postId'] ) ) {
$context['postId'] = $parent_block->context['postId'];
}

$result = wp_conditional_blocks_condition_block_result( $parent_block->parsed_block, $context );

if ( false !== $result ) {
$pre_render = '';
}
}

return $pre_render;
return pre_render_on_bool( 'wp-conditional-blocks/is-false', false, $pre_render, $parsed_block, $parent_block );
}
add_filter( 'pre_render_block', 'wp_conditional_blocks_pre_render_is_false_block', 10, 3 );
35 changes: 7 additions & 28 deletions blocks/is-true/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
* @package wp-conditional-blocks
*/

use function Alley\WP\WP_Conditional_Blocks\is_active_block;
use function Alley\WP\WP_Conditional_Blocks\is_active_parent_block;
use function Alley\WP\WP_Conditional_Blocks\on_bool;
use function Alley\WP\WP_Conditional_Blocks\pre_render_on_bool;

/**
* Registers the block using the metadata loaded from the `block.json` file.
* Behind the scenes, it registers also all assets so they can be enqueued
Expand All @@ -27,36 +32,10 @@ function wp_conditional_blocks_is_true_block_init(): void {
* Short-circuit the display of blocks inside if the outer condition isn't true.
*
* @param string|null $pre_render The pre-rendered content. Default null.
* @param WP_Block $parsed_block The block being rendered.
* @param mixed[] $parsed_block The block being rendered.
* @param WP_Block|null $parent_block If this is a nested block, a reference to the parent block.
*/
function wp_conditional_blocks_pre_render_is_true_block( $pre_render, $parsed_block, $parent_block ): string|null {
/*
* Previously, the condition block added 'conditionResult' as context to this block. However,
* limitations in the context API meant that the context didn't get passed to child blocks when
* the condition block was itself a child block. We now pass the condition block back to a
* separate function that lives outside the context API and evaluates the result.
*/
if (
isset( $parsed_block['blockName'] )
&& 'wp-conditional-blocks/is-true' === $parsed_block['blockName']
&& $parent_block instanceof WP_Block
&& isset( $parent_block->parsed_block['blockName'] )
&& 'wp-conditional-blocks/condition' === $parent_block->parsed_block['blockName']
) {
$context = [];

if ( isset( $parent_block->context['postId'] ) ) {
$context['postId'] = $parent_block->context['postId'];
}

$result = wp_conditional_blocks_condition_block_result( $parent_block->parsed_block, $context );

if ( true !== $result ) {
$pre_render = '';
}
}

return $pre_render;
return pre_render_on_bool( 'wp-conditional-blocks/is-true', true, $pre_render, $parsed_block, $parent_block );
}
add_filter( 'pre_render_block', 'wp_conditional_blocks_pre_render_is_true_block', 10, 3 );
97 changes: 97 additions & 0 deletions src/helpers.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php
/**
* Contains helper functions to be used elsewhere in the plugin.
*
* @package wp-conditional-blocks
*/

namespace Alley\WP\WP_Conditional_Blocks;

use WP_Block;

/**
* Check if the defined block is the active block. Useful in pre_render_block
* callbacks.
*
* @param string $block_name The block name to look for. Should be the full namespace.
* @param mixed[]|null $parsed_block The parsed block array, or null.
* @return bool
*/
function is_active_block( string $block_name, ?array $parsed_block ): bool {
if ( ! isset( $parsed_block['blockName'] ) ) {
return false;
}

return $block_name === $parsed_block['blockName'];
}

/**
* Check if the defined block is the active parent block. Useful in pre_render_block
* callbacks.
*
* @param string $block_name The block name to look for. Should be the full namespace.
* @param WP_Block|null $parent_block The parent block to check.
* @return bool
*/
function is_active_parent_block( string $block_name, ?WP_Block $parent_block ): bool {
if ( ! ( $parent_block instanceof WP_Block ) ) {
return false;
}

return is_active_block( $block_name, $parent_block->parsed_block );
}

/**
* Handles performing a callback when a condition block returns the expected result.
*
* @param bool $result The expected result of the evaluation.
* @param WP_Block $parent_block The parent block object.
* @param callable $callback The callback to execute on true.
* @param mixed[] ...$args An array of arguments passed to the callback function.
*/
function on_bool( bool $result, WP_Block $parent_block, callable $callback, ...$args ): void {
$context = [];

if ( isset( $parent_block->context['postId'] ) ) {
$context['postId'] = $parent_block->context['postId'];
}

if ( wp_conditional_blocks_condition_block_result( $parent_block->parsed_block, $context ) === $result ) {
$callback( ...$args );
}
}

/**
* A filter used by both the is-true and is-false blocks to filter their render content,
* and either show or hide it based on the result.
*
* @param string $block_name The block name to run on.
* @param bool $bool True or false. The expected value of the evaluation.
* @param string|null $pre_render The pre-rendered content. Default null.
* @param mixed[] $parsed_block The block being rendered.
* @param WP_Block|null $parent_block If this is a nested block, a reference to the parent block.
*/
function pre_render_on_bool( string $block_name, bool $bool, $pre_render, $parsed_block, $parent_block ): string|null {
/*
* Previously, the condition block added 'conditionResult' as context to this block. However,
* limitations in the context API meant that the context didn't get passed to child blocks when
* the condition block was itself a child block. We now pass the condition block back to a
* separate function that lives outside the context API and evaluates the result.
*/
if (
is_active_block( $block_name, $parsed_block )
&& is_active_parent_block( 'wp-conditional-blocks/condition', $parent_block )
) {
$context = [];

if ( isset( $parent_block->context['postId'] ) ) {
$context['postId'] = $parent_block->context['postId'];
}

if ( wp_conditional_blocks_condition_block_result( $parent_block->parsed_block, $context ) !== $bool ) { // @phpstan-ignore-line
$pre_render = '';
}
}

return $pre_render;
}
25 changes: 0 additions & 25 deletions tests/feature/class-example-feature-test.php

This file was deleted.

51 changes: 51 additions & 0 deletions tests/feature/class-true-false-block-test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php
/**
* WP Conditional Blocks Tests: Is True and Is False Block Feature Tests
*
* @package wp-conditional-blocks
*/

namespace Alley\WP\WP_Conditional_Blocks\Tests\Feature;

use Alley\WP\WP_Conditional_Blocks\Conditions;
use Alley\WP\WP_Conditional_Blocks\Tests\Test_Case;

/**
* A test suite for the is-true and is-false blocks.
*
* @link https://mantle.alley.com/testing/test-framework.html
*/
class True_False_Block_Test extends Test_Case {

/**
* Verifies that the is-true block renders, while the is-false block does not render,
* when a condition returns true.
*
* @test
*/
public function test_is_true_and_is_false_render_block_as_expected() {
$post = self::factory()->post->as_models()->create_and_get(
[
'post_content' => <<<HTML
<!-- wp:wp-conditional-blocks/condition {"post":"","query":"is_single"} -->
<div class="wp-block-wp-conditional-blocks-condition"><!-- wp:wp-conditional-blocks/is-true -->
<div class="wp-block-wp-conditional-blocks-is-true"><!-- wp:paragraph -->
<p>This is an is_single page.</p>
<!-- /wp:paragraph --></div>
<!-- /wp:wp-conditional-blocks/is-true -->
<!-- wp:wp-conditional-blocks/is-false -->
<div class="wp-block-wp-conditional-blocks-is-false"><!-- wp:paragraph -->
<p>This is NOT an is_single page.</p>
<!-- /wp:paragraph --></div>
<!-- /wp:wp-conditional-blocks/is-false --></div>
<!-- /wp:wp-conditional-blocks/condition -->
HTML,
]
);

$this->get( $post->permalink() )
->assertSee( 'This is an is_single page.' )
->assertDontSee( 'This is NOT an is_single page.' );
}
}
1 change: 1 addition & 0 deletions wp-conditional-blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ function () {
}

// Load the plugin's main files.
require_once __DIR__ . '/src/helpers.php';
require_once __DIR__ . '/src/assets.php';
require_once __DIR__ . '/src/class-conditions.php';
require_once __DIR__ . '/src/class-endpoints.php';
Expand Down

0 comments on commit 8080928

Please sign in to comment.