fix: 修复 /links 页面 500(th:attr 受限求值)并校正友链申请回执 (v1.1.11)
问题:GET /links 抛 TemplateProcessingException ——
"Instantiation of new objects and access to static classes or parameters is forbidden"
定位到 links.html 第 126 行第 978 列:
th:attr="value=${param.value != null and !#lists.isEmpty(param.value) ? param.value[0] : ''}"
Thymeleaf 对 th:attr 走受限表达式求值,禁止表达式对象的方法调用(#lists.isEmpty 等),
且校验发生在解析阶段,运行时短路(param.value 为 null)也救不了。同样的表达式
放在 th:with 里是合法的 —— 这正是本主题其他页面的既有写法。
修复:
- 全部取值逻辑移入 th:with(采用主题已验证写法 param?.x + x.length > 0 ? x[0] : null),
输出改用单值属性 th:value,彻底不在 th:attr 里放复杂表达式
- 校正申请回执语义:插件实际回跳参数是 applied=success|error|disabled,
另有 message / field / value(旧版误判为 applied=true)
- 统一单条提示:有 message 显示 message,否则成功文案
- applied=success 用强调色,error 用红色
- applied=disabled 时隐藏表单,保留「未开放」提示
- field/value 回填到对应输入框(displayName / url)
- 新增 .wi-links__apply-result--ok 样式
- 版本升至 1.1.11
同时沉淀校验:新增扫描脚本检查构建产物中 th:attr 是否含 #xxx. 方法调用 / new / T() / @bean,
全主题扫描结果为 0。
This commit is contained in:
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "1.1.10",
|
||||
"version": "1.1.11",
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": ">=22.12.0"
|
||||
|
||||
+63
-28
@@ -87,42 +87,66 @@ import Layout from "../layouts/Layout.astro";
|
||||
</div>
|
||||
</th:block>
|
||||
|
||||
<!--
|
||||
友链申请:表单 POST 到插件的 /links/apply/submit,插件以 303 回跳 /links,
|
||||
并带上 applied(success / error / disabled)、message、field、value 四个查询参数。
|
||||
|
||||
注意(踩过坑):th:attr 的赋值里不能调用 #lists 等表达式对象的方法,
|
||||
Thymeleaf 会对 th:attr 走受限求值并抛
|
||||
"Instantiation of new objects and access to static classes or parameters is forbidden"。
|
||||
取值逻辑一律先在 th:with 里算成变量,再用 th:value 之类的单值属性输出。
|
||||
-->
|
||||
<div
|
||||
class="wi-links__apply"
|
||||
th:if="${theme.config?.links?.links_apply_form_enabled != false}"
|
||||
th:with="applied=${param.applied != null and !#lists.isEmpty(param.applied) and param.applied[0] == 'true'},
|
||||
applyMsg=${param.message != null and !#lists.isEmpty(param.message) ? param.message[0] : null}"
|
||||
th:with="appliedList=${param?.applied},
|
||||
applied=${appliedList != null and appliedList.length > 0 ? appliedList[0] : null},
|
||||
messageList=${param?.message},
|
||||
applyMsg=${messageList != null and messageList.length > 0 ? messageList[0] : null},
|
||||
fieldList=${param?.field},
|
||||
applyField=${fieldList != null and fieldList.length > 0 ? fieldList[0] : null},
|
||||
valueList=${param?.value},
|
||||
applyValue=${valueList != null and valueList.length > 0 ? valueList[0] : null}"
|
||||
>
|
||||
<h2 class="wi-links__apply-title" th:text="'申请友链'">申请友链</h2>
|
||||
<p
|
||||
class="wi-links__apply-result"
|
||||
th:if="${applied}"
|
||||
th:text="'申请已提交,等待站长审核 🌙'"
|
||||
th:if="${applied != null}"
|
||||
th:classappend="${applied == 'success'} ? 'wi-links__apply-result--ok' : 'wi-links__apply-result--error'"
|
||||
th:text="${applyMsg != null ? applyMsg : '申请已提交,等待站长审核 🌙'}"
|
||||
role="status"
|
||||
></p>
|
||||
<p
|
||||
class="wi-links__apply-result wi-links__apply-result--error"
|
||||
th:if="${not applied and applyMsg != null}"
|
||||
th:text="${applyMsg}"
|
||||
role="alert"
|
||||
></p>
|
||||
|
||||
<form
|
||||
class="wi-links__apply-form"
|
||||
method="post"
|
||||
th:action="@{/links/apply/submit}"
|
||||
>
|
||||
<input type="hidden" name="_csrf" th:value="${csrfToken}" />
|
||||
<div class="wi-links__apply-row">
|
||||
<label class="wi-links__apply-field">
|
||||
<span th:text="'站点名称 *'">站点名称 *</span>
|
||||
<input type="text" name="displayName" required maxlength="50" placeholder="你的站点名称" th:attr="value=${param.value != null and !#lists.isEmpty(param.value) ? param.value[0] : ''}" />
|
||||
</label>
|
||||
<label class="wi-links__apply-field">
|
||||
<span th:text="'站点链接 *'">站点链接 *</span>
|
||||
<input type="url" name="url" required placeholder="https://" />
|
||||
</label>
|
||||
</div>
|
||||
<th:block th:unless="${applied == 'disabled'}">
|
||||
<form
|
||||
class="wi-links__apply-form"
|
||||
method="post"
|
||||
th:action="@{/links/apply/submit}"
|
||||
>
|
||||
<input type="hidden" name="_csrf" th:value="${csrfToken}" />
|
||||
<div class="wi-links__apply-row">
|
||||
<label class="wi-links__apply-field">
|
||||
<span th:text="'站点名称 *'">站点名称 *</span>
|
||||
<input
|
||||
type="text"
|
||||
name="displayName"
|
||||
required
|
||||
maxlength="50"
|
||||
placeholder="你的站点名称"
|
||||
th:value="${applyField == 'displayName' ? applyValue : null}"
|
||||
/>
|
||||
</label>
|
||||
<label class="wi-links__apply-field">
|
||||
<span th:text="'站点链接 *'">站点链接 *</span>
|
||||
<input
|
||||
type="url"
|
||||
name="url"
|
||||
required
|
||||
placeholder="https://"
|
||||
th:value="${applyField == 'url' ? applyValue : null}"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div class="wi-links__apply-row">
|
||||
<label class="wi-links__apply-field">
|
||||
<span th:text="'图标地址'">图标地址</span>
|
||||
@@ -164,8 +188,15 @@ import Layout from "../layouts/Layout.astro";
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<button class="wi-links__apply-submit" type="submit" th:text="'提交申请'">提交申请</button>
|
||||
</form>
|
||||
<button
|
||||
class="wi-links__apply-submit"
|
||||
type="submit"
|
||||
th:text="'提交申请'"
|
||||
>
|
||||
提交申请
|
||||
</button>
|
||||
</form>
|
||||
</th:block>
|
||||
<p
|
||||
class="wi-links__apply-unavailable-tip"
|
||||
th:text="'友链申请暂未开放。'"
|
||||
@@ -299,6 +330,10 @@ import Layout from "../layouts/Layout.astro";
|
||||
margin-bottom: var(--space-md);
|
||||
}
|
||||
|
||||
.wi-links__apply-result--ok {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.wi-links__apply-result--error {
|
||||
color: #e6162d;
|
||||
}
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ spec:
|
||||
description: 微信读书书架(依赖微信读书插件)
|
||||
screenshot:
|
||||
file: weread.html
|
||||
version: "1.1.10"
|
||||
version: "1.1.11"
|
||||
requires: ">=2.24.0"
|
||||
license:
|
||||
- name: "GPL-3.0"
|
||||
|
||||
Reference in New Issue
Block a user