3.2.18: 清明按节气换算、主题内 [TOC] 目录、重建评论区替代 wpDiscuz
三项功能:
1. 清明不再用固定 04-04
清明是节气,日期在 4/4~4/6 之间浮动。硬编码 04-04 实测 1900-2100
共 201 年里只有 76 年是对的(约 38%)。改为内嵌逐年表换算真实日期,
超出 1900-2100 返回 null 明确放弃,不退化成近似值。
兼容 3.2.17 及以前勾过的 '04-04' 键,升级后勾选不会被静默丢弃。
2. 主题内实现 [TOC]
文章里写 [TOC],该位置输出本文目录,点击跳到对应标题。
在 the_content 优先级 9 处理(早于 wpautop 10 / do_shortcode 11),
保证"补 id"与"扫目录"用的是同一份文本,href 与 id 必然对得上。
嵌套用深度归一化,h1→h3 跳级不会算错层级。
scroll-margin-top 声明式让位,原生锚点/外部 #hash/后退全都生效。
3. 重建评论区
旧实现的问题:列表渲染与 AJAX 渲染各写一份 HTML,已经分叉
(AJAX 返回的新评论没有回复按钮);<li> 被 <div> 包着,嵌套回复错位。
现在统一到 yang_comment_html() 单一渲染函数,列表与 AJAX 只差一个
is-new 类。同时修掉三处真实缺陷:
· 评论项用 flex 会把 <ol class="yang-children"> 当成第三个 flex 项,
子评论跑到父评论右侧、正文被挤到 156px、页面横向溢出 75px —— 改 grid
· 成功提示在 exitReplyMode() 之前设置,被其末尾的 setStatus('','')
擦掉,用户提交成功却看不到反馈 —— 调整顺序
· 窄屏媒体查询打不过深层选择器(媒体查询不增加特异性),
嵌套头像反向变大 —— 补深层覆盖
与 wpDiscuz 解耦:邮件模块不再无条件 return false(那等于永久关掉
notify_postauthor 且不报错);插件在场时不加载主题评论资源,
避免双份表单互抢。
验证:PHP 语法 73/73;_static_qingming 36、_test_toc 53、
_test_comments 62、_test_comments_falsify 17、
_toc_geometry 121、_toc_geometry_falsify 9、
_comments_geometry 98、_comments_geometry_falsify 23,全部 0 失败。
线上端到端 29/0(真实文章渲染目录 + 真实评论数据渲染)。
This commit is contained in:
+62
-3
@@ -221,7 +221,7 @@ function yang_mail_short_circuit($return, $atts)
|
||||
add_filter('pre_wp_mail', 'yang_mail_short_circuit', 10, 2);
|
||||
|
||||
/**
|
||||
* 关掉核心的重复通知
|
||||
* 关掉核心的重复通知(**仅在 wpDiscuz 存在时**)
|
||||
*
|
||||
* ── 为什么要关 ──
|
||||
* 站点用了 wpDiscuz,评论通知由插件负责(它能带订阅、退订链接、
|
||||
@@ -237,12 +237,27 @@ add_filter('pre_wp_mail', 'yang_mail_short_circuit', 10, 2);
|
||||
* ── 只关通知,不关审核 ──
|
||||
* 注意这里只拦 `notify_*` 两个 filter,评论审核流程(comment_moderation)
|
||||
* 完全不受影响,评论该进待审还是进待审。
|
||||
*
|
||||
* ── 🔴 3.2.18:插件不在时必须放行 ─────────────────────────────
|
||||
* 这一条是卸载 wpDiscuz 时最容易出的事故:
|
||||
* 原来无条件返回 false,等于永久关掉核心的「有新评论通知作者」。
|
||||
* 插件在时无所谓(插件自己会发);插件一卸,就没有任何东西通知作者了。
|
||||
* 而主题自带的 yang_notify_comment_reply() 只处理**回复**场景
|
||||
* ($comment_parent > 0),顶层新评论仍然依赖核心的 notify_postauthor。
|
||||
* 两者叠加的结果是:作者从此收不到任何新评论邮件,且没有任何报错,
|
||||
* 只有"怎么一直没邮件"这种模糊现象。
|
||||
*
|
||||
* 所以这里的判据必须跟着插件走,而不是"只要开了 SMTP 就关"。
|
||||
*/
|
||||
function yang_mail_disable_core_notify($maybe, $comment_id)
|
||||
{
|
||||
if (!yang_mail_smtp_ready()) {
|
||||
return $maybe;
|
||||
}
|
||||
// 没有插件接管 → 核心通知是唯一的顶层评论通知渠道,必须放行
|
||||
if (!yang_mail_wpdiscuz_present()) {
|
||||
return $maybe;
|
||||
}
|
||||
// 用户在主题选项里可以保留核心通知(默认关)
|
||||
if (kratos_option('m_keep_core_notify', false)) {
|
||||
return $maybe;
|
||||
@@ -329,12 +344,35 @@ function yang_mail_send_test($to = null)
|
||||
* 解法:把 `&` 全部预编码成 `&`。这样插件解码一次之后,
|
||||
* 恰好还原成我们想要的转义状态(decode("&lt;") === "<")。
|
||||
* 只处理 `&` 就够,因为其它实体的风险都源于 `&` 被还原。
|
||||
*
|
||||
* ── 3.2.18:这个函数只在插件存在时才能用 ─────────────────────
|
||||
* 主题现在自带评论通知(inc/theme-comments.php),不再依赖插件。
|
||||
* 如果这里无条件做 `&` 预编码,而没有插件去 decode 那一次,
|
||||
* 收件人看到的邮件正文里就会出现字面的 `&lt;`、`&nbsp;`
|
||||
* —— 比安全风险更常见的实际故障,而且极难联想到原因。
|
||||
*
|
||||
* 所以调用点必须先判断插件在不在。见下方两个 add_filter 的包裹。
|
||||
*/
|
||||
function yang_mail_escape_for_wpdiscuz($html)
|
||||
{
|
||||
return str_replace('&', '&', $html);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前是否有 wpDiscuz 在接管评论邮件
|
||||
*
|
||||
* 单独抽出来,是因为 theme-mail.php 加载早于 theme-comments.php
|
||||
* 时(子主题调整了 require 顺序)`yang_comments_plugin_active()`
|
||||
* 可能还不存在 —— 这时退回自己探测,不能让后台白屏。
|
||||
*/
|
||||
function yang_mail_wpdiscuz_present()
|
||||
{
|
||||
if (function_exists('yang_comments_plugin_active')) {
|
||||
return yang_comments_plugin_active();
|
||||
}
|
||||
return class_exists('WpdiscuzCore') || function_exists('wpdiscuz');
|
||||
}
|
||||
|
||||
/**
|
||||
* 把 wpDiscuz 的通知邮件接管成主题模板
|
||||
*
|
||||
@@ -351,6 +389,17 @@ function yang_mail_escape_for_wpdiscuz($html)
|
||||
* 上面那两段引用,正文骨架完全一样。做成两套模板会立刻分叉,
|
||||
* 以后改一次配色要改两处。
|
||||
*
|
||||
* ── 3.2.18:这整段只在装了 wpDiscuz 时才注册 ─────────────────
|
||||
* 主题已经自带评论通知(inc/theme-comments.php)。若插件不存在,
|
||||
* 这两个 `wpdiscuz_*` 过滤器永远不会被触发 —— 注册了也是死代码,
|
||||
* 但它们会让人误以为"邮件通知依赖插件",日后维护时是个陷阱。
|
||||
* 更实际的问题:这些函数内部调用 yang_mail_escape_for_wpdiscuz()
|
||||
* 做 `&` 预编码,那是专门给插件多一次 decode 用的;没有插件时
|
||||
* 一旦被别处误调,邮件里就会出现字面的 &lt;。
|
||||
*
|
||||
* 所以整个注册包在 if 里。插件卸载后,通知自动由主题接管,
|
||||
* 用户不需要改任何配置。
|
||||
*
|
||||
* @param string $message 插件生成的 HTML(丢弃)
|
||||
* @param WP_Comment $comment 新评论
|
||||
* @param array $email_data 订阅记录
|
||||
@@ -418,7 +467,14 @@ function yang_mail_render_comment_notify($message, $comment, $email_data = array
|
||||
|
||||
return yang_mail_escape_for_wpdiscuz($body);
|
||||
}
|
||||
add_filter('wpdiscuz_email_content', 'yang_mail_render_comment_notify', 20, 3);
|
||||
|
||||
/* 只在插件确实存在时挂这两个过滤器。
|
||||
插件不在时(用户按 3.2.18 的建议卸载了),评论通知由
|
||||
inc/theme-comments.php 的 yang_notify_comment_reply() /
|
||||
yang_notify_comment_approved() 接管,发的是**不预编码**的正文。 */
|
||||
if (yang_mail_wpdiscuz_present()) {
|
||||
add_filter('wpdiscuz_email_content', 'yang_mail_render_comment_notify', 20, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* 审核通过通知也套同一套模板
|
||||
@@ -449,4 +505,7 @@ function yang_mail_render_approved_notify($message, $post_id, $email)
|
||||
'note' => __('这是评论审核结果通知,无需回复。', 'kratos'),
|
||||
)));
|
||||
}
|
||||
add_filter('wpdiscuz_comment_approved_email_content', 'yang_mail_render_approved_notify', 20, 3);
|
||||
|
||||
if (yang_mail_wpdiscuz_present()) {
|
||||
add_filter('wpdiscuz_comment_approved_email_content', 'yang_mail_render_approved_notify', 20, 3);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user