Skip to content

Commit

Permalink
Refactor: Dynamic tag parser
Browse files Browse the repository at this point in the history
  • Loading branch information
tomusborne committed Nov 27, 2024
1 parent 033b6e8 commit efc7962
Showing 1 changed file with 83 additions and 144 deletions.
227 changes: 83 additions & 144 deletions includes/dynamic-tags/class-register-dynamic-tag.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public function __construct( $args ) {
* @return array
*/
private static function parse_options( $options_string, $tag_name ) {
$pairs = explode( '|', $options_string );
$pairs = $options_string ? explode( '|', $options_string ) : [];
$result = [
'tag_name' => $tag_name, // Make it so the tag name is available to us in $options.
];
Expand Down Expand Up @@ -88,154 +88,93 @@ public static function get_tags() {
* @return string
*/
public static function replace_tags( $content, $block, $instance ) {
foreach ( self::$tags as $tag_name => $data ) {
$opening_tag = '{{' . $tag_name;

if ( ! generateblocks_str_contains( $content, $opening_tag ) ) {
continue;
}

$full_tag = $opening_tag . '}}';
$supports = $data['supports'];

if ( generateblocks_str_contains( $content, $full_tag ) ) {
$full_tag = self::maybe_prepend_protocol( $content, $full_tag );
$replacement = $data['return']( [], $block, $instance );
$og_replacement = $replacement; // Keep a copy of this in case it's manipulated via filter.

/**
* Allow developers to filter the replacement.
*
* @since 2.0.0
*
* @param string $replacement The replacement.
* @param string $full_tag The full tag.
* @param mixed $content The replacement.
* @param array $block The block.
* @param Object $instance The block instance.
*/
$replacement = apply_filters(
'generateblocks_dynamic_tag_replacement',
$replacement,
[
'full_tag' => $full_tag,
'tag' => $tag_name,
'content' => $content,
'block' => $block,
'instance' => $instance,
'supports' => $supports,
'options' => [],
]
);

// Tags are required to have a value by default. Since this tag has no options,
// we can remove the block and break out of the loop if there is no replacement.
if ( ! $replacement ) {
$content = '';
break;
}

/**
* Allow developers to filter the content before dynamic tag replacement.
*
* @since 2.0.0
*
* @param string $content The content.
* @param string $full_tag The full tag.
* @param mixed $replacement The replacement.
* @param array $block The block.
* @param Object $instance The block instance.
*/
$content = apply_filters(
'generateblocks_before_dynamic_tag_replace',
$content,
[
'tag' => $tag_name,
'full_tag' => $full_tag,
'replacement' => $replacement,
'og_replacement' => $og_replacement,
'block' => $block,
'instance' => $instance,
'supports' => $supports,
'options' => [],
]
);

$content = str_replace( $full_tag, (string) $replacement, $content );
} else {
$pattern = '/\{{' . $tag_name . '(\s+([^}]+))*\}}/';
preg_match_all( $pattern, $content, $matches, PREG_SET_ORDER );

foreach ( $matches as $match ) {
$full_tag = $match[0];
$full_tag = self::maybe_prepend_protocol( $content, $full_tag );
$options_string = $match[2] ?? '';
$options = self::parse_options( $options_string, $tag_name );
$replacement = $data['return']( $options, $block, $instance );
$og_replacement = $replacement; // Keep a copy of this in case it's manipulated via filter.
$required = isset( $options['required'] ) && 'false' === $options['required'] ? false : true;
if ( ! generateblocks_str_contains( $content, '{{' ) ) {
return $content;
}

/**
* Allow developers to filter the replacement.
*
* @since 2.0.0
*
* @param string $replacement The replacement.
* @param string $full_tag The full tag.
* @param mixed $content The replacement.
* @param array $block The block.
* @param Object $instance The block instance.
*/
$replacement = apply_filters(
'generateblocks_dynamic_tag_replacement',
$replacement,
[
'tag' => $tag_name,
'full_tag' => $full_tag,
'content' => $content,
'block' => $block,
'instance' => $instance,
'options' => $options,
'supports' => $supports,
]
);
$pattern = '/\{{(' . implode( '|', array_keys( self::$tags ) ) . ')(\s+[^}]+)?}}/';
preg_match_all( $pattern, $content, $matches, PREG_SET_ORDER );

// If this tag is required for the block to render and there is no replacement,
// we can remove the block and break out of the loop.
if ( $required && ! $replacement ) {
$content = '';
break;
}
foreach ( $matches as $match ) {
$tag_name = $match[1] ?? '';

/**
* Allow developers to filter the content before dynamic tag replacement.
*
* @since 2.0.0
*
* @param string $content The content.
* @param string $full_tag The full tag.
* @param mixed $replacement The replacement.
* @param array $block The block.
* @param Object $instance The block instance.
*/
$content = apply_filters(
'generateblocks_before_dynamic_tag_replace',
$content,
[
'full_tag' => $full_tag,
'tag' => $tag_name,
'replacement' => $replacement,
'og_replacement' => $og_replacement,
'block' => $block,
'instance' => $instance,
'options' => $options,
'supports' => $supports,
]
);
if ( ! isset( self::$tags[ $tag_name ] ) ) {
continue;
}

$content = str_replace( $full_tag, (string) $replacement, $content );
}
$data = self::$tags[ $tag_name ];
$full_tag = $match[0];
$full_tag = self::maybe_prepend_protocol( $content, $full_tag );
$options_string = isset( $match[2] ) ? trim( $match[2], ' ' ) : '';
$options = self::parse_options( $options_string, $tag_name );
$replacement = $data['return']( $options, $block, $instance );
$og_replacement = $replacement;
$supports = $data['supports'];
$required = ! isset( $options['required'] ) || 'false' !== $options['required'];

/**
* Allow developers to filter the replacement.
*
* @since 2.0.0
*
* @param string $replacement The replacement.
* @param string $full_tag The full tag.
* @param mixed $content The replacement.
* @param array $block The block.
* @param Object $instance The block instance.
* @param array $options The options.
* @param array $supports The supports.
*/
$replacement = apply_filters(
'generateblocks_dynamic_tag_replacement',
$replacement,
[
'tag' => $tag_name,
'full_tag' => $full_tag,
'content' => $content,
'block' => $block,
'instance' => $instance,
'options' => $options,
'supports' => $supports,
]
);

// If this tag is required for the block to render and there is no replacement, bail.
if ( $required && ! $replacement ) {
return '';
}

/**
* Allow developers to filter the content before dynamic tag replacement.
*
* @since 2.0.0
*
* @param string $content The content.
* @param string $full_tag The full tag.
* @param string $tag The tag.
* @param mixed $replacement The replacement.
* @param mixed $og_replacement The original replacement.
* @param array $block The block.
* @param Object $instance The block instance.
* @param array $options The options.
* @param array $supports The supports.
*/
$content = apply_filters(
'generateblocks_before_dynamic_tag_replace',
$content,
[
'full_tag' => $full_tag,
'tag' => $tag_name,
'replacement' => $replacement,
'og_replacement' => $og_replacement,
'block' => $block,
'instance' => $instance,
'options' => $options,
'supports' => $supports,
]
);

$content = str_replace( $full_tag, (string) $replacement, $content );
}

return $content;
Expand Down

0 comments on commit efc7962

Please sign in to comment.