halo-theme-dream2.0-plus
Version:
114 lines (111 loc) • 8.79 kB
HTML
<th:block xmlns:th="https://www.thymeleaf.org"
th:insert="~{common/layout :: layout (showTitle = ${#messages.msg('page.links.browser.title', linksTitle, site.title)}, canonical = @{/links}, content = ~{::content}, isPost = false, hideSidebar = false)}"
th:with="baseEnableComment = ${theme.config.page_config.link_enable_comment == true || (!#strings.isEmpty(theme.config.page_config.link_comment_id) && theme.config.page_config.link_enable_comment == 'custom')}">
<th:block th:fragment="content"
th:with="defaultAvatar = ${#strings.defaultString(theme.config.page_config.links_default_avatar, #theme.assets('/img/avatar.svg'))}">
<script>
function setSafeSrc(element, url) {
// 空值检查:防止 url 为空或 undefined 时报错
if (!url) { element.src = ''; return; }
// 安全协议检查:只允许 http/https/data:image/相对路径
var isSafe = /^(https?|data:image\/[a-z]+;base64|\/)/i.test(url);
if (!isSafe) { element.src = ''; return; }
// 检查URL是否已编码(包含百分号编码字符)
element.src = encodeURI(decodeURI(url));
}
</script>
<div class="card">
<div th:if="${!#strings.isEmpty(theme.config.page_config.links_thumbnail)}" class="card-image cover-image"
th:style="'background-image: url(' + ${theme.config.page_config.links_thumbnail} + ')'">
</div>
<div class="card-content main">
<h1 class="title"
th:text="${#messages.msg('page.links.title', linksTitle, contributor.displayName)}"></h1>
<div class="main-content">
<th:block th:each="group : ${groups}"
th:if="${#annotations.getOrDefault(group, 'hide','false') == 'false'}">
<div th:if="${!#lists.isEmpty(group.links)}" class="links">
<h3 class="link-title"
th:text="${#strings.defaultString(group.spec.displayName, #messages.msg('page.links.group.default_name'))}"
th:id="'toc' + ${groupStat.index}"></h3>
<ul class="link-items">
<li th:each="link : ${group.links}"
th:if="${#annotations.getOrDefault(link, 'hide','false') == 'false'}">
<a class="links-item" th:href="${link.spec.url}" rel="noopener noreferrer"
target="_blank" th:aria-label="${link.spec.description}"
th:title="${link.spec.description}">
<img th:if="${#strings.isEmpty(link.spec.logo)}" class="not-gallery"
th:title="${link.spec.displayName}" th:src="${defaultAvatar}"
th:alt="${link.spec.displayName}">
<img th:unless="${#strings.isEmpty(link.spec.logo)}" class="not-gallery"
th:title="${link.spec.displayName}" th:src="${defaultAvatar}"
th:data-url="${link.spec.logo}"
th:data-default="${defaultAvatar}"
onload="if(!this.finish){this.finish=true;setSafeSrc(this, this.getAttribute('data-url'))}"
onerror="this.onerror='';if (this.finish) {setSafeSrc(this, this.getAttribute('data-default'))} else {this.finish=true;setSafeSrc(this, this.getAttribute('data-url'))}"
th:alt="${link.spec.displayName}">
<span class="link-name" th:text="${link.spec.displayName}"></span>
<div class="link-desc"
th:text="${#strings.defaultString(link.spec.description, #messages.msg('page.links.link.description.default'))}"></div>
</a>
<th:block th:if="${pluginFinder.available('PluginLinks', '>=2.1.0') && link.status?.verification != null}" >
<span class="status"
th:with="state1 = ${link.status?.verification?.access?.state?.name()},
lastCheckedAt1 = ${link.status?.verification?.lastCheckedAt}"
th:title="${#messages.msg('page.links.link.last_checked_at', #dates.format(lastCheckedAt1, 'yyyy-MM-dd HH:mm'))}"
th:classappend="${state1 == 'ACCESSIBLE' ? 'online' : (state1 == 'INACCESSIBLE' ? 'offline' : 'checking')}"></span>
</th:block>
</li>
</ul>
</div>
</th:block>
<hr th:if="${theme.config.page_config.show_exchange_info || !#strings.isEmpty(theme.config.page_config.links_info)}"/>
<th:block th:if="${theme.config.page_config.show_exchange_info}"
th:with="bloggerAvatar= ${#strings.defaultString(theme.config.page_config.links_blogger_avatar, contributor.avatar)},
descriptive= ${#strings.defaultString(theme.config.page_config.links_descriptive, contributor.bio)}">
<h3 style="margin-bottom: 4px">[[#{page.links.exchange_info.title}]]</h3>
<ul>
<li>[[${#messages.msg('page.links.exchange_info.name', site.title)}]]</li>
<li th:with="title=${site.url},
linkHtml='<a href="' + ${title} + '" target=/"_blank" aria-label="' + ${title} + '" title="' + ${title} + '">' + ${title} + '</a>',
finalMessage=${#messages.msg('page.links.exchange_info.url', linkHtml)}">
[(${finalMessage})]
</li>
<li th:with="title=${bloggerAvatar},
linkHtml='<a href="' + ${title} + '" target=/"_blank" aria-label="' + ${title} + '" title="' + ${title} + '">' + ${title} + '</a>',
finalMessage=${#messages.msg('page.links.exchange_info.avatar', linkHtml)}">
[(${finalMessage})]
</li>
<li>[[${#messages.msg('page.links.exchange_info.description', descriptive)}]]</li>
<li th:if="${!#strings.isEmpty(theme.config.page_config.links_rss_address)}" th:with="title=${theme.config.page_config.links_rss_address},
linkHtml='<a href="' + ${title} + '" target=/"_blank" aria-label="' + ${title} + '" title="' + ${title} + '">' + ${title} + '</a>',
finalMessage=${#messages.msg('page.links.exchange_info.rss', linkHtml)}">
[(${finalMessage})]
</li>
</ul>
</th:block>
<div th:if="${!#strings.isEmpty(theme.config.page_config.links_info)}"
th:utext="${theme.config.page_config.links_info}"></div>
</div>
</div>
</div>
<div class="card card-content comment-wrapper-z-index" id="comment-wrapper" th:if="${enableComment}">
<h3 class="comment-title">[[#{global.comment_title}]]</h3>
<th:block th:if="${theme.config.page_config.link_enable_comment == 'custom'}">
<halo:comment
group="content.halo.run"
kind="SinglePage"
th:attr="name=${theme.config.page_config.link_comment_id}"
/>
</th:block>
<th:block th:if="${theme.config.page_config.link_enable_comment != 'custom'}">
<halo:comment
group="plugin.halo.run"
kind="Plugin"
th:attr="name=${pluginName}"
/>
</th:block>
</div>
</th:block>
</th:block>