PluginProbe
Gutenberg / 23.6.0
Gutenberg v23.6.0
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / build / scripts / block-library / playlist.php

playlist.php in Gutenberg 23.6.0, at build/scripts/block-library/playlist.php

211 lines 6.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Server-side rendering of the `core/playlist` block.
4 *
5 * @package WordPress
6 */
7
8 /**
9 * Renders the `core/playlist` block on server.
10 *
11 * @since 7.1.0
12 *
13 * @param array $attributes The block attributes.
14 * @param string $content The block content.
15 * @param WP_Block $block The block instance.
16 *
17 * @return string Returns the Playlist.
18 */
19 function gutenberg_render_block_core_playlist( $attributes, $content, $block ) {
20 $playlist_id = wp_unique_id( 'playlist-' );
21 $playlist_tracks = array();
22 $tracks_data = array();
23 $show_play_button_artwork = ! empty( $attributes['showPlayButtonArtwork'] );
24
25 // Parse inner blocks to extract track data.
26 // This approach avoids duplicating track data in the HTML output.
27 if ( ! empty( $block->inner_blocks ) ) {
28 foreach ( $block->inner_blocks as $inner_block ) {
29 if ( 'core/playlist-track' === $inner_block->name ) {
30 $track_attributes = $inner_block->attributes;
31
32 if ( empty( $track_attributes['id'] ) ) {
33 continue;
34 }
35
36 $track_id = 'track-' . count( $playlist_tracks );
37 $playlist_tracks[] = $track_id;
38
39 // Extract track metadata from block attributes.
40 $title = isset( $track_attributes['title'] ) && ! empty( $track_attributes['title'] ) ? $track_attributes['title'] : __( 'Unknown title' );
41 $artist = $track_attributes['artist'] ?? '';
42 $album = $track_attributes['album'] ?? '';
43 $image = $track_attributes['image'] ?? '';
44 $image_alt = $track_attributes['imageAlt'] ?? '';
45 $url = $track_attributes['src'] ?? '';
46 $aria_label = $title;
47
48 if ( $title && $artist && $album ) {
49 $aria_label = sprintf(
50 /* translators: %1$s: track title, %2$s: artist name, %3$s: album name. */
51 _x( '%1$s by %2$s from the album %3$s', 'track title, artist name, album name' ),
52 $title,
53 $artist,
54 $album
55 );
56 }
57
58 // Data is passed to wp_interactivity_state() which JSON-encodes it,
59 // so we use wp_strip_all_tags() instead of esc_html() to prevent
60 // HTML injection without double-encoding. URLs still use esc_url().
61 $tracks_data[ $track_id ] = array(
62 'url' => esc_url( $url ),
63 'title' => wp_strip_all_tags( $title ),
64 'artist' => wp_strip_all_tags( $artist ),
65 'album' => wp_strip_all_tags( $album ),
66 'image' => esc_url( $image ),
67 'imageAlt' => wp_strip_all_tags( $image_alt ),
68 'ariaLabel' => wp_strip_all_tags( $aria_label ),
69 );
70 }
71 }
72 }
73
74 if ( empty( $playlist_tracks ) ) {
75 return '';
76 }
77
78 wp_enqueue_script_module( '@wordpress/block-library/playlist/view' );
79
80 // Add the playlist tracks to the global state,
81 // but keep them isolated from other playlists with the help of playlistId.
82 wp_interactivity_state(
83 'core/playlist',
84 array(
85 'playlists' => array(
86 $playlist_id => array(
87 'tracks' => $tracks_data,
88 ),
89 ),
90 )
91 );
92
93 // Add waveform player container with translated button labels.
94 $label_play = esc_attr__( 'Play' );
95 $label_pause = esc_attr__( 'Pause' );
96 $label_seek = esc_attr__( 'Seek' );
97 /* translators: %1$s: current audio time, %2$s: total audio duration. */
98 $label_seek_value = esc_attr_x(
99 '%1$s of %2$s',
100 'audio current time of total duration'
101 );
102 $waveform_color_attribute = '';
103 $waveform_gradient_attribute = '';
104 $waveform_background_color_attribute = '';
105 $waveform_background_gradient_attribute = '';
106 if ( ! empty( $attributes['waveformColor'] ) ) {
107 $waveform_color_attribute = sprintf(
108 ' data-waveform-player-color="%s"',
109 esc_attr( $attributes['waveformColor'] )
110 );
111 }
112 if ( ! empty( $attributes['waveformGradient'] ) ) {
113 $waveform_gradient_attribute = sprintf(
114 ' data-waveform-player-gradient="%s"',
115 esc_attr( $attributes['waveformGradient'] )
116 );
117 }
118 if ( ! empty( $attributes['waveformBackgroundColor'] ) ) {
119 $waveform_background_color_attribute = sprintf(
120 ' data-waveform-player-background-color="%s"',
121 esc_attr( $attributes['waveformBackgroundColor'] )
122 );
123 }
124 if ( ! empty( $attributes['waveformBackgroundGradient'] ) ) {
125 $waveform_background_gradient_attribute = sprintf(
126 ' data-waveform-player-background-gradient="%s"',
127 esc_attr( $attributes['waveformBackgroundGradient'] )
128 );
129 }
130 $html = '<div class="wp-block-playlist__waveform-player"' .
131 $waveform_color_attribute .
132 $waveform_gradient_attribute .
133 $waveform_background_color_attribute .
134 $waveform_background_gradient_attribute . '
135 data-wp-watch="callbacks.initWaveformPlayer"
136 data-label-play="' . $label_play . '"
137 data-label-pause="' . $label_pause . '"
138 data-label-seek="' . $label_seek . '"
139 data-label-seek-value="' . $label_seek_value . '"
140 ></div>';
141
142 // Add the waveform player container inside the figure.
143 $figure = null;
144 preg_match( '/<figure[^>]*>/', $content, $figure );
145 if ( ! empty( $figure[0] ) ) {
146 $content = preg_replace( '/(<figure[^>]*>)/', '$1' . $html, $content, 1 );
147 }
148
149 $processor = new WP_HTML_Tag_Processor( $content );
150 $processor->next_tag( 'figure' );
151 $processor->set_attribute( 'data-wp-interactive', 'core/playlist' );
152
153 $waveform_style = $attributes['waveformStyle'] ?? 'bars';
154
155 $processor->set_attribute(
156 'data-wp-context',
157 wp_json_encode(
158 array(
159 'playlistId' => $playlist_id,
160 'currentId' => $playlist_tracks[0],
161 'isPlaying' => false,
162 'tracks' => $playlist_tracks,
163 'waveformStyle' => $waveform_style,
164 'showPlayButtonArtwork' => $show_play_button_artwork,
165 'labelPauseTrack' => __( 'Pause' ),
166 'labelSelectTrack' => __( 'Play' ),
167 )
168 )
169 );
170
171 // Track IDs are render-time only. Add them after inner blocks have rendered
172 // so track buttons can update the Interactivity API state without storing
173 // persistent unique IDs in post content.
174 $track_index = 0;
175 while ( $processor->next_tag( array( 'class_name' => 'wp-block-playlist-track__button' ) ) ) {
176 $track_id = $playlist_tracks[ $track_index ] ?? null;
177
178 if ( null === $track_id ) {
179 break;
180 }
181
182 $processor->set_attribute(
183 'data-wp-context',
184 wp_json_encode(
185 array(
186 'trackId' => $track_id,
187 )
188 )
189 );
190
191 ++$track_index;
192 }
193
194 return $processor->get_updated_html();
195 }
196
197 /**
198 * Registers the `core/playlist` block on server.
199 *
200 * @since 7.1.0
201 */
202 function gutenberg_register_block_core_playlist() {
203 register_block_type_from_metadata(
204 __DIR__ . '/playlist',
205 array(
206 'render_callback' => 'gutenberg_render_block_core_playlist',
207 )
208 );
209 }
210 add_action( 'init', 'gutenberg_register_block_core_playlist', 20 );
211