v1.5 — 微言评论 + Photo 画廊

微言评论:
- 需登录后留言,未登录提示
- PHP 后端渲染评论,本地证件照头像
- 平级评论 + @回复引用
- 时间线 ASC 排列
- 评论无需审核直接显示
- tucao 禁用单独详情页
- 评论后锚点定位回列表

Photo 画廊:
- 灯箱全屏查看,多图左右切换
- 单图/边界隐藏方向键
- 图片去重
- 顶部显示标题·作者
This commit is contained in:
2026-05-04 02:35:58 +08:00
parent 55cfd26162
commit 58ef5f2635
3 changed files with 107 additions and 14 deletions
+32 -11
View File
@@ -1,6 +1,6 @@
<?php <?php
/** /**
* 微言归档页 — 带评论 * 微言归档页 — 带 AJAX 评论 + 登录验证
*/ */
get_header(); get_header();
?> ?>
@@ -19,22 +19,38 @@ get_header();
<span class="tucao-time"><?php echo get_the_time('Y-m-d H:i'); ?></span> <span class="tucao-time"><?php echo get_the_time('Y-m-d H:i'); ?></span>
</div> </div>
<div class="tucao-body"><?php the_content(); ?></div> <div class="tucao-body"><?php the_content(); ?></div>
<?php <?php $comment_count = get_comments_number(); ?>
$comment_count = get_comments_number(); <span class="tucao-comments-toggle" onclick="var el=document.getElementById('tucao-comments-<?php the_ID(); ?>'); el.classList.toggle('open');">💬 <?php echo $comment_count; ?> 条留言</span>
?>
<span class="tucao-comments-toggle" onclick="document.getElementById('tucao-comments-<?php the_ID(); ?>').classList.toggle('open')">💬 <?php echo $comment_count; ?> 条留言</span>
<div class="tucao-comments" id="tucao-comments-<?php the_ID(); ?>"> <div class="tucao-comments" id="tucao-comments-<?php the_ID(); ?>">
<?php <?php
$comments = get_comments(array('post_id' => get_the_ID(), 'status' => 'approve')); $comments = get_comments(array('post_id' => get_the_ID(), 'status' => 'approve', 'order' => 'ASC'));
foreach ($comments as $c) { foreach ($comments as $c) :
echo '<div class="tucao-comment"><span class="tucao-comment-author">' . esc_html($c->comment_author) . '</span> · ' . esc_html($c->comment_date) . '<br>' . esc_html($c->comment_content) . '</div>'; $reply_to = $c->comment_parent ? get_comment($c->comment_parent) : null;
}
?> ?>
<form action="<?php echo site_url('/wp-comments-post.php'); ?>" method="post" class="tucao-comment-form"> <div class="tucao-comment">
<div class="tucao-comment-meta">
<?php echo get_avatar($c, 16, '', '', array('class' => 'tucao-comment-avatar')); ?>
<span class="tucao-comment-author"><?php echo esc_html($c->comment_author); ?></span>
<?php if ($reply_to) : ?>
<span class="tucao-reply-to">回复 @<?php echo esc_html($reply_to->comment_author); ?></span>
<?php endif; ?>
<span class="tucao-comment-time"><?php echo get_comment_date('Y-m-d H:i:s', $c); ?></span>
</div>
<div class="tucao-comment-text"><?php echo esc_html($c->comment_content); ?></div>
</div>
<?php endforeach; ?>
<div class="tucao-comment-form-wrap">
<?php if (is_user_logged_in()) : ?>
<form class="tucao-comment-form" method="post" action="<?php echo site_url('/wp-comments-post.php'); ?>">
<input type="hidden" name="comment_post_ID" value="<?php the_ID(); ?>"> <input type="hidden" name="comment_post_ID" value="<?php the_ID(); ?>">
<input type="text" name="comment" placeholder="说点什么..."> <input type="hidden" name="comment_parent" value="0" class="tucao-reply-parent">
<input type="text" name="comment" placeholder="说点什么..." required>
<button type="submit">落笔</button> <button type="submit">落笔</button>
</form> </form>
<?php else : ?>
<p class="tucao-login-hint"><a href="/wp-login.php">登录</a>后可留言</p>
<?php endif; ?>
</div>
</div> </div>
</div> </div>
<?php endwhile; ?> <?php endwhile; ?>
@@ -45,4 +61,9 @@ get_header();
<p style="color:var(--ink-lighter);text-align:center;padding:60px 0;">暂无微言</p> <p style="color:var(--ink-lighter);text-align:center;padding:60px 0;">暂无微言</p>
<?php endif; ?> <?php endif; ?>
<!-- 评论时间本地化脚本 -->
<script>
// 已改为 PHP 后端渲染,不需要 AJAX
</script>
<?php get_footer(); ?> <?php get_footer(); ?>
+34
View File
@@ -146,6 +146,14 @@ add_filter('get_avatar', function($avatar, $id_or_email, $size, $default, $alt)
$uid = 0; $uid = 0;
if (is_numeric($id_or_email)) $uid = (int) $id_or_email; if (is_numeric($id_or_email)) $uid = (int) $id_or_email;
elseif (is_object($id_or_email) && isset($id_or_email->user_id)) $uid = (int) $id_or_email->user_id; elseif (is_object($id_or_email) && isset($id_or_email->user_id)) $uid = (int) $id_or_email->user_id;
elseif (is_object($id_or_email) && $id_or_email instanceof WP_Comment) {
$uid = (int) $id_or_email->user_id;
}
// 如果传的是 email 但找不到用户,尝试用 email 找
if (!$uid && is_string($id_or_email) && strpos($id_or_email, '@') !== false) {
$u = get_user_by('email', $id_or_email);
if ($u) $uid = $u->ID;
}
$att_id = get_user_meta($uid, 'custom_avatar', true); $att_id = get_user_meta($uid, 'custom_avatar', true);
if ($att_id) { if ($att_id) {
$url = wp_get_attachment_image_url($att_id, 'medium'); $url = wp_get_attachment_image_url($att_id, 'medium');
@@ -232,3 +240,29 @@ add_action('init', function() {
add_rewrite_rule('^photo/([0-9]+)/([^/]+)/?$', 'index.php?post_type=photo&p=$matches[1]', 'top'); add_rewrite_rule('^photo/([0-9]+)/([^/]+)/?$', 'index.php?post_type=photo&p=$matches[1]', 'top');
add_rewrite_rule('^photo/([0-9]+)/?$', 'index.php?post_type=photo&p=$matches[1]', 'top'); add_rewrite_rule('^photo/([0-9]+)/?$', 'index.php?post_type=photo&p=$matches[1]', 'top');
}); });
// 允许通过 REST API 创建评论
add_filter('rest_allow_anonymous_comments', '__return_false');
// 评论后重定向回当前页
// tucao 不要详情页,直接回 archive
add_action('template_redirect', function() {
if (is_singular('tucao')) {
wp_redirect(get_post_type_archive_link('tucao'), 301);
exit;
}
});
// 评论后送回微言列表并锚点定位
add_filter('comment_post_redirect', function($loc, $comment) {
$post = get_post($comment->comment_post_ID);
if ($post && $post->post_type === 'tucao') {
return get_post_type_archive_link('tucao') . '#tucao-' . $comment->comment_post_ID;
}
return $loc;
}, 99, 2);
// 中国时区
date_default_timezone_set('Asia/Shanghai');
+38
View File
@@ -488,3 +488,41 @@ echo "done"
.photo-lightbox__content img { border-radius: 6px; } .photo-lightbox__content img { border-radius: 6px; }
.tucao-login-hint { font-size: 12px; color: var(--ink-lighter); margin-top: 12px; }
.tucao-login-hint a { color: var(--cinnabar); }
.tucao-comment { display:flex; gap:8px; align-items:flex-start; padding:8px 0; }
.tucao-comment-avatar { width:22px !important; height:22px !important; border-radius:50% !important; object-fit:cover !important; flex-shrink:0; }
.tucao-comment-time { font-size:11px; color:var(--ink-lighter); margin-left:4px; }
.tucao-comment-text { font-size:13px; color:var(--ink-light); line-height:1.6; margin-top:2px; }
.tucao-comment-body { flex:1; }
.tucao-comment-author { font-size:13px; font-weight:600; }
.tucao-comment-avatar { border-radius:50% !important; }
.tucao-comment { align-items: baseline; }
.tucao-comment-avatar { position: relative; top: 3px; }
.tucao-comment-body { line-height: 16px; }
.tucao-comment-avatar { top: 0 !important; width:16px !important; height:16px !important; }
.tucao-comment { padding:6px 0; }
.tucao-comment-meta { display:flex; align-items:center; gap:6px; margin-bottom:4px; }
.tucao-comment-meta > img { width:16px !important; height:16px !important; border-radius:50% !important; object-fit:cover !important; flex-shrink:0; }
.tucao-comment-meta { display:flex; align-items:baseline; gap:6px; }
.tucao-comment-time { font-size:11px; color:var(--ink-lighter); }
.tucao-comment-author { font-size:13px; font-weight:600; }
.tucao-comment-time { font-size:11px; color:var(--ink-lighter); }
.tucao-comment-text { font-size:13px; color:var(--ink-light); line-height:1.6; margin-left:22px; }
.tucao-comment { padding:6px 0; border-bottom:1px dashed var(--border-light); display:block !important; }
.tucao-comment:last-child { border-bottom:none; }
.tucao-comment-meta { display:flex !important; align-items:center !important; gap:6px; margin-bottom:2px; }
.tucao-comment-meta > img { width:16px !important; height:16px !important; border-radius:50% !important; object-fit:cover !important; flex-shrink:0; }
.tucao-comment-author { font-size:13px; font-weight:600; }
.tucao-comment-time { font-size:11px; color:var(--ink-lighter); }
.tucao-comment-text { display:block; font-size:13px; color:var(--ink-light); line-height:1.6; margin-left:22px; }
.tucao-reply-to { font-size:11px; color:var(--cinnabar); margin:0 2px; }