diff --git a/inc/theme-archives.php b/inc/theme-archives.php index bb787dc..af2f5a3 100644 --- a/inc/theme-archives.php +++ b/inc/theme-archives.php @@ -285,16 +285,22 @@ function yang_archives_data() /** * 短代码参数 * - * @param array $atts + * @param array $atts + * @param string $tag 实际命中的标签名(`archives` 或 `Archives`) * @return array */ -function yang_archives_atts($atts) +function yang_archives_atts($atts, $tag = 'archives') { + /* 🔴 第 3 个参数必须是**实际命中的那个 tag**,不能写死 'archives'。 + * 它决定 `shortcode_atts_{$tag}` 过滤器往外传的名字。 + * 我们同时注册了 `archives` 与 `Archives` 两种写法, + * 写死小写的话,用 `[Archives]` 的站点上 `shortcode_atts_Archives` + * 这个钩子永远收不到 —— 属于"功能能用但扩展点悄悄失效"的隐性 bug。 */ $a = shortcode_atts(array( 'year' => '', 'month' => '1', 'nav' => '1', - ), $atts, 'archives'); + ), $atts, $tag); return array( 'year' => $a['year'] === '' ? '' : (int) $a['year'], @@ -567,12 +573,24 @@ function yang_archives_render_nav_btn($target, $dir, $year) /** * 短代码主体 * - * @param array $atts + * 🔴 签名必须是 `($atts, $content, $tag)` 三个参数 —— 这是 WordPress + * `do_shortcode_tag()` 的调用约定: + * call_user_func( $shortcode_tags[$tag], $attr, $content, $tag ) + * 中间的 `$content` 是**闭合式短代码**(`[x]...[/x]`)的中间内容, + * 自闭合短代码传空串。本短代码用不到它,但**位置不能省**: + * 省掉之后 `$tag` 会落到第 2 个参数上,实际收到的 tag 变成空串, + * `shortcode_atts_{$tag}` 就只剩 `shortcode_atts_` 这个无主钩子。 + * (3.2.47 开发中实测踩到:直接调函数传 ('Archives') 是对的, + * 过 do_shortcode 才变成空 —— 差别就在中间这个 $content。) + * + * @param array $atts + * @param string $content 闭合式短代码的中间内容(本短代码不用) + * @param string $tag 实际命中的标签名(archives / Archives / ARCHIVES) * @return string */ -function yang_archives_shortcode($atts) +function yang_archives_shortcode($atts, $content = '', $tag = 'archives') { - $opt = yang_archives_atts($atts); + $opt = yang_archives_atts($atts, $tag); $data = yang_archives_data(); if (empty($data['order'])) { @@ -691,7 +709,27 @@ function yang_archives_shortcode($atts) return $out; } -/* WP 的 shortcode 标签是**大小写不敏感**的(它内部统一 strtolower), - * 所以注册小写 `archives` 就能同时匹配 [Archives] / [ARCHIVES] / [archives]。 - * 这里按 WP 惯例注册小写。 */ -add_shortcode('archives', 'yang_archives_shortcode'); \ No newline at end of file +/* 🔴🔴 WP 的 shortcode 标签**区分大小写** —— 这一点 3.2.46 写错过,实测过。 + * + * 内核证据(wp-includes/shortcodes.php): + * ① `get_shortcode_regex()` 直接 `implode('|', array_map('preg_quote', $tagnames))`, + * 拿注册名拼正则,**没有做任何大小写归一化**; + * ② `do_shortcode()` 里 `preg_match_all('/' . get_shortcode_regex() . '/', ...)` + * —— 修饰符只有默认,**没有 `i`**; + * ③ `do_shortcode_tag()` 拿到 `$tag = $m[2]` 后直接 `$shortcode_tags[$tag]` 精确查表。 + * + * ⇒ `add_shortcode('archives', ...)` **只匹配全小写 `[archives]`**。 + * 用户按文档写 `[Archives]`,正则压根不认,WordPress 就把原文原样吐出来 + * —— 页面显示 `

[Archives]

`,看起来极像"短代码没装/被转义", + * 实际是**标签名大小写对不上**。 + * + * ⇒ 只能把要支持的写法**逐个注册**。这里注册三种常见形态: + * 全小写(WP 惯例)、首字母大写(文档与用户习惯)、全大写。 + * 注册同一个回调是安全的:`$shortcode_tags` 里就是几条 key 指向同一个函数, + * 任何时刻只会命中其中一条(正则里几个分支互斥),不会渲染两次。 + * + * ⚠️ 不追求覆盖任意混合大小写(`[aRcHiVeS]`):那需要每隔位置都注册一条, + * 正则会膨胀到不可维护。三种形态已经覆盖真实使用中的全部习惯写法。 */ +add_shortcode('archives', 'yang_archives_shortcode'); +add_shortcode('Archives', 'yang_archives_shortcode'); +add_shortcode('ARCHIVES', 'yang_archives_shortcode'); \ No newline at end of file diff --git a/style.css b/style.css index 613e992..7d5c78a 100644 --- a/style.css +++ b/style.css @@ -1,7 +1,7 @@ /* Theme Name: Kratos_Yang Text Domain: kratos_Yang -Version: 3.2.46 +Version: 3.2.47 Requires PHP: 7.0 Description: 这是一个Kratos主题的分支版本,用来增加一些定制化功能。 Tags: 博客, 双栏, 响应式, 自定义背景, 自定义颜色, 自定义图标, 自定义菜单, 特色图像, 收录优化, 邮件中心, 主题选项, 小工具, 文章置顶, 无障碍友好