PluginProbe
bBlocks – Essential Gutenberg Blocks & Patterns Collection / 2.1.8
bBlocks – Essential Gutenberg Blocks & Patterns Collection v2.1.8
2.1.8 2.1.7 2.1.6 2.1.5 2.1.4 2.1.3 2.1.2 2.1.1 2.1.0 2.0.43 2.0.42 2.0.41 2.0.40 2.0.39 2.0.38 trunk 1.0 1.1 1.2 1.3 1.4 1.5 1.5.1 1.5.2 1.5.3 All 108 releases
← All changes | build/timeline/render.php +29 -77 2.1.2 → 2.1.8 View file →
@@ -1,18 +1,24 @@
1 1 <?php
2 2 /**
3 - * Server-side render for the b-blocks/timeline block.
3 + * Timeline Block server-side render.
4 4 *
5 - * The block is hydrated on the front-end by view.js, which reads the
6 - * sanitized attributes from the data-attributes JSON payload and renders
7 - * the timeline. We output a single wrapping element here, escape all
8 - * attribute output, and avoid emitting any raw user-supplied HTML at
9 - * the PHP layer.
5 + * Only the wrapper and the entries are written here — no classes and no
6 + * styles. Both are applied on the client from the attributes forwarded in
7 + * `data-attributes`: the wrapper's classes by Components/Frontend/Timeline.js
8 + * and every style by Components/Common/Style.js, the same way the Data Table
9 + * block renders.
10 10 *
11 + * That leaves the class list with a single source of truth in
12 + * utils/functions.js rather than a copy here that has to be kept in step.
13 + *
14 + * The entries are InnerBlocks, so they are rendered into a holder that
15 + * view.js adopts into the React tree rather than re-creating.
16 + *
11 17 * @package bBlocks
12 18 *
13 19 * @var array $attributes Block attributes.
14 - * @var string $content Block inner HTML (unused).
20 + * @var string $content Rendered inner blocks.
15 21 */
16 22
17 23 if ( ! defined( 'ABSPATH' ) ) {
18 24 exit;
@@ -17,76 +23,22 @@
17 23 if ( ! defined( 'ABSPATH' ) ) {
18 24 exit;
19 25 }
20 26
21 -$bblocks_timeline_id = wp_unique_id( 'bBlocksTimeline-' );
22 -
23 -// Allow-list the attributes we forward to the front-end so unexpected
24 -// keys are dropped before the JSON payload is rendered.
25 -$bblocks_timeline_allowed_layouts = array( 'left', 'right', 'alternating' );
26 -$bblocks_timeline_allowed_variants = array( 'modern', 'classic', 'minimal' );
27 -
28 -$bblocks_timeline_layout = isset( $attributes['layout'] ) ? sanitize_key( $attributes['layout'] ) : 'alternating';
29 -if ( ! in_array( $bblocks_timeline_layout, $bblocks_timeline_allowed_layouts, true ) ) {
30 - $bblocks_timeline_layout = 'alternating';
31 -}
32 -
33 -$bblocks_timeline_variant = isset( $attributes['variant'] ) ? sanitize_key( $attributes['variant'] ) : 'modern';
34 -if ( ! in_array( $bblocks_timeline_variant, $bblocks_timeline_allowed_variants, true ) ) {
35 - $bblocks_timeline_variant = 'modern';
36 -}
37 -
38 -$bblocks_timeline_line_color = isset( $attributes['lineColor'] ) ? sanitize_hex_color( $attributes['lineColor'] ) : '';
39 -if ( empty( $bblocks_timeline_line_color ) ) {
40 - $bblocks_timeline_line_color = '#dee2e6';
41 -}
42 -
43 -$bblocks_timeline_show_icons = ! empty( $attributes['showIcons'] );
44 -
45 -$bblocks_timeline_items = array();
46 -if ( isset( $attributes['items'] ) && is_array( $attributes['items'] ) ) {
47 - foreach ( $attributes['items'] as $bblocks_timeline_item ) {
48 - if ( ! is_array( $bblocks_timeline_item ) ) {
49 - continue;
50 - }
51 -
52 - $bblocks_timeline_accent = isset( $bblocks_timeline_item['accentColor'] )
53 - ? sanitize_hex_color( $bblocks_timeline_item['accentColor'] )
54 - : '';
55 -
56 - $bblocks_timeline_items[] = array(
57 - 'date' => isset( $bblocks_timeline_item['date'] ) ? sanitize_text_field( $bblocks_timeline_item['date'] ) : '',
58 - 'title' => isset( $bblocks_timeline_item['title'] ) ? wp_kses_post( $bblocks_timeline_item['title'] ) : '',
59 - 'description' => isset( $bblocks_timeline_item['description'] ) ? wp_kses_post( $bblocks_timeline_item['description'] ) : '',
60 - 'icon' => isset( $bblocks_timeline_item['icon'] ) ? sanitize_text_field( $bblocks_timeline_item['icon'] ) : '',
61 - 'accentColor' => $bblocks_timeline_accent ? $bblocks_timeline_accent : '#0d6efd',
62 - );
63 - }
64 -}
65 -
66 -$bblocks_timeline_payload = array(
67 - 'layout' => $bblocks_timeline_layout,
68 - 'variant' => $bblocks_timeline_variant,
69 - 'lineColor' => $bblocks_timeline_line_color,
70 - 'showIcons' => (bool) $bblocks_timeline_show_icons,
71 - 'items' => $bblocks_timeline_items,
72 -);
73 -
74 -$bblocks_timeline_plan_class = ( class_exists( '\\BBlocks\\Inc\\Utils' ) && \BBlocks\Inc\Utils::isPro() ) ? 'pro' : 'free';
75 -
76 -$bblocks_timeline_wrapper_classes = sprintf(
77 - '%s timeline-block timeline-variant-%s timeline-layout-%s',
78 - $bblocks_timeline_plan_class,
79 - $bblocks_timeline_variant,
80 - $bblocks_timeline_layout
81 -);
27 +$id = wp_unique_id( 'timeline-' );
82 28 ?>
83 29 <div
84 - <?php
85 - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- get_block_wrapper_attributes() is properly escaped.
86 - echo get_block_wrapper_attributes( array( 'class' => $bblocks_timeline_wrapper_classes ) );
87 - ?>
88 - id="<?php echo esc_attr( $bblocks_timeline_id ); ?>"
89 - role="list"
90 - aria-label="<?php echo esc_attr__( 'Timeline', 'b-blocks' ); ?>"
91 - data-attributes='<?php echo esc_attr( wp_json_encode( $bblocks_timeline_payload ) ); ?>'
92 -></div>
30 + <?php // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- get_block_wrapper_attributes() is properly escaped ?>
31 + <?php echo get_block_wrapper_attributes(); ?>
32 + id='<?php echo esc_attr( $id ); ?>'
33 + data-attributes='<?php echo esc_attr( wp_json_encode( $attributes ) ); ?>'
34 +>
35 + <div class='b-blocks-timeline-innerBlocks-contents'>
36 + <div class='b-blocks-timeline-items'>
37 + <?php
38 + // $content is the rendered inner blocks — a series of Timeline
39 + // Items, each of which escaped its own output in its render.php.
40 + echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- inner blocks render their own escaped markup
41 + ?>
42 + </div>
43 + </div>
44 +</div>