PluginProbe
Gutenberg / 12.6.0
Gutenberg v12.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 / block-library / blocks / latest-posts.php

latest-posts.php in Gutenberg 12.6.0, at build/block-library/blocks/latest-posts.php

240 lines 7.1 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/latest-posts` block.
4 *
5 * @package WordPress
6 */
7
8 /**
9 * The excerpt length set by the Latest Posts core block
10 * set at render time and used by the block itself.
11 *
12 * @var int
13 */
14 global $block_core_latest_posts_excerpt_length;
15 $block_core_latest_posts_excerpt_length = 0;
16
17 /**
18 * Callback for the excerpt_length filter used by
19 * the Latest Posts block at render time.
20 *
21 * @return int Returns the global $block_core_latest_posts_excerpt_length variable
22 * to allow the excerpt_length filter respect the Latest Block setting.
23 */
24 function gutenberg_block_core_latest_posts_get_excerpt_length() {
25 global $block_core_latest_posts_excerpt_length;
26 return $block_core_latest_posts_excerpt_length;
27 }
28
29 /**
30 * Renders the `core/latest-posts` block on server.
31 *
32 * @param array $attributes The block attributes.
33 *
34 * @return string Returns the post content with latest posts added.
35 */
36 function gutenberg_render_block_core_latest_posts( $attributes ) {
37 global $post, $block_core_latest_posts_excerpt_length;
38
39 $args = array(
40 'posts_per_page' => $attributes['postsToShow'],
41 'post_status' => 'publish',
42 'order' => $attributes['order'],
43 'orderby' => $attributes['orderBy'],
44 'suppress_filters' => false,
45 );
46
47 $block_core_latest_posts_excerpt_length = $attributes['excerptLength'];
48 add_filter( 'excerpt_length', 'gutenberg_block_core_latest_posts_get_excerpt_length', 20 );
49
50 if ( isset( $attributes['categories'] ) ) {
51 $args['category__in'] = array_column( $attributes['categories'], 'id' );
52 }
53 if ( isset( $attributes['selectedAuthor'] ) ) {
54 $args['author'] = $attributes['selectedAuthor'];
55 }
56
57 $recent_posts = get_posts( $args );
58
59 $list_items_markup = '';
60
61 foreach ( $recent_posts as $post ) {
62 $post_link = esc_url( get_permalink( $post ) );
63 $title = get_the_title( $post );
64
65 if ( ! $title ) {
66 $title = __( '(no title)' );
67 }
68
69 $list_items_markup .= '<li>';
70
71 if ( $attributes['displayFeaturedImage'] && has_post_thumbnail( $post ) ) {
72 $image_style = '';
73 if ( isset( $attributes['featuredImageSizeWidth'] ) ) {
74 $image_style .= sprintf( 'max-width:%spx;', $attributes['featuredImageSizeWidth'] );
75 }
76 if ( isset( $attributes['featuredImageSizeHeight'] ) ) {
77 $image_style .= sprintf( 'max-height:%spx;', $attributes['featuredImageSizeHeight'] );
78 }
79
80 $image_classes = 'wp-block-latest-posts__featured-image';
81 if ( isset( $attributes['featuredImageAlign'] ) ) {
82 $image_classes .= ' align' . $attributes['featuredImageAlign'];
83 }
84
85 $featured_image = get_the_post_thumbnail(
86 $post,
87 $attributes['featuredImageSizeSlug'],
88 array(
89 'style' => esc_attr( $image_style ),
90 )
91 );
92 if ( $attributes['addLinkToFeaturedImage'] ) {
93 $featured_image = sprintf(
94 '<a href="%1$s" aria-label="%2$s">%3$s</a>',
95 esc_url( $post_link ),
96 esc_attr( $title ),
97 $featured_image
98 );
99 }
100 $list_items_markup .= sprintf(
101 '<div class="%1$s">%2$s</div>',
102 esc_attr( $image_classes ),
103 $featured_image
104 );
105 }
106
107 $list_items_markup .= sprintf(
108 '<a href="%1$s">%2$s</a>',
109 esc_url( $post_link ),
110 $title
111 );
112
113 if ( isset( $attributes['displayAuthor'] ) && $attributes['displayAuthor'] ) {
114 $author_display_name = get_the_author_meta( 'display_name', $post->post_author );
115
116 /* translators: byline. %s: current author. */
117 $byline = sprintf( __( 'by %s' ), $author_display_name );
118
119 if ( ! empty( $author_display_name ) ) {
120 $list_items_markup .= sprintf(
121 '<div class="wp-block-latest-posts__post-author">%1$s</div>',
122 $byline
123 );
124 }
125 }
126
127 if ( isset( $attributes['displayPostDate'] ) && $attributes['displayPostDate'] ) {
128 $list_items_markup .= sprintf(
129 '<time datetime="%1$s" class="wp-block-latest-posts__post-date">%2$s</time>',
130 esc_attr( get_the_date( 'c', $post ) ),
131 get_the_date( '', $post )
132 );
133 }
134
135 if ( isset( $attributes['displayPostContent'] ) && $attributes['displayPostContent']
136 && isset( $attributes['displayPostContentRadio'] ) && 'excerpt' === $attributes['displayPostContentRadio'] ) {
137
138 $trimmed_excerpt = get_the_excerpt( $post );
139
140 if ( post_password_required( $post ) ) {
141 $trimmed_excerpt = __( 'This content is password protected.' );
142 }
143
144 $list_items_markup .= sprintf(
145 '<div class="wp-block-latest-posts__post-excerpt">%1$s</div>',
146 $trimmed_excerpt
147 );
148 }
149
150 if ( isset( $attributes['displayPostContent'] ) && $attributes['displayPostContent']
151 && isset( $attributes['displayPostContentRadio'] ) && 'full_post' === $attributes['displayPostContentRadio'] ) {
152
153 $post_content = html_entity_decode( $post->post_content, ENT_QUOTES, get_option( 'blog_charset' ) );
154
155 if ( post_password_required( $post ) ) {
156 $post_content = __( 'This content is password protected.' );
157 }
158
159 $list_items_markup .= sprintf(
160 '<div class="wp-block-latest-posts__post-full-content">%1$s</div>',
161 wp_kses_post( $post_content )
162 );
163 }
164
165 $list_items_markup .= "</li>\n";
166 }
167
168 remove_filter( 'excerpt_length', 'gutenberg_block_core_latest_posts_get_excerpt_length', 20 );
169
170 $class = 'wp-block-latest-posts__list';
171
172 if ( isset( $attributes['postLayout'] ) && 'grid' === $attributes['postLayout'] ) {
173 $class .= ' is-grid';
174 }
175
176 if ( isset( $attributes['columns'] ) && 'grid' === $attributes['postLayout'] ) {
177 $class .= ' columns-' . $attributes['columns'];
178 }
179
180 if ( isset( $attributes['displayPostDate'] ) && $attributes['displayPostDate'] ) {
181 $class .= ' has-dates';
182 }
183
184 if ( isset( $attributes['displayAuthor'] ) && $attributes['displayAuthor'] ) {
185 $class .= ' has-author';
186 }
187
188 $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $class ) );
189
190 return sprintf(
191 '<ul %1$s>%2$s</ul>',
192 $wrapper_attributes,
193 $list_items_markup
194 );
195 }
196
197 /**
198 * Registers the `core/latest-posts` block on server.
199 */
200 function gutenberg_register_block_core_latest_posts() {
201 register_block_type_from_metadata(
202 __DIR__ . '/latest-posts',
203 array(
204 'render_callback' => 'gutenberg_render_block_core_latest_posts',
205 )
206 );
207 }
208 add_action( 'init', 'gutenberg_register_block_core_latest_posts', 20 );
209
210 /**
211 * Handles outdated versions of the `core/latest-posts` block by converting
212 * attribute `categories` from a numeric string to an array with key `id`.
213 *
214 * This is done to accommodate the changes introduced in #20781 that sought to
215 * add support for multiple categories to the block. However, given that this
216 * block is dynamic, the usual provisions for block migration are insufficient,
217 * as they only act when a block is loaded in the editor.
218 *
219 * TODO: Remove when and if the bottom client-side deprecation for this block
220 * is removed.
221 *
222 * @param array $block A single parsed block object.
223 *
224 * @return array The migrated block object.
225 */
226 function gutenberg_block_core_latest_posts_migrate_categories( $block ) {
227 if (
228 'core/latest-posts' === $block['blockName'] &&
229 ! empty( $block['attrs']['categories'] ) &&
230 is_string( $block['attrs']['categories'] )
231 ) {
232 $block['attrs']['categories'] = array(
233 array( 'id' => absint( $block['attrs']['categories'] ) ),
234 );
235 }
236
237 return $block;
238 }
239 add_filter( 'render_block_data', 'gutenberg_block_core_latest_posts_migrate_categories' );
240