feat(forum): rebuild plate, post and compose pages
Match the reference layouts for the remaining forum routes: plate pages get the blurred header card, moderator row and the affix tab bar with per-tab filtering, topping posts and moderator-only pending/trash tabs; post pages get the article shell with breadcrumbs, cover, meta row, vote box, tag row and footer actions; compose pages get the reference editor plus settings sidebar (submit/draft, status, access, plate, topic, tag, type, vote) with a cover picker. Saving now honours draft state and the featured image through the REST contract. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
eceddb5f7d
commit
5d3358d844
13 files changed
+891
-199
No files matched your search
+55
-2
@@ -73,8 +73,61 @@ final class Cards {
|
||||
return '<h2 class="' . esc_attr($class) . '"><a' . $link_class . ' href="' . esc_url($url) . '" title="' . esc_attr($post->post_title) . '">' . $badges . esc_html($post->post_title) . '</a></h2>';
|
||||
}
|
||||
|
||||
public static function plate_item(\WP_Post $plate): string {
|
||||
$url = get_permalink($plate);
|
||||
/** Plate page header: blurred cover, title, stats and moderators (reference layout). */
|
||||
public static function plate_header(\WP_Post $plate): string {
|
||||
$id = $plate->ID;
|
||||
PlateStats::prime([$id]);
|
||||
$stats = PlateStats::get($id);
|
||||
$followers = (int) get_post_meta($id, '_jio_forum_follow_count', true);
|
||||
$plate_name = (string) jio_get_setting('jio_forum_plate_name', '版块') ?: '版块';
|
||||
$thumb = self::thumbnail($plate);
|
||||
$cats = '';
|
||||
$terms = wp_get_post_terms($id, Core::CATEGORY);
|
||||
foreach (is_array($terms) ? $terms : [] as $term) {
|
||||
$cats .= '<a class="badg badg-sm b-theme" href="' . esc_url(get_term_link($term)) . '">' . esc_html($term->name) . '</a>';
|
||||
}
|
||||
$meta = '<div class="px12-sm mt10"><item class="mate-posts mr10">' . esc_html(sprintf('%s %s', $plate_name, jio_cut_count($stats['posts']))) . '</item>'
|
||||
. '<item class="mate-reply mr10">' . esc_html(sprintf('今日 %s', jio_cut_count($stats['today']))) . '</item>'
|
||||
. ($followers > 0
|
||||
? '<item class="mate-follow mr10">' . esc_html(sprintf('关注 %s', jio_cut_count($followers))) . '</item>'
|
||||
: '') . '</div>';
|
||||
$excerpt = wp_trim_words(wp_strip_all_tags($plate->post_excerpt ?: $plate->post_content), 40);
|
||||
$html = '<div class="plate-header-wrap"><div class="forum-header blur-header relative-h mb20">';
|
||||
$html .= '<div class="abs-blur-bg">' . $thumb . '</div><div class="absolute forum-mask"></div>';
|
||||
if (get_post_meta($id, '_jio_forum_hot', true)) {
|
||||
$html .= '<span class="img-badge top jb-red px12-sm">热门</span>';
|
||||
}
|
||||
$html .= '<div class="relative header-content"><div class="flex ac"><div class="item-info flex1">';
|
||||
if ($cats !== '') $html .= '<div class="mb6">' . $cats . '</div>';
|
||||
$html .= '<h1 class="forum-title em14"><a href="' . esc_url(get_permalink($plate)) . '">' . esc_html($plate->post_title) . '</a></h1>';
|
||||
$html .= $meta;
|
||||
if ($excerpt !== '') $html .= '<div class="desc px12-sm mt6">' . esc_html($excerpt) . '</div>';
|
||||
$html .= '</div><div class="plate-thumb flex0 ml10">' . $thumb . '</div></div>';
|
||||
$html .= self::plate_moderator_btns($plate);
|
||||
return $html . '</div></div></div>';
|
||||
}
|
||||
|
||||
/** Plate moderator avatars row under the header. */
|
||||
private static function plate_moderator_btns(\WP_Post $plate): string {
|
||||
$ids = array_values(array_unique(array_filter(array_merge(
|
||||
[(int) $plate->post_author],
|
||||
array_map('absint', (array) get_post_meta($plate->ID, '_jio_forum_moderators', true))
|
||||
))));
|
||||
if (!$ids) return '';
|
||||
$btns = '';
|
||||
foreach ($ids as $user_id) {
|
||||
$user = get_userdata($user_id);
|
||||
if (!$user) continue;
|
||||
$btns .= '<a class="but c-white mr6 mt6" href="' . esc_url(get_author_posts_url($user_id)) . '" title="' . esc_attr($user->display_name) . '"><span class="avatar-mini avatar-img">' . get_avatar($user_id, 40) . '</span><span class="ml6">' . esc_html($user->display_name) . '</span></a>';
|
||||
}
|
||||
$html = '<div class="mt10 moderator-btns em09">' . $btns;
|
||||
if (is_user_logged_in() && !Access::is_moderator(get_current_user_id(), $plate->ID) && jio_get_setting('jio_forum_moderator_apply', true)) {
|
||||
$html .= '<button type="button" class="but hollow c-white mt6" data-forum-action="apply" data-id="' . (int) $plate->ID . '">申请版主</button>';
|
||||
}
|
||||
return $html . '</div>';
|
||||
}
|
||||
|
||||
public static function plate_item(\WP_Post $plate): string { $url = get_permalink($plate);
|
||||
$counts = PlateStats::get($plate->ID);
|
||||
$today = $counts['today'] > 0 ? '<span class="badg but-plate hide-sm flex0" title="' . esc_attr(sprintf('今日新帖 %d', $counts['today'])) . '"><i class="fa fas fa-comment-dots c-red mr3"></i>' . esc_html(sprintf('今日:%s', jio_cut_count($counts['today']))) . '</span>' : '';
|
||||
$excerpt = wp_trim_words(wp_strip_all_tags($plate->post_excerpt ?: $plate->post_content), 30);
|
||||
|
||||
Reference in new issue
Block a user