author | ymh <ymh.work@gmail.com> |
Mon, 08 Sep 2025 19:44:41 +0200 | |
changeset 23 | 417f20492bf7 |
parent 21 | 48c4eec2b7e6 |
permissions | -rw-r--r-- |
9 | 1 |
<?php |
2 |
/** |
|
3 |
* Server-side rendering of the `core/latest-comments` block. |
|
4 |
* |
|
5 |
* @package WordPress |
|
6 |
*/ |
|
7 |
||
8 |
/** |
|
9 |
* Get the post title. |
|
10 |
* |
|
11 |
* The post title is fetched and if it is blank then a default string is |
|
12 |
* returned. |
|
13 |
* |
|
14 |
* Copied from `wp-admin/includes/template.php`, but we can't include that |
|
15 |
* file because: |
|
16 |
* |
|
17 |
* 1. It causes bugs with test fixture generation and strange Docker 255 error |
|
18 |
* codes. |
|
19 |
* 2. It's in the admin; ideally we *shouldn't* be including files from the |
|
20 |
* admin for a block's output. It's a very small/simple function as well, |
|
21 |
* so duplicating it isn't too terrible. |
|
22 |
* |
|
23 |
* @since 3.3.0 |
|
24 |
* |
|
25 |
* @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post. |
|
26 |
* @return string The post title if set; "(no title)" if no title is set. |
|
27 |
*/ |
|
28 |
function wp_latest_comments_draft_or_post_title( $post = 0 ) { |
|
29 |
$title = get_the_title( $post ); |
|
30 |
if ( empty( $title ) ) { |
|
31 |
$title = __( '(no title)' ); |
|
32 |
} |
|
19 | 33 |
return $title; |
9 | 34 |
} |
35 |
||
36 |
/** |
|
37 |
* Renders the `core/latest-comments` block on server. |
|
38 |
* |
|
21
48c4eec2b7e6
Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
19
diff
changeset
|
39 |
* @since 5.1.0 |
48c4eec2b7e6
Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
19
diff
changeset
|
40 |
* |
9 | 41 |
* @param array $attributes The block attributes. |
42 |
* |
|
43 |
* @return string Returns the post content with latest comments added. |
|
44 |
*/ |
|
45 |
function render_block_core_latest_comments( $attributes = array() ) { |
|
46 |
$comments = get_comments( |
|
19 | 47 |
/** This filter is documented in wp-includes/widgets/class-wp-widget-recent-comments.php */ |
9 | 48 |
apply_filters( |
49 |
'widget_comments_args', |
|
50 |
array( |
|
51 |
'number' => $attributes['commentsToShow'], |
|
52 |
'status' => 'approve', |
|
53 |
'post_status' => 'publish', |
|
19 | 54 |
), |
55 |
array() |
|
9 | 56 |
) |
57 |
); |
|
58 |
||
59 |
$list_items_markup = ''; |
|
60 |
if ( ! empty( $comments ) ) { |
|
61 |
// Prime the cache for associated posts. This is copied from \WP_Widget_Recent_Comments::widget(). |
|
62 |
$post_ids = array_unique( wp_list_pluck( $comments, 'comment_post_ID' ) ); |
|
63 |
_prime_post_caches( $post_ids, strpos( get_option( 'permalink_structure' ), '%category%' ), false ); |
|
64 |
||
65 |
foreach ( $comments as $comment ) { |
|
66 |
$list_items_markup .= '<li class="wp-block-latest-comments__comment">'; |
|
67 |
if ( $attributes['displayAvatar'] ) { |
|
68 |
$avatar = get_avatar( |
|
69 |
$comment, |
|
70 |
48, |
|
71 |
'', |
|
72 |
'', |
|
73 |
array( |
|
74 |
'class' => 'wp-block-latest-comments__comment-avatar', |
|
75 |
) |
|
76 |
); |
|
77 |
if ( $avatar ) { |
|
78 |
$list_items_markup .= $avatar; |
|
79 |
} |
|
80 |
} |
|
81 |
||
82 |
$list_items_markup .= '<article>'; |
|
83 |
$list_items_markup .= '<footer class="wp-block-latest-comments__comment-meta">'; |
|
84 |
$author_url = get_comment_author_url( $comment ); |
|
85 |
if ( empty( $author_url ) && ! empty( $comment->user_id ) ) { |
|
86 |
$author_url = get_author_posts_url( $comment->user_id ); |
|
87 |
} |
|
88 |
||
89 |
$author_markup = ''; |
|
90 |
if ( $author_url ) { |
|
91 |
$author_markup .= '<a class="wp-block-latest-comments__comment-author" href="' . esc_url( $author_url ) . '">' . get_comment_author( $comment ) . '</a>'; |
|
92 |
} else { |
|
93 |
$author_markup .= '<span class="wp-block-latest-comments__comment-author">' . get_comment_author( $comment ) . '</span>'; |
|
94 |
} |
|
95 |
||
96 |
// `_draft_or_post_title` calls `esc_html()` so we don't need to wrap that call in |
|
97 |
// `esc_html`. |
|
98 |
$post_title = '<a class="wp-block-latest-comments__comment-link" href="' . esc_url( get_comment_link( $comment ) ) . '">' . wp_latest_comments_draft_or_post_title( $comment->comment_post_ID ) . '</a>'; |
|
99 |
||
100 |
$list_items_markup .= sprintf( |
|
101 |
/* translators: 1: author name (inside <a> or <span> tag, based on if they have a URL), 2: post title related to this comment */ |
|
102 |
__( '%1$s on %2$s' ), |
|
103 |
$author_markup, |
|
104 |
$post_title |
|
105 |
); |
|
106 |
||
107 |
if ( $attributes['displayDate'] ) { |
|
108 |
$list_items_markup .= sprintf( |
|
109 |
'<time datetime="%1$s" class="wp-block-latest-comments__comment-date">%2$s</time>', |
|
110 |
esc_attr( get_comment_date( 'c', $comment ) ), |
|
111 |
date_i18n( get_option( 'date_format' ), get_comment_date( 'U', $comment ) ) |
|
112 |
); |
|
113 |
} |
|
114 |
$list_items_markup .= '</footer>'; |
|
115 |
if ( $attributes['displayExcerpt'] ) { |
|
116 |
$list_items_markup .= '<div class="wp-block-latest-comments__comment-excerpt">' . wpautop( get_comment_excerpt( $comment ) ) . '</div>'; |
|
117 |
} |
|
118 |
$list_items_markup .= '</article></li>'; |
|
119 |
} |
|
120 |
} |
|
121 |
||
18 | 122 |
$classnames = array(); |
9 | 123 |
if ( $attributes['displayAvatar'] ) { |
18 | 124 |
$classnames[] = 'has-avatars'; |
9 | 125 |
} |
126 |
if ( $attributes['displayDate'] ) { |
|
18 | 127 |
$classnames[] = 'has-dates'; |
9 | 128 |
} |
129 |
if ( $attributes['displayExcerpt'] ) { |
|
18 | 130 |
$classnames[] = 'has-excerpts'; |
9 | 131 |
} |
132 |
if ( empty( $comments ) ) { |
|
18 | 133 |
$classnames[] = 'no-comments'; |
9 | 134 |
} |
18 | 135 |
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => implode( ' ', $classnames ) ) ); |
9 | 136 |
|
16 | 137 |
return ! empty( $comments ) ? sprintf( |
18 | 138 |
'<ol %1$s>%2$s</ol>', |
139 |
$wrapper_attributes, |
|
9 | 140 |
$list_items_markup |
141 |
) : sprintf( |
|
18 | 142 |
'<div %1$s>%2$s</div>', |
143 |
$wrapper_attributes, |
|
9 | 144 |
__( 'No comments to show.' ) |
145 |
); |
|
146 |
} |
|
147 |
||
16 | 148 |
/** |
149 |
* Registers the `core/latest-comments` block. |
|
21
48c4eec2b7e6
Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
19
diff
changeset
|
150 |
* |
48c4eec2b7e6
Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
19
diff
changeset
|
151 |
* @since 5.3.0 |
16 | 152 |
*/ |
153 |
function register_block_core_latest_comments() { |
|
154 |
register_block_type_from_metadata( |
|
155 |
__DIR__ . '/latest-comments', |
|
156 |
array( |
|
157 |
'render_callback' => 'render_block_core_latest_comments', |
|
158 |
) |
|
159 |
); |
|
160 |
} |
|
161 |
||
162 |
add_action( 'init', 'register_block_core_latest_comments' ); |