PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / 1.5.2
GenerateBlocks v1.5.2
trunk 1.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.7.0 1.7.1 1.7.2 1.7.3 1.8.0 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 2.0.0 2.0.1 2.0.2 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.3.0
generateblocks / includes / class-render-blocks.php
generateblocks / includes Last commit date
class-do-css.php 4 years ago class-dynamic-content.php 4 years ago class-enqueue-css.php 4 years ago class-legacy-attributes.php 4 years ago class-plugin-update.php 5 years ago class-query-loop.php 4 years ago class-render-blocks.php 4 years ago class-rest.php 4 years ago class-settings.php 4 years ago dashboard.php 4 years ago defaults.php 4 years ago functions.php 4 years ago general.php 4 years ago generate-css.php 4 years ago
class-render-blocks.php
860 lines
1 <?php
2 /**
3 * This file handles the dynamic parts of our blocks.
4 *
5 * @package GenerateBlocks
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit; // Exit if accessed directly.
10 }
11
12 /**
13 * Render the dynamic aspects of our blocks.
14 *
15 * @since 1.2.0
16 */
17 class GenerateBlocks_Render_Block {
18 /**
19 * Instance.
20 *
21 * @access private
22 * @var object Instance
23 * @since 1.2.0
24 */
25 private static $instance;
26
27 /**
28 * Initiator.
29 *
30 * @since 1.2.0
31 * @return object initialized object of class.
32 */
33 public static function get_instance() {
34 if ( ! isset( self::$instance ) ) {
35 self::$instance = new self();
36 }
37
38 return self::$instance;
39 }
40
41 /**
42 * Constructor.
43 */
44 public function __construct() {
45 add_action( 'init', array( $this, 'register_blocks' ) );
46
47 if ( version_compare( $GLOBALS['wp_version'], '5.9', '>' ) ) {
48 add_filter( 'render_block', array( $this, 'filter_rendered_blocks' ), 10, 3 );
49 }
50 }
51
52 /**
53 * Register our dynamic blocks.
54 *
55 * @since 1.2.0
56 */
57 public function register_blocks() {
58 register_block_type(
59 'generateblocks/container',
60 array(
61 'title' => esc_html__( 'Container', 'generateblocks' ),
62 'render_callback' => array( $this, 'do_container_block' ),
63 'editor_script' => 'generateblocks',
64 'editor_style' => 'generateblocks',
65 )
66 );
67
68 register_block_type(
69 'generateblocks/grid',
70 array(
71 'title' => esc_html__( 'Grid', 'generateblocks' ),
72 'render_callback' => array( $this, 'do_grid_block' ),
73 'uses_context' => array(
74 'generateblocks/query',
75 'generateblocks/queryId',
76 ),
77 )
78 );
79
80 register_block_type(
81 'generateblocks/query-loop',
82 array(
83 'title' => esc_html__( 'Query loop', 'generateblocks' ),
84 'render_callback' => array( $this, 'do_grid_block' ),
85 'provides_context' => array(
86 'generateblocks/query' => 'query',
87 'generateblocks/queryId' => 'uniqueId',
88 'generateblocks/inheritQuery' => 'inheritQuery',
89 ),
90 )
91 );
92
93 register_block_type(
94 'generateblocks/button-container',
95 array(
96 'title' => esc_html__( 'Buttons', 'generateblocks' ),
97 'render_callback' => array( $this, 'do_button_container' ),
98 )
99 );
100
101 register_block_type(
102 'generateblocks/headline',
103 array(
104 'title' => esc_html__( 'Headline', 'generateblocks' ),
105 'render_callback' => array( $this, 'do_headline_block' ),
106 )
107 );
108
109 register_block_type(
110 'generateblocks/button',
111 array(
112 'title' => esc_html__( 'Button', 'generateblocks' ),
113 'render_callback' => array( $this, 'do_button_block' ),
114 'uses_context' => array(
115 'generateblocks/query',
116 'generateblocks/queryId',
117 'generateblocks/inheritQuery',
118 ),
119 )
120 );
121
122 register_block_type(
123 GENERATEBLOCKS_DIR . 'dist/blocks/image',
124 array(
125 'title' => esc_html__( 'Image', 'generateblocks' ),
126 'render_callback' => array( $this, 'do_image_block' ),
127 'uses_context' => array(
128 'generateblocks/query',
129 'generateblocks/queryId',
130 'postType',
131 'postId',
132 ),
133 )
134 );
135 }
136
137 /**
138 * Output the dynamic aspects of our Container block.
139 *
140 * @since 1.2.0
141 * @param array $attributes The block attributes.
142 * @param string $content The inner blocks.
143 * @param object $block The block data.
144 */
145 public function do_container_block( $attributes, $content, $block ) {
146 if ( ! isset( $attributes['isDynamic'] ) || ! $attributes['isDynamic'] ) {
147 return $content;
148 }
149
150 $defaults = generateblocks_get_block_defaults();
151
152 $settings = wp_parse_args(
153 $attributes,
154 $defaults['container']
155 );
156
157 $output = '';
158
159 if ( $settings['isGrid'] ) {
160 $gridItemClassNames = array(
161 'gb-grid-column',
162 'gb-grid-column-' . $settings['uniqueId'],
163 );
164
165 $output .= sprintf(
166 '<div %s>',
167 generateblocks_attr(
168 'grid-item',
169 array(
170 'class' => implode( ' ', $gridItemClassNames ),
171 ),
172 $settings,
173 $block
174 )
175 );
176 }
177
178 $classNames = array(
179 'gb-container',
180 'gb-container-' . $settings['uniqueId'],
181 );
182
183 if ( ! empty( $settings['className'] ) ) {
184 $classNames[] = $settings['className'];
185 }
186
187 if ( ! $settings['isGrid'] && ! empty( $settings['align'] ) ) {
188 $classNames[] = 'align' . $settings['align'];
189 }
190
191 // Pass the dynamic url to our URL attribute.
192 if ( isset( $settings['url'] ) ) {
193 if ( $settings['useDynamicData'] && '' !== $settings['dynamicLinkType'] ) {
194 $attributes['url'] = GenerateBlocks_Dynamic_Content::get_dynamic_url( $settings, $block );
195 }
196 }
197
198 $tagName = apply_filters(
199 'generateblocks_container_tagname',
200 $settings['tagName'],
201 $attributes,
202 $block
203 );
204
205 $allowedTagNames = apply_filters(
206 'generateblocks_container_allowed_tagnames',
207 array(
208 'div',
209 'section',
210 'header',
211 'footer',
212 'aside',
213 'a',
214 ),
215 $attributes,
216 $block
217 );
218
219 if ( ! in_array( $tagName, $allowedTagNames ) ) {
220 $tagName = 'div';
221 }
222
223 $output .= sprintf(
224 '<%1$s %2$s>',
225 $tagName,
226 generateblocks_attr(
227 'container',
228 array(
229 'id' => isset( $settings['anchor'] ) ? $settings['anchor'] : null,
230 'class' => implode( ' ', $classNames ),
231 ),
232 $settings,
233 $block
234 )
235 );
236
237 $output = apply_filters(
238 'generateblocks_after_container_open',
239 $output,
240 $attributes,
241 $block
242 );
243
244 $output .= '<div class="gb-inside-container">';
245
246 $output = apply_filters(
247 'generateblocks_inside_container',
248 $output,
249 $attributes,
250 $block
251 );
252
253 $output .= $content;
254 $output .= '</div>';
255
256 $output = apply_filters(
257 'generateblocks_before_container_close',
258 $output,
259 $attributes,
260 $block
261 );
262
263 $output .= sprintf(
264 '</%s>',
265 $tagName
266 );
267
268 if ( $settings['isGrid'] ) {
269 $output .= '</div>';
270 }
271
272 return $output;
273 }
274
275 /**
276 * Output the dynamic aspects of our Grid block.
277 *
278 * @since 1.2.0
279 * @param array $attributes The block attributes.
280 * @param string $content The inner blocks.
281 * @param object $block The block data.
282 */
283 public function do_grid_block( $attributes, $content, $block ) {
284 if ( ! isset( $attributes['isDynamic'] ) || ! $attributes['isDynamic'] ) {
285 return $content;
286 }
287
288 $defaults = generateblocks_get_block_defaults();
289
290 $settings = wp_parse_args(
291 $attributes,
292 $defaults['gridContainer']
293 );
294
295 $classNames = array(
296 'gb-grid-wrapper',
297 'gb-grid-wrapper-' . $settings['uniqueId'],
298 );
299
300 if ( ! empty( $settings['className'] ) ) {
301 $classNames[] = $settings['className'];
302 }
303
304 $output = sprintf(
305 '<div %s>',
306 generateblocks_attr(
307 'grid-wrapper',
308 array(
309 'id' => isset( $settings['anchor'] ) ? $settings['anchor'] : null,
310 'class' => implode( ' ', $classNames ),
311 ),
312 $settings,
313 $block
314 )
315 );
316
317 if ( empty( $attributes['isQueryLoop'] ) ) {
318 $output .= $content;
319 } else {
320 $output .= $this->do_post_template( $attributes, $content, $block );
321 }
322
323 $output .= '</div>';
324
325 return $output;
326 }
327
328 /**
329 * Output the dynamic aspects of our Button Container block.
330 *
331 * @since 1.2.0
332 * @param array $attributes The block attributes.
333 * @param string $content The inner blocks.
334 * @param object $block The block data.
335 */
336 public function do_button_container( $attributes, $content, $block ) {
337 if ( ! isset( $attributes['isDynamic'] ) || ! $attributes['isDynamic'] ) {
338 return $content;
339 }
340
341 if ( isset( $block->parsed_block['innerBlocks'] ) ) {
342 $button_count = apply_filters(
343 'generateblocks_button_count',
344 count( (array) $block->parsed_block['innerBlocks'] ),
345 $attributes,
346 $block
347 );
348
349 if ( 0 === $button_count ) {
350 return;
351 }
352 }
353
354 $defaults = generateblocks_get_block_defaults();
355
356 $settings = wp_parse_args(
357 $attributes,
358 $defaults['buttonContainer']
359 );
360
361 $classNames = array(
362 'gb-button-wrapper',
363 'gb-button-wrapper-' . $settings['uniqueId'],
364 );
365
366 if ( ! empty( $settings['className'] ) ) {
367 $classNames[] = $settings['className'];
368 }
369
370 $output = sprintf(
371 '<div %s>',
372 generateblocks_attr(
373 'button-container',
374 array(
375 'id' => isset( $settings['anchor'] ) ? $settings['anchor'] : null,
376 'class' => implode( ' ', $classNames ),
377 ),
378 $settings,
379 $block
380 )
381 );
382
383 $output .= $content;
384
385 $output .= '</div>';
386
387 return $output;
388 }
389
390 /**
391 * Output the query.
392 *
393 * @param array $attributes The block attributes.
394 * @param string $content The inner blocks.
395 * @param WP_Block $block Block instance.
396 */
397 public function do_post_template( $attributes, $content, $block ) {
398 $page_key = isset( $block->context['generateblocks/queryId'] ) ? 'query-' . $block->context['generateblocks/queryId'] . '-page' : 'query-page';
399 $page = empty( $_GET[ $page_key ] ) ? 1 : (int) $_GET[ $page_key ]; // phpcs:ignore -- No data processing happening.
400 $query_args = GenerateBlocks_Query_Loop::get_query_args( $block, $page );
401
402 // Override the custom query with the global query if needed.
403 $use_global_query = ( isset( $block->context['generateblocks/inheritQuery'] ) && $block->context['generateblocks/inheritQuery'] );
404
405 if ( $use_global_query ) {
406 global $wp_query;
407
408 if ( $wp_query && isset( $wp_query->query_vars ) && is_array( $wp_query->query_vars ) ) {
409 // Unset `offset` because if is set, $wp_query overrides/ignores the paged parameter and breaks pagination.
410 unset( $query_args['offset'] );
411 $query_args = wp_parse_args( $wp_query->query_vars, $query_args );
412
413 if ( empty( $query_args['post_type'] ) && is_singular() ) {
414 $query_args['post_type'] = get_post_type( get_the_ID() );
415 }
416 }
417 }
418
419 $query_args = apply_filters(
420 'generateblocks_query_loop_args',
421 $query_args,
422 $attributes,
423 $block
424 );
425
426 $the_query = new WP_Query( $query_args );
427
428 $content = '';
429 if ( $the_query->have_posts() ) {
430 while ( $the_query->have_posts() ) {
431 $the_query->the_post();
432
433 $block_content = (
434 new WP_Block(
435 $block->parsed_block,
436 array(
437 'postType' => get_post_type(),
438 'postId' => get_the_ID(),
439 )
440 )
441 )->render( array( 'dynamic' => false ) );
442
443 $content .= $block_content;
444 }
445 }
446
447 wp_reset_postdata();
448
449 return $content;
450 }
451
452 /**
453 * Wrapper function for our dynamic headlines.
454 *
455 * @since 1.5.0
456 * @param array $attributes The block attributes.
457 * @param string $content The dynamic text to display.
458 * @param WP_Block $block Block instance.
459 */
460 public static function do_headline_block( $attributes, $content, $block ) {
461 if ( ! isset( $attributes['useDynamicData'] ) || ! $attributes['useDynamicData'] ) {
462 return $content;
463 }
464
465 $allow_empty_content = false;
466
467 if ( empty( $attributes['dynamicContentType'] ) ) {
468 $dynamic_content = GenerateBlocks_Dynamic_Content::get_static_content( $content );
469
470 if ( ! empty( $attributes['hasIcon'] ) && ! empty( $attributes['removeText'] ) ) {
471 // Allow icon-only items to continue.
472 $allow_empty_content = true;
473 }
474 } else {
475 $dynamic_content = GenerateBlocks_Dynamic_Content::get_content( $attributes, $block );
476 }
477
478 if ( ! $dynamic_content && '0' !== $dynamic_content && ! $allow_empty_content ) {
479 return '';
480 }
481
482 $defaults = generateblocks_get_block_defaults();
483
484 $settings = wp_parse_args(
485 $attributes,
486 $defaults['headline']
487 );
488
489 $classNames = array(
490 'gb-headline',
491 'gb-headline-' . $settings['uniqueId'],
492 );
493
494 if ( ! empty( $settings['className'] ) ) {
495 $classNames[] = $settings['className'];
496 }
497
498 if ( empty( $settings['icon'] ) ) {
499 $classNames[] = 'gb-headline-text';
500 }
501
502 $tagName = apply_filters(
503 'generateblocks_dynamic_headline_tagname',
504 $settings['element'],
505 $attributes,
506 $block
507 );
508
509 $allowedTagNames = apply_filters(
510 'generateblocks_dynamic_headline_allowed_tagnames',
511 array(
512 'h1',
513 'h2',
514 'h3',
515 'h4',
516 'h5',
517 'h6',
518 'div',
519 'p',
520 'figcaption',
521 ),
522 $attributes,
523 $block
524 );
525
526 if ( ! in_array( $tagName, $allowedTagNames ) ) {
527 $tagName = 'div';
528 }
529
530 $output = sprintf(
531 '<%1$s %2$s>',
532 $tagName,
533 generateblocks_attr(
534 'dynamic-headline',
535 array(
536 'id' => isset( $settings['anchor'] ) ? $settings['anchor'] : null,
537 'class' => implode( ' ', $classNames ),
538 ),
539 $settings,
540 $block
541 )
542 );
543
544 $icon_html = '';
545
546 // Extract our icon from the static HTML.
547 if ( $settings['hasIcon'] ) {
548 $icon_html = GenerateBlocks_Dynamic_Content::get_icon_html( $content );
549
550 if ( $icon_html ) {
551 $output .= $icon_html;
552 $output .= '<span class="gb-headline-text">';
553 }
554 }
555
556 $dynamic_link = GenerateBlocks_Dynamic_Content::get_dynamic_url( $attributes, $block );
557
558 if ( $dynamic_link ) {
559 $dynamic_content = sprintf(
560 '<a href="%s">%s</a>',
561 $dynamic_link,
562 $dynamic_content
563 );
564 }
565
566 $output .= $dynamic_content;
567
568 if ( $icon_html ) {
569 $output .= '</span>';
570 }
571
572 $output .= sprintf(
573 '</%s>',
574 $tagName
575 );
576
577 return $output;
578 }
579
580 /**
581 * Wrapper function for our dynamic buttons.
582 *
583 * @since 1.5.0
584 * @param array $attributes The block attributes.
585 * @param string $content The dynamic text to display.
586 * @param WP_Block $block Block instance.
587 */
588 public static function do_button_block( $attributes, $content, $block ) {
589 if ( ! isset( $attributes['useDynamicData'] ) || ! $attributes['useDynamicData'] ) {
590 return $content;
591 }
592
593 $allow_empty_content = false;
594
595 // Add an attribute showing we're working with the Button block.
596 $attributes['isButton'] = true;
597
598 if ( empty( $attributes['dynamicContentType'] ) ) {
599 $dynamic_content = GenerateBlocks_Dynamic_Content::get_static_content( $content );
600
601 if ( ! empty( $attributes['hasIcon'] ) && ! empty( $attributes['removeText'] ) ) {
602 // Allow icon-only items to continue.
603 $allow_empty_content = true;
604 }
605 } else {
606 $dynamic_content = GenerateBlocks_Dynamic_Content::get_content( $attributes, $block );
607 }
608
609 if ( ! $dynamic_content && '0' !== $dynamic_content && ! $allow_empty_content ) {
610 return '';
611 }
612
613 $defaults = generateblocks_get_block_defaults();
614
615 $settings = wp_parse_args(
616 $attributes,
617 $defaults['button']
618 );
619
620 $classNames = array(
621 'gb-button',
622 'gb-button-' . $settings['uniqueId'],
623 );
624
625 if ( ! empty( $settings['className'] ) ) {
626 $classNames[] = $settings['className'];
627 }
628
629 if ( empty( $settings['icon'] ) ) {
630 $classNames[] = 'gb-button-text';
631 }
632
633 $relAttributes = array();
634
635 if ( ! empty( $settings['relNoFollow'] ) ) {
636 $relAttributes[] = 'nofollow';
637 }
638
639 if ( ! empty( $settings['target'] ) ) {
640 $relAttributes[] = 'noopener';
641 $relAttributes[] = 'noreferrer';
642 }
643
644 if ( ! empty( $settings['relSponsored'] ) ) {
645 $relAttributes[] = 'sponsored';
646 }
647
648 $icon_html = '';
649
650 // Extract our icon from the static HTML.
651 if ( $settings['hasIcon'] ) {
652 $icon_html = GenerateBlocks_Dynamic_Content::get_icon_html( $content );
653 }
654
655 $output = '';
656
657 foreach ( (array) $dynamic_content as $content ) {
658 $tagName = 'span';
659
660 $dynamic_link = GenerateBlocks_Dynamic_Content::get_dynamic_url( $attributes, $block );
661
662 if ( isset( $content['attributes']['href'] ) || $dynamic_link ) {
663 $tagName = 'a';
664 }
665
666 $button_attributes = array(
667 'id' => isset( $settings['anchor'] ) ? $settings['anchor'] : null,
668 'class' => implode( ' ', $classNames ),
669 'href' => 'a' === $tagName ? $dynamic_link : null,
670 'rel' => ! empty( $relAttributes ) ? implode( ' ', $relAttributes ) : null,
671 'target' => ! empty( $settings['target'] ) ? '_blank' : null,
672 );
673
674 if ( isset( $content['attributes'] ) ) {
675 foreach ( $content['attributes'] as $attribute => $value ) {
676 if ( 'class' === $attribute ) {
677 $button_attributes[ $attribute ] .= ' ' . $value;
678 } else {
679 $button_attributes[ $attribute ] = $value;
680 }
681 }
682 }
683
684 $output .= sprintf(
685 '<%1$s %2$s>',
686 $tagName,
687 generateblocks_attr(
688 'dynamic-button',
689 $button_attributes,
690 $settings,
691 $block
692 )
693 );
694
695 if ( $icon_html ) {
696 if ( 'left' === $settings['iconLocation'] ) {
697 $output .= $icon_html;
698 }
699
700 $output .= '<span class="gb-button-text">';
701 }
702
703 if ( isset( $content['content'] ) ) {
704 $output .= $content['content'];
705 } else {
706 $output .= $content;
707 }
708
709 if ( $icon_html ) {
710 $output .= '</span>';
711
712 if ( 'right' === $settings['iconLocation'] ) {
713 $output .= $icon_html;
714 }
715 }
716
717 $output .= sprintf(
718 '</%s>',
719 $tagName
720 );
721 }
722
723 return $output;
724 }
725
726 /**
727 * Wrapper function for our image block.
728 *
729 * @since 1.5.0
730 * @param array $attributes The block attributes.
731 * @param string $content The dynamic text to display.
732 * @param WP_Block $block Block instance.
733 */
734 public static function do_image_block( $attributes, $content, $block ) {
735 if ( empty( $attributes['useDynamicData'] ) ) {
736 return generateblocks_filter_images( $content, $attributes );
737 }
738
739 $image = empty( $attributes['dynamicContentType'] )
740 ? generateblocks_filter_images( GenerateBlocks_Dynamic_Content::get_static_content( $content ), $attributes )
741 : GenerateBlocks_Dynamic_Content::get_dynamic_image( $attributes, $block );
742
743 if ( ! $image ) {
744 return '';
745 }
746
747 $defaults = generateblocks_get_block_defaults();
748
749 $settings = wp_parse_args(
750 $attributes,
751 $defaults['image']
752 );
753
754 $output = sprintf(
755 '<figure %s>',
756 generateblocks_attr(
757 'image-figure',
758 array(
759 'class' => implode(
760 ' ',
761 array(
762 'gb-block-image',
763 'gb-block-image-' . $settings['uniqueId'],
764 )
765 ),
766 ),
767 $settings,
768 $block
769 )
770 );
771
772 $dynamic_link = GenerateBlocks_Dynamic_Content::get_dynamic_url( $attributes, $block );
773
774 if ( $dynamic_link ) {
775 $relAttributes = array();
776
777 if ( ! empty( $settings['relNoFollow'] ) ) {
778 $relAttributes[] = 'nofollow';
779 }
780
781 if ( ! empty( $settings['openInNewWindow'] ) ) {
782 $relAttributes[] = 'noopener';
783 $relAttributes[] = 'noreferrer';
784 }
785
786 if ( ! empty( $settings['relSponsored'] ) ) {
787 $relAttributes[] = 'sponsored';
788 }
789
790 $dynamic_link_data = array(
791 'href' => $dynamic_link,
792 'rel' => ! empty( $relAttributes ) ? implode( ' ', $relAttributes ) : null,
793 'target' => ! empty( $settings['openInNewWindow'] ) ? '_blank' : null,
794 );
795
796 $dynamic_link_attributes = '';
797
798 foreach ( $dynamic_link_data as $attribute => $value ) {
799 $dynamic_link_attributes .= sprintf(
800 ' %s="%s"',
801 $attribute,
802 $value
803 );
804 }
805
806 $image = sprintf(
807 '<a %s>%s</a>',
808 trim( $dynamic_link_attributes ),
809 $image
810 );
811 }
812
813 $output .= $image;
814
815 if ( isset( $block->parsed_block['innerBlocks'][0]['attrs'] ) ) {
816 $image_id = GenerateBlocks_Dynamic_Content::get_dynamic_image_id( $attributes );
817 $block->parsed_block['innerBlocks'][0]['attrs']['dynamicImage'] = $image_id;
818
819 $caption = (
820 new WP_Block(
821 $block->parsed_block['innerBlocks'][0]
822 )
823 )->render( array( 'dynamic' => true ) );
824
825 if ( $caption ) {
826 $output .= $caption;
827 }
828 }
829
830 $output .= '</figure>';
831
832 return $output;
833 }
834
835 /**
836 * Filter existing rendered blocks.
837 *
838 * @since 1.5.0
839 * @param string $block_content The block content.
840 * @param array $block The block data.
841 * @param WP_Block $instance Block instance.
842 */
843 public function filter_rendered_blocks( $block_content, $block, $instance ) {
844 $attributes = isset( $block['attrs'] ) ? $block['attrs'] : null;
845
846 // Don't output if no dynamic link exists.
847 if ( isset( $attributes ) && ! empty( $attributes['dynamicLinkType'] ) && ! empty( $attributes['dynamicLinkRemoveIfEmpty'] ) ) {
848 $dynamic_link = GenerateBlocks_Dynamic_Content::get_dynamic_url( $attributes, $instance );
849
850 if ( ! $dynamic_link ) {
851 return '';
852 }
853 }
854
855 return $block_content;
856 }
857 }
858
859 GenerateBlocks_Render_Block::get_instance();
860