PluginProbe
Gutenberg / trunk
Gutenberg vtrunk
24.1.0 24.0.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 All 404 releases
← All changes | build/scripts/block-library/latest-posts.php +63 -21 23.2.1 → trunk View file →
@@ -43,8 +43,9 @@
43 43 * @return string Returns the post content with latest posts added.
44 44 */
45 45 function gutenberg_render_block_core_latest_posts( $attributes ) {
46 46 global $post, $block_core_latest_posts_excerpt_length;
47 + static $rendering_stack = array();
47 48
48 49 $args = array(
49 50 'posts_per_page' => $attributes['postsToShow'],
50 51 'post_status' => 'publish',
@@ -56,17 +57,17 @@
56 57
57 58 $block_core_latest_posts_excerpt_length = $attributes['excerptLength'];
58 59 add_filter( 'excerpt_length', 'gutenberg_block_core_latest_posts_get_excerpt_length', 20 );
59 60
60 - if ( ! empty( $attributes['categories'] ) ) {
61 - $args['category__in'] = array_column( $attributes['categories'], 'id' );
61 + $categories = $attributes['categories'] ?? null;
62 + if ( ! empty( $categories ) && is_array( $categories ) ) {
63 + $args['category__in'] = array_column( $categories, 'id' );
62 64 }
63 65 if ( isset( $attributes['selectedAuthor'] ) ) {
64 66 $args['author'] = $attributes['selectedAuthor'];
65 67 }
66 68
67 - $query = new WP_Query();
68 - $recent_posts = $query->query( $args );
69 + $query = new WP_Query( $args );
69 70
70 71 if ( isset( $attributes['displayFeaturedImage'] ) && $attributes['displayFeaturedImage'] ) {
71 72 update_post_thumbnail_cache( $query );
72 73 }
@@ -71,12 +72,18 @@
71 72 update_post_thumbnail_cache( $query );
72 73 }
73 74
74 75 $list_items_markup = '';
76 + // Snapshot the current global post so it can be restored after the loop.
77 + // We use have_posts()/the_post() rather than foreach so that setup_postdata()
78 + // is called for each post, establishing the correct global context for
79 + // do_blocks() and other filters that run during full-content rendering.
80 + $previous_post = $post ?? null;
75 81
76 - foreach ( $recent_posts as $post ) {
77 - $post_link = esc_url( get_permalink( $post ) );
78 - $title = get_the_title( $post );
82 + while ( $query->have_posts() ) {
83 + $query->the_post();
84 + $post_link = esc_url( get_permalink() );
85 + $title = get_the_title();
79 86
80 87 if ( ! $title ) {
81 88 $title = __( '(no title)' );
82 89 }
@@ -82,9 +89,9 @@
82 89 }
83 90
84 91 $list_items_markup .= '<li>';
85 92
86 - if ( $attributes['displayFeaturedImage'] && has_post_thumbnail( $post ) ) {
93 + if ( $attributes['displayFeaturedImage'] && has_post_thumbnail() ) {
87 94 $image_style = '';
88 95 if ( isset( $attributes['featuredImageSizeWidth'] ) ) {
89 96 $image_style .= sprintf( 'max-width:%spx;', $attributes['featuredImageSizeWidth'] );
90 97 }
@@ -97,9 +104,9 @@
97 104 $image_classes .= ' align' . $attributes['featuredImageAlign'];
98 105 }
99 106
100 107 $featured_image = get_the_post_thumbnail(
101 - $post,
108 + null,
102 109 $attributes['featuredImageSizeSlug'],
103 110 array(
104 111 'style' => esc_attr( $image_style ),
105 112 )
@@ -125,9 +132,9 @@
125 132 $title
126 133 );
127 134
128 135 if ( isset( $attributes['displayAuthor'] ) && $attributes['displayAuthor'] ) {
129 - $author_display_name = get_the_author_meta( 'display_name', $post->post_author );
136 + $author_display_name = get_the_author_meta( 'display_name' );
130 137
131 138 /* translators: byline. %s: author. */
132 139 $byline = sprintf( __( 'by %s' ), $author_display_name );
133 140
@@ -141,10 +148,10 @@
141 148
142 149 if ( isset( $attributes['displayPostDate'] ) && $attributes['displayPostDate'] ) {
143 150 $list_items_markup .= sprintf(
144 151 '<time datetime="%1$s" class="wp-block-latest-posts__post-date">%2$s</time>',
145 - esc_attr( get_the_date( 'c', $post ) ),
146 - get_the_date( '', $post )
152 + esc_attr( get_the_date( 'c' ) ),
153 + get_the_date( '' )
147 154 );
148 155 }
149 156
150 157 if ( isset( $attributes['displayPostContent'] ) && $attributes['displayPostContent']
@@ -149,9 +156,9 @@
149 156
150 157 if ( isset( $attributes['displayPostContent'] ) && $attributes['displayPostContent']
151 158 && isset( $attributes['displayPostContentRadio'] ) && 'excerpt' === $attributes['displayPostContentRadio'] ) {
152 159
153 - $trimmed_excerpt = get_the_excerpt( $post );
160 + $trimmed_excerpt = get_the_excerpt();
154 161
155 162 /*
156 163 * Adds a "Read more" link with screen reader text.
157 164 * [&hellip;] is the default excerpt ending from wp_trim_excerpt() in Core.
@@ -169,9 +176,9 @@
169 176 );
170 177 }
171 178 }
172 179
173 - if ( post_password_required( $post ) ) {
180 + if ( post_password_required() ) {
174 181 $trimmed_excerpt = __( 'This content is password protected.' );
175 182 }
176 183
177 184 $list_items_markup .= sprintf(
@@ -182,17 +189,32 @@
182 189
183 190 if ( isset( $attributes['displayPostContent'] ) && $attributes['displayPostContent']
184 191 && isset( $attributes['displayPostContentRadio'] ) && 'full_post' === $attributes['displayPostContentRadio'] ) {
185 192
186 - $post_content = html_entity_decode( $post->post_content, ENT_QUOTES, get_option( 'blog_charset' ) );
193 + if ( post_password_required() ) {
194 + $post_content = __( 'This content is password protected.' );
195 + } else {
196 + $post_id = get_the_ID();
197 + $post_content = get_post_field( 'post_content', $post_id, 'raw' );
198 + // Check if we're already rendering this post to prevent infinite recursion.
199 + if ( in_array( $post_id, $rendering_stack, true ) ) {
200 + $post_content = '';
201 + } else {
202 + $rendering_stack[] = $post_id;
187 203
188 - if ( post_password_required( $post ) ) {
189 - $post_content = __( 'This content is password protected.' );
204 + try {
205 + // Run through the actions that are typically taken on the_content.
206 + $post_content = _wp_apply_block_content_filters( $post_content, 'latest-posts' );
207 + } finally {
208 + array_pop( $rendering_stack );
209 + }
210 + }
190 211 }
191 212
213 + $post_content = str_replace( ']]>', ']]&gt;', $post_content );
192 214 $list_items_markup .= sprintf(
193 215 '<div class="wp-block-latest-posts__post-full-content">%1$s</div>',
194 - wp_kses_post( $post_content )
216 + $post_content
195 217 );
196 218 }
197 219
198 220 $list_items_markup .= "</li>\n";
@@ -197,16 +219,36 @@
197 219
198 220 $list_items_markup .= "</li>\n";
199 221 }
200 222
223 + // Restore the post context that was active before this secondary query.
224 + // wp_reset_postdata() is intentionally not used here: when this block is
225 + // rendered inside another post's content (e.g. via do_blocks()), it would
226 + // restore to the main query post rather than the outer rendering post.
227 + $post = $previous_post;
228 + if ( $previous_post instanceof WP_Post ) {
229 + setup_postdata( $previous_post );
230 + }
231 +
201 232 remove_filter( 'excerpt_length', 'gutenberg_block_core_latest_posts_get_excerpt_length', 20 );
202 233
234 + $layout = $attributes['layout'] ?? array();
235 + $legacy_layout_type = (
236 + isset( $attributes['postLayout'] ) &&
237 + 'grid' === $attributes['postLayout']
238 + ) ? 'grid' : 'default';
239 + $layout_type = $layout['type'] ?? $legacy_layout_type;
240 + $column_count = $layout['columnCount'] ?? ( $attributes['columns'] ?? null );
241 +
203 242 $classes = array( 'wp-block-latest-posts__list' );
204 - if ( isset( $attributes['postLayout'] ) && 'grid' === $attributes['postLayout'] ) {
243 + if ( 'grid' === $layout_type ) {
205 244 $classes[] = 'is-grid';
206 245 }
207 - if ( isset( $attributes['columns'] ) && 'grid' === $attributes['postLayout'] ) {
208 - $classes[] = 'columns-' . $attributes['columns'];
246 + if ( 'grid' === $layout_type && ! empty( $column_count ) ) {
247 + $classes[] = sanitize_title( 'columns-' . $column_count );
248 + }
249 + if ( 'grid' === $layout_type && ! empty( $column_count ) && ! empty( $layout['minimumColumnWidth'] ) ) {
250 + $classes[] = 'has-native-responsive-grid';
209 251 }
210 252 if ( isset( $attributes['displayPostDate'] ) && $attributes['displayPostDate'] ) {
211 253 $classes[] = 'has-dates';
212 254 }