feat(frontend): align single post page 1:1 with Zibll

Restore Zibll float dual-column shell, fix single settings DTO key mapping,
reorder article footer/actions, and match author bar, prev/next, title/body
typography, and limit-height expand UX.
This commit is contained in:
2026-07-13 08:26:36 +08:00
parent a651bd6d2d
commit 5ae1a9ad93
12 changed files with 626 additions and 218 deletions
@@ -45,6 +45,12 @@ export const pageSchema = {
post_article_video_cover_scale: 56,
item_heading_bold: false,
post_button_toptext: '喜欢就支持一下吧',
post_rewards_enabled: false,
post_rewards_text: '',
post_rewards_image: '',
post_rewards_btn_text: '赞赏',
article_maxheight_kg: false,
article_maxheight: 1000,
},
groups: [
{
@@ -121,6 +127,12 @@ export const pageSchema = {
{ key: 'post_copyright_enabled', label: '版权信息', type: 'switch', default: true },
{ key: 'post_copyright_text', label: '版权默认文案', type: 'textarea', default: '', help: '留空则自动生成"本文由 XX 原创发布"' },
{ key: 'post_button_toptext', label: '按钮上方文案', type: 'input', default: '喜欢就支持一下吧', help: '显示在点赞/打赏/分享按钮上方' },
{ key: 'post_rewards_enabled', label: '打赏', type: 'switch', default: false },
{ key: 'post_rewards_btn_text', label: '打赏按钮文案', type: 'input', default: '赞赏', dependsOn: { key: 'post_rewards_enabled', value: true } },
{ key: 'post_rewards_text', label: '打赏说明', type: 'input', default: '', dependsOn: { key: 'post_rewards_enabled', value: true } },
{ key: 'post_rewards_image', label: '打赏二维码 URL', type: 'input', default: '', dependsOn: { key: 'post_rewards_enabled', value: true } },
{ key: 'article_maxheight_kg', label: '正文限高', type: 'switch', default: false, help: '开启后长文默认折叠,可展开全文' },
{ key: 'article_maxheight', label: '限高像素', type: 'number', default: 1000, min: 200, max: 5000, dependsOn: { key: 'article_maxheight_kg', value: true } },
],
},
{
+1
View File
@@ -1,3 +1,4 @@
@import url("single-post/shell.css");
@import url("single-post/content.css");
@import url("single-post/code-blocks.css");
@import url("single-post/navigation.css");
@@ -440,3 +440,103 @@ html.dark .post-drop-meta__item:hover {
.author-box__posts a:hover { color: var(--color-primary); }
.author-box__posts a::before { content: '\2022'; color: var(--color-primary); }
/* ===== Zibll single-metabox / author bar ===== */
.article-avatar .user-info {
width: 100%;
}
.article-avatar .avatar-img img,
.article-avatar .avatar {
width: 42px;
height: 42px;
border-radius: 50%;
object-fit: cover;
}
.article-avatar .display-name {
font-weight: 600;
color: var(--key-color, #333);
}
.article-header .article-avatar .relative {
margin-top: 20px;
}
.single-metabox {
right: 0;
font-size: 15px;
--meta-color: var(--muted-color, #777);
}
.single-metabox .post-metas {
background: var(--body-bg-color, #f5f5f5);
right: 0;
padding: 2px 6px;
border-radius: 100px;
color: var(--meta-color);
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 0;
}
.single-metabox .post-metas item {
margin: 0 6px;
font-size: 13px;
}
.single-metabox .post-drop-meta {
position: relative;
display: inline-block;
}
.single-metabox.cover-meta {
font-size: 14px;
right: 1em;
top: 1.6em;
--meta-color: rgba(255, 255, 255, 0.8);
--body-bg-color: rgba(0, 0, 0, 0.3);
}
.line-form-line {
display: block;
height: 1px;
background: var(--main-border-color, rgba(50,50,50,.06));
margin: 12px 0 0;
}
.post-actions {
padding-bottom: 15px;
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 10px;
}
.post-actions .action {
min-width: 3.2em;
height: 3.2em;
border-radius: 100px;
border: 0;
background: var(--muted-bg-color, #f2f2f2);
color: var(--muted-color, #777);
display: inline-flex;
align-items: center;
justify-content: center;
gap: 4px;
padding: 0 14px;
cursor: pointer;
transition: .15s;
}
.post-actions .action:hover,
.post-actions .action.is-active {
color: var(--focus-color, #f04494);
background: var(--focus-color-opacity1, rgba(240,68,148,.1));
}
.post-actions .action i {
font-size: 16px;
}
+63 -12
View File
@@ -1,20 +1,31 @@
/* ========== Single Post ========== */
.entry-header,
.article-header {
margin-bottom: 28px;
padding-bottom: 18px;
border-bottom: 1px solid var(--color-line-soft);
margin-bottom: 10px;
padding-bottom: 0;
border-bottom: none;
}
/* 标题 — 对齐 zibll: 22px, bold, line-height 1.4 */
.entry-title,
.article-title {
font-size: 28px;
font-weight: 700;
margin: 0 0 18px;
line-height: 1.35;
letter-spacing: -0.01em;
color: var(--color-ink);
font-size: 22px;
font-weight: bold;
margin: 0;
line-height: 1.4;
letter-spacing: 0;
color: var(--key-color, var(--color-ink));
}
.article-header .article-title {
font-size: 22px;
font-weight: bold;
color: var(--key-color, var(--color-ink));
margin-top: 15px;
}
.article-header .article-avatar {
margin-top: 15px;
}
.entry-meta {
@@ -40,15 +51,55 @@
}
/* 内容区 — 对齐 zibll: 16px, line-height 2 */
.entry-content {
.entry-content,
.wp-posts-content {
font-size: 16px;
line-height: 1.95;
color: var(--color-ink);
line-height: 2;
color: var(--main-color, var(--color-ink));
overflow-wrap: break-word;
word-wrap: break-word;
min-height: 90px;
}
/* Zibll content heading bars */
.wp-posts-content > h1:not([class]),
.wp-posts-content > h2:not([class]),
.wp-posts-content > h3:not([class]),
.wp-posts-content > h4:not([class]),
.wp-posts-content > h1.wp-block-heading,
.wp-posts-content > h2.wp-block-heading,
.wp-posts-content > h3.wp-block-heading,
.wp-posts-content > h4.wp-block-heading {
position: relative;
padding-bottom: 8px;
}
.wp-posts-content > h1:not([class]):before,
.wp-posts-content > h2:not([class]):before,
.wp-posts-content > h3:not([class]):before,
.wp-posts-content > h4:not([class]):before,
.wp-posts-content > h1.wp-block-heading:before,
.wp-posts-content > h2.wp-block-heading:before,
.wp-posts-content > h3.wp-block-heading:before,
.wp-posts-content > h4.wp-block-heading:before {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 40px;
height: 3px;
background: var(--theme-color, var(--focus-color, #f04494));
border-radius: 5px;
}
.wp-posts-content > h3:not([class]):before,
.wp-posts-content > h4:not([class]):before,
.wp-posts-content > h3.wp-block-heading:before,
.wp-posts-content > h4.wp-block-heading:before {
width: 28px;
height: 2px;
}
.entry-content > *:first-child {
margin-top: 0;
}
@@ -1,3 +1,47 @@
/* ===== Zibll article-nav (prev/next) ===== */
.article-nav {
display: block;
width: 100%;
}
.article-nav .box-body {
width: calc(50% - 7px);
margin: 0;
display: inline-block;
vertical-align: top;
}
.article-nav .box-body + .box-body {
margin-right: 0;
float: right;
text-align: right;
}
.article-nav a {
display: block;
color: inherit;
text-decoration: none;
}
.article-nav a:hover {
color: var(--focus-color, #f04494);
}
.article-nav .text-ellipsis-2 {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
font-size: 14px;
line-height: 1.5;
color: var(--key-color, #333);
}
.article-nav p {
margin: 0 0 6px;
font-size: 12px;
}
/* ===== Previous / Next Navigation ===== */
.post-nav-box {
display: grid;
@@ -112,12 +156,45 @@
/* ===== Comment Card Spacing ===== */
.comments-card { margin-bottom: 16px; }
/* ===== Content Height Clamp ===== */
/* ===== Content Height Clamp (Zibll) ===== */
.limit-height,
.wp-posts-content.limit-height {
position: relative;
overflow: hidden;
}
.limit-height .read-more {
position: absolute;
bottom: 0;
width: 100%;
text-align: center;
background-image: linear-gradient(0deg, var(--main-bg-color, #fff) 70px, rgba(255, 255, 255, 0) 100%);
animation: lazy_fade 0.5s;
z-index: 80;
}
html.dark .limit-height .read-more,
body.dark-theme .limit-height .read-more {
background-image: linear-gradient(0deg, var(--main-bg-color, #2a2a2a) 70px, rgba(53, 54, 55, 0) 100%);
}
.limit-height .read-more a,
.limit-height .read-more .read-more-open {
padding: 25px 0;
display: inline-block;
color: var(--focus-color, #f04494);
margin-top: 80px;
cursor: pointer;
background: none;
border: 0;
font-size: 14px;
}
@keyframes lazy_fade {
from { opacity: 0; }
to { opacity: 1; }
}
.wp-posts-content.limit-height::after {
content: '';
position: absolute;
+59
View File
@@ -0,0 +1,59 @@
/* Single page shell — Zibll float dual-column (scoped to body.single) */
body.single .container {
position: relative;
}
body.single .content-wrap {
float: left;
width: 100%;
}
/* Clear floats after main dual-column shell */
body.single main.container::after {
content: "";
display: table;
clear: both;
}
/* Default: no sidebar full width */
body.single.container--no-sidebar .content-layout,
body.single .container--no-sidebar .content-layout,
body.single main.container--no-sidebar .content-layout {
margin-right: 0;
}
/* Zibll site-layout-2: content left, sidebar right (311px) */
@media (min-width: 992px) {
body.single:not(.no-sidebar) main.container:not(.container--no-sidebar) .content-layout {
margin-right: calc(var(--sidebar-width, 311px) + 15px);
}
body.single:not(.no-sidebar) main.container:not(.container--no-sidebar) > .sidebar {
float: left;
width: var(--sidebar-width, 311px);
margin-left: calc(0px - var(--sidebar-width, 311px));
position: relative;
}
}
@media (max-width: 991.98px) {
body.single main.container > .sidebar {
display: none;
}
body.single main.container .content-layout {
margin-right: 0 !important;
}
}
/* Sidebar widgets spacing */
body.single .sidebar .zib-widget,
body.single .sidebar .widget {
margin-bottom: 15px;
}
body.single .sidebar .posts-nav-box.toc-widget {
position: sticky;
top: calc(var(--nav-height, 60px) + 16px);
}
+44 -32
View File
@@ -190,15 +190,27 @@
}
function initContentExpand() {
document.querySelectorAll('.entry-content[data-nav]').forEach(function (content) {
// Zibll-style: inject .read-more inside .limit-height and expand on click.
document.querySelectorAll('.wp-posts-content.limit-height, .limit-height[data-nav]').forEach(function (content) {
if (content.dataset.aksrtExpandBound === '1') return;
content.dataset.aksrtExpandBound = '1';
// Only expand when server enabled maxheight (data-maxheight > 0).
var customMax = parseInt(content.getAttribute('data-maxheight') || content.dataset.maxheight || '0', 10);
if (!(customMax > 0)) return;
var limit = customMax;
if (content.scrollHeight <= limit) {
// data-maxheight may be maxheight-80 (Zibll) or absolute maxheight; prefer style max-height.
var styleMax = 0;
if (content.style && content.style.maxHeight) {
styleMax = parseInt(content.style.maxHeight, 10) || 0;
}
var limit = styleMax > 0 ? styleMax : (customMax > 0 ? customMax + 80 : 0);
if (!(limit > 0) && customMax > 0) {
limit = customMax;
}
if (!(limit > 0)) {
content.classList.remove('limit-height');
return;
}
if (content.scrollHeight <= limit + 40) {
content.classList.remove('limit-height');
content.style.maxHeight = '';
return;
@@ -207,37 +219,37 @@
content.classList.add('limit-height');
content.style.maxHeight = limit + 'px';
var existingBtn = content.nextElementSibling;
if (existingBtn && existingBtn.classList && existingBtn.classList.contains('content-expand-btn')) {
return;
}
if (content.querySelector('.read-more')) return;
var button = document.createElement('button');
button.type = 'button';
button.className = 'content-expand-btn';
button.innerHTML = '<i class="fas fa-chevron-down" aria-hidden="true"></i> <span>展开阅读全文</span>';
content.parentNode.insertBefore(button, content.nextSibling);
var wrap = document.createElement('div');
wrap.className = 'read-more';
var link = document.createElement('a');
link.href = 'javascript:;';
link.className = 'read-more-open';
link.innerHTML = '展开阅读全文<i class="fa ml10 fa-angle-down" aria-hidden="true"></i>';
wrap.appendChild(link);
content.appendChild(wrap);
button.addEventListener('click', function () {
var expanded = content.classList.contains('is-expanded');
if (expanded) {
content.classList.remove('is-expanded');
content.style.maxHeight = limit + 'px';
button.classList.remove('is-expanded');
button.querySelector('span').textContent = '展开阅读全文';
content.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
return;
}
content.classList.add('is-expanded');
content.style.maxHeight = content.scrollHeight + 'px';
button.classList.add('is-expanded');
button.querySelector('span').textContent = '收起';
link.addEventListener('click', function (event) {
event.preventDefault();
content.classList.remove('limit-height');
content.style.maxHeight = '';
wrap.remove();
});
});
// Compatibility: old external expand buttons.
document.addEventListener('click', function (event) {
var open = event.target.closest && event.target.closest('.read-more-open');
if (!open) return;
var limitBox = open.closest('.limit-height');
if (!limitBox) return;
event.preventDefault();
limitBox.classList.remove('limit-height');
limitBox.style.maxHeight = '';
var more = open.closest('.read-more');
if (more) more.remove();
});
}
function initFlashQueryCleanup() {
@@ -228,16 +228,40 @@ class AKSRT_Settings_Post_Display {
public static function get_post_page_settings(): array {
$settings = AKSRT_Settings::get_all();
// Canonical render keys (used by aksrt_single_*). Legacy *_s aliases kept for older callers.
$breadcrumbs = !isset($settings['breadcrumbs_single_s']) || !empty($settings['breadcrumbs_single_s']);
$breadcrumbs_home = sanitize_text_field((string) ($settings['breadcrumbs_home_text'] ?? '首页'));
$prevnext = !isset($settings['post_prevnext_s']) || !empty($settings['post_prevnext_s']);
$authordesc = !isset($settings['post_authordesc_s']) || !empty($settings['post_authordesc_s']);
$hide_time = !empty($settings['post_single_hide_time_s']);
$share_enabled = !isset($settings['share_s']) || !empty($settings['share_s']);
$rewards_enabled = !empty($settings['post_rewards_enabled']) || !empty($settings['post_rewards_s']);
$rewards_image = (string) ($settings['post_rewards_image'] ?? $settings['post_rewards_qrcode'] ?? '');
$rewards_text = sanitize_text_field((string) ($settings['post_rewards_text'] ?? ''));
$rewards_btn_text = sanitize_text_field((string) ($settings['post_rewards_btn_text'] ?? '赞赏'));
$maxheight_enabled = !empty($settings['article_maxheight_kg']) || !empty($settings['post_article_maxheight_kg']);
$maxheight = max(0, (int) ($settings['article_maxheight'] ?? $settings['post_article_maxheight'] ?? 1000));
if ($maxheight <= 0) {
$maxheight = 1000;
}
return [
'toc_enabled' => !isset($settings['post_toc_enabled']) || !empty($settings['post_toc_enabled']),
'toc_depth' => max(1, min(6, (int) ($settings['post_toc_depth'] ?? 3))),
'article_nav_mobile_nav_s' => !isset($settings['article_nav_mobile_nav_s']) || !empty($settings['article_nav_mobile_nav_s']),
'reading_progress' => !isset($settings['post_reading_progress']) || !empty($settings['post_reading_progress']),
'breadcrumbs_single_s' => !isset($settings['breadcrumbs_single_s']) || !empty($settings['breadcrumbs_single_s']),
'breadcrumbs_home_text' => sanitize_text_field((string) ($settings['breadcrumbs_home_text'] ?? '首页')),
'prevnext_s' => !isset($settings['post_prevnext_s']) || !empty($settings['post_prevnext_s']),
'authordesc_s' => !isset($settings['post_authordesc_s']) || !empty($settings['post_authordesc_s']),
'single_hide_time_s' => !empty($settings['post_single_hide_time_s']),
// Canonical + legacy breadcrumbs.
'breadcrumbs' => $breadcrumbs,
'breadcrumbs_home' => $breadcrumbs_home,
'breadcrumbs_single_s' => $breadcrumbs,
'breadcrumbs_home_text' => $breadcrumbs_home,
// Canonical + legacy prev/next / author / time.
'prevnext' => $prevnext,
'prevnext_s' => $prevnext,
'authordesc' => $authordesc,
'authordesc_s' => $authordesc,
'hide_time' => $hide_time,
'single_hide_time_s' => $hide_time,
'article_image_cover' => !isset($settings['post_article_image_cover']) || !empty($settings['post_article_image_cover']),
'article_image_cover_scale'=> max(10, min(100, (int) ($settings['post_article_image_cover_scale'] ?? 35))),
'article_slide_cover' => !isset($settings['post_article_slide_cover']) || !empty($settings['post_article_slide_cover']),
@@ -256,7 +280,17 @@ class AKSRT_Settings_Post_Display {
'related_title' => sanitize_text_field((string) ($settings['post_related_title'] ?? '相关推荐')),
'like_enabled' => !isset($settings['post_like_enabled']) || !empty($settings['post_like_enabled']),
'favorite_enabled' => !isset($settings['post_favorite_enabled']) || !empty($settings['post_favorite_enabled']),
'share_s' => !isset($settings['share_s']) || !empty($settings['share_s']),
// Canonical + legacy share.
'share_enabled' => $share_enabled,
'share_s' => $share_enabled,
// Rewards (Zibll post_rewards_s).
'rewards_enabled' => $rewards_enabled,
'rewards_image' => $rewards_image,
'rewards_text' => $rewards_text,
'rewards_btn_text' => $rewards_btn_text !== '' ? $rewards_btn_text : '赞赏',
// Content max height (Zibll article_maxheight_kg / article_maxheight).
'maxheight_enabled' => $maxheight_enabled,
'maxheight' => $maxheight,
'copyright_enabled' => !isset($settings['post_copyright_enabled']) || !empty($settings['post_copyright_enabled']),
'copyright_text' => (string) ($settings['post_copyright_text'] ?? ''),
'button_toptext' => sanitize_text_field((string) ($settings['post_button_toptext'] ?? '喜欢就支持一下吧')),
@@ -269,6 +303,8 @@ class AKSRT_Settings_Post_Display {
'default_views_max' => max(1, min(9999, (int) ($settings['post_default_views_max'] ?? 50))),
'default_likes_min' => max(0, min(9999, (int) ($settings['post_default_likes_min'] ?? 5))),
'default_likes_max' => max(1, min(9999, (int) ($settings['post_default_likes_max'] ?? 15))),
'word_count_enabled' => !isset($settings['post_word_count_enabled']) || !empty($settings['post_word_count_enabled']),
'reading_time_enabled' => !isset($settings['post_reading_time_enabled']) || !empty($settings['post_reading_time_enabled']),
];
}
+35 -1
View File
@@ -192,6 +192,17 @@ if (!function_exists('aksrt_resolve_single_post_display_settings')) :
'like_enabled' => true,
'favorite_enabled' => true,
'share_enabled' => true,
'breadcrumbs' => true,
'breadcrumbs_home' => '首页',
'prevnext' => true,
'authordesc' => true,
'hide_time' => false,
'rewards_enabled' => false,
'rewards_image' => '',
'rewards_text' => '',
'rewards_btn_text' => '赞赏',
'maxheight_enabled' => false,
'maxheight' => 1000,
'copyright_enabled' => true,
'copyright_text' => '',
'front_content' => '',
@@ -205,6 +216,26 @@ if (!function_exists('aksrt_resolve_single_post_display_settings')) :
'reading_time_enabled' => true,
];
// Normalize legacy aliases → canonical render keys (idempotent).
if (!array_key_exists('share_enabled', $settings) && array_key_exists('share_s', $settings)) {
$settings['share_enabled'] = !empty($settings['share_s']);
}
if (!array_key_exists('hide_time', $settings) && array_key_exists('single_hide_time_s', $settings)) {
$settings['hide_time'] = !empty($settings['single_hide_time_s']);
}
if (!array_key_exists('breadcrumbs', $settings) && array_key_exists('breadcrumbs_single_s', $settings)) {
$settings['breadcrumbs'] = !empty($settings['breadcrumbs_single_s']);
}
if (!array_key_exists('breadcrumbs_home', $settings) && array_key_exists('breadcrumbs_home_text', $settings)) {
$settings['breadcrumbs_home'] = (string) $settings['breadcrumbs_home_text'];
}
if (!array_key_exists('prevnext', $settings) && array_key_exists('prevnext_s', $settings)) {
$settings['prevnext'] = !empty($settings['prevnext_s']);
}
if (!array_key_exists('authordesc', $settings) && array_key_exists('authordesc_s', $settings)) {
$settings['authordesc'] = !empty($settings['authordesc_s']);
}
$meta = class_exists('AKSRT_Post_Meta_Box') ? AKSRT_Post_Meta_Box::get_meta($post->ID) : [];
if (($meta['show_toc'] ?? '') !== '') {
$settings['toc_enabled'] = $meta['show_toc'] === '1';
@@ -231,11 +262,14 @@ if (!function_exists('aksrt_resolve_single_post_display_settings')) :
$settings['related_count'] = max(1, min(20, (int) $meta['related_count']));
}
// Per-post maxheight override (Zibll article_maxheight_xz).
// Per-post maxheight override (Zibll article_maxheight_xz). Global may already set maxheight_enabled.
$meta_maxheight = (int) ($meta['maxheight'] ?? 0);
if ($meta_maxheight > 0) {
$settings['maxheight_enabled'] = true;
$settings['maxheight'] = $meta_maxheight;
} elseif (empty($settings['maxheight_enabled'])) {
$settings['maxheight_enabled'] = false;
$settings['maxheight'] = max(0, (int) ($settings['maxheight'] ?? 0));
}
$cover_mode = (string) ($meta['header_image_mode'] ?? '');
+68 -57
View File
@@ -92,7 +92,7 @@ if (!function_exists('aksrt_single_build_context')) :
$breadcrumbs_html = '';
if (!empty($settings['breadcrumbs']) && function_exists('aksrt_breadcrumbs')) {
ob_start();
aksrt_breadcrumbs($settings['breadcrumbs_home'] ?? '');
aksrt_breadcrumbs($settings['breadcrumbs_home'] ?? ($settings['breadcrumbs_home_text'] ?? ''));
$breadcrumbs_html = trim((string) ob_get_clean());
}
@@ -508,13 +508,12 @@ endif;
if (!function_exists('aksrt_single_render_prevnext')) :
/**
* Previous / next navigation.
* Previous / next navigation (Zibll .article-nav).
*
* @param array<string,mixed> $ctx Single context.
*/
function aksrt_single_render_prevnext(array $ctx = []): void {
$settings = is_array($ctx['settings'] ?? null) ? $ctx['settings'] : [];
// Accept both canonical `prevnext` (Settings DTO) and legacy `prevnext_s`.
$enabled = array_key_exists('prevnext', $settings)
? !empty($settings['prevnext'])
: (!array_key_exists('prevnext_s', $settings) || !empty($settings['prevnext_s']));
@@ -522,30 +521,40 @@ if (!function_exists('aksrt_single_render_prevnext')) :
return;
}
$prev = get_previous_post();
$next = get_next_post();
// Zibll: constrain to current category when available.
$in_same_term = !empty(get_the_category());
$prev = get_previous_post($in_same_term, '', 'category');
$next = get_next_post($in_same_term, '', 'category');
if (!$prev && !$next) {
// Fallback: any post.
$prev = get_previous_post();
$next = get_next_post();
}
if (!$prev && !$next) {
return;
}
$prev_title = $prev ? get_the_title($prev) : __('无更多文章', 'aksrt');
$next_title = $next ? get_the_title($next) : __('无更多文章', 'aksrt');
$prev_href = $prev ? get_permalink($prev) : 'javascript:;';
$next_href = $next ? get_permalink($next) : 'javascript:;';
?>
<nav class="post-nav-box theme-box box-body radius8 main-shadow">
<?php if ($prev) : ?>
<a class="post-nav-box__item post-nav-box__item--prev" href="<?php echo esc_url(get_permalink($prev)); ?>">
<span class="post-nav-box__label"><?php esc_html_e('上一篇', 'aksrt'); ?></span>
<span class="post-nav-box__title"><?php echo esc_html(get_the_title($prev)); ?></span>
</a>
<?php else : ?>
<span class="post-nav-box__item post-nav-box__item--prev is-empty" aria-hidden="true"></span>
<?php endif; ?>
<?php if ($next) : ?>
<a class="post-nav-box__item post-nav-box__item--next" href="<?php echo esc_url(get_permalink($next)); ?>">
<span class="post-nav-box__label"><?php esc_html_e('下一篇', 'aksrt'); ?></span>
<span class="post-nav-box__title"><?php echo esc_html(get_the_title($next)); ?></span>
</a>
<?php else : ?>
<span class="post-nav-box__item post-nav-box__item--next is-empty" aria-hidden="true"></span>
<?php endif; ?>
</nav>
<div class="theme-box" style="height:99px">
<nav class="article-nav">
<div class="main-bg box-body radius8 main-shadow">
<a href="<?php echo $prev ? esc_url($prev_href) : 'javascript:;'; ?>">
<p class="muted-2-color"><i class="fa fa-angle-left em12" aria-hidden="true"></i><i class="fa fa-angle-left em12 mr6" aria-hidden="true"></i><?php esc_html_e('上一篇', 'aksrt'); ?></p>
<div class="text-ellipsis-2"><?php echo esc_html($prev_title); ?></div>
</a>
</div>
<div class="main-bg box-body radius8 main-shadow">
<a href="<?php echo $next ? esc_url($next_href) : 'javascript:;'; ?>">
<p class="muted-2-color"><?php esc_html_e('下一篇', 'aksrt'); ?><i class="fa fa-angle-right em12 ml6" aria-hidden="true"></i><i class="fa fa-angle-right em12" aria-hidden="true"></i></p>
<div class="text-ellipsis-2"><?php echo esc_html($next_title); ?></div>
</a>
</div>
</nav>
</div>
<?php
}
endif;
@@ -777,7 +786,7 @@ endif;
if (!function_exists('aksrt_single_render_article')) :
/**
* Main article box.
* Main article box (Zibll zib_single_content order).
*
* @param array<string,mixed> $ctx Single context.
*/
@@ -785,49 +794,51 @@ if (!function_exists('aksrt_single_render_article')) :
$settings = is_array($ctx['settings'] ?? null) ? $ctx['settings'] : [];
$maxheight = (int) $ctx['content_maxheight'];
?>
<article <?php post_class('article article-shell main-bg theme-box box-body radius8 main-shadow'); ?>>
<article <?php post_class('article main-bg theme-box box-body radius8 main-shadow'); ?>>
<?php aksrt_single_render_box_header($ctx); ?>
<?php if (!empty($settings['yiyan_header'])) : ?>
<div class="article-yiyan yiyan-box aksrt-yiyan yiyan--header" data-aksrt-yiyan data-type="hitokoto"></div>
<?php endif; ?>
<div class="article-content">
<?php if (!empty($settings['yiyan_header'])) : ?>
<div class="article-yiyan yiyan-box aksrt-yiyan yiyan--header theme-box text-center radius8 main-shadow" data-aksrt-yiyan data-type="hitokoto"></div>
<?php endif; ?>
<?php do_action('aksrt_single_content_before', get_post()); ?>
<?php do_action('aksrt_single_content_before', get_post()); ?>
<?php if (function_exists('aksrt_single_pay_box_matches') && aksrt_single_pay_box_matches($ctx, 'top')) : ?>
<?php if (function_exists('aksrt_single_pay_box_matches') && aksrt_single_pay_box_matches($ctx, 'top')) : ?>
<?php aksrt_single_render_pay_box($ctx); ?>
<?php endif; ?>
<?php if ($ctx['front_content'] !== '') : ?>
<div class="post_front_content theme-box box-body"><?php echo wp_kses_post((string) $ctx['front_content']); ?></div>
<?php endif; ?>
<?php if ($ctx['front_content'] !== '') : ?>
<div class="post_front_content theme-box box-body"><?php echo wp_kses_post((string) $ctx['front_content']); ?></div>
<?php endif; ?>
<div class="theme-box wp-posts-content entry-content<?php echo $maxheight > 0 ? ' limit-height' : ''; ?>"
<?php echo $maxheight > 0 ? ' style="max-height:' . esc_attr((string) $maxheight) . 'px;"' : ''; ?>
data-nav="posts"
data-maxheight="<?php echo esc_attr((string) $maxheight); ?>"
data-aksrt-toc="<?php echo !empty($ctx['show_toc']) ? '1' : '0'; ?>"
data-aksrt-toc-depth="<?php echo esc_attr((string) ((int) ($settings['toc_depth'] ?? 3))); ?>"
<?php echo !empty($settings['lightbox']) ? ' data-aksrt-lightbox="1"' : ''; ?>>
<?php the_content(); ?>
<?php
wp_link_pages([
'before' => '<p class="text-center post-nav-links radius8 padding-6">',
'after' => '</p>',
]);
?>
<div class="theme-box wp-posts-content<?php echo $maxheight > 0 ? ' limit-height' : ''; ?>"
<?php echo $maxheight > 0 ? ' style="max-height:' . esc_attr((string) $maxheight) . 'px;"' : ''; ?>
data-nav="posts"
data-maxheight="<?php echo esc_attr((string) ($maxheight > 0 ? max(0, $maxheight - 80) : 0)); ?>"
data-aksrt-toc="<?php echo !empty($ctx['show_toc']) ? '1' : '0'; ?>"
data-aksrt-toc-depth="<?php echo esc_attr((string) ((int) ($settings['toc_depth'] ?? 3))); ?>"
<?php echo !empty($settings['lightbox']) ? ' data-aksrt-lightbox="1"' : ''; ?>>
<?php the_content(); ?>
<?php
wp_link_pages([
'before' => '<p class="text-center post-nav-links radius8 padding-6">',
'after' => '</p>',
]);
?>
<?php if ($ctx['after_content'] !== '') : ?>
<?php echo wp_kses_post((string) $ctx['after_content']); ?>
<?php endif; ?>
</div>
<?php if (function_exists('aksrt_single_pay_box_matches') && aksrt_single_pay_box_matches($ctx, 'bottom')) : ?>
<?php aksrt_single_render_pay_box($ctx); ?>
<?php endif; ?>
<?php aksrt_single_render_content_footer($ctx); ?>
</div>
<?php if ($ctx['after_content'] !== '') : ?>
<div class="post_after_content theme-box box-body"><?php echo wp_kses_post((string) $ctx['after_content']); ?></div>
<?php endif; ?>
<?php if (function_exists('aksrt_single_pay_box_matches') && aksrt_single_pay_box_matches($ctx, 'bottom')) : ?>
<?php aksrt_single_render_pay_box($ctx); ?>
<?php endif; ?>
<?php aksrt_single_render_actions($ctx); ?>
<?php aksrt_single_render_content_footer($ctx); ?>
</article>
<?php
}
@@ -914,7 +925,7 @@ if (!function_exists('aksrt_single')) :
echo $ctx['breadcrumbs_html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
} elseif (function_exists('aksrt_breadcrumbs')) {
$settings = is_array($ctx['settings'] ?? null) ? $ctx['settings'] : [];
aksrt_breadcrumbs($settings['breadcrumbs_home'] ?? '');
aksrt_breadcrumbs($settings['breadcrumbs_home'] ?? ($settings['breadcrumbs_home_text'] ?? ''));
}
} else {
aksrt_single_render_cover($ctx);
+26 -32
View File
@@ -1,6 +1,6 @@
<?php
/**
* Single post template — thin Zibll-style shell.
* Single post template — Zibll-style shell.
*
* Composition lives in inc/helpers/aksrt-single.php.
*
@@ -10,7 +10,6 @@
defined('ABSPATH') || exit;
wp_reset_postdata();
get_header();
while (have_posts()) :
the_post();
@@ -21,13 +20,16 @@ while (have_posts()) :
: ['show_aside' => false, 'settings' => []];
if (function_exists('aksrt_single_is_docs_page') && aksrt_single_is_docs_page($post_id)) {
get_header();
get_template_part('templates/pages/page-documentnav');
get_footer();
return;
}
$settings = is_array($ctx['settings'] ?? null) ? $ctx['settings'] : [];
$show_aside = !empty($ctx['show_aside']);
$show_aside = !empty($ctx['show_aside']) && !wp_is_mobile();
get_header();
?>
<?php if (!empty($settings['reading_progress'])) : ?>
@@ -41,42 +43,34 @@ while (have_posts()) :
</div>
<?php endif; ?>
<main id="main-content" role="main" class="site-main container content-shell content-shell--stream content-shell--single" tabindex="-1">
<main role="main" class="container<?php echo $show_aside ? '' : ' container--no-sidebar'; ?>">
<div class="content-wrap">
<div class="content-layout<?php echo $show_aside ? '' : ' content-layout--no-sidebar'; ?>">
<div class="content-layout__primary">
<?php if (is_active_sidebar('single_top_content')) : ?>
<div class="aksrt-single-widget-area aksrt-single-widget-area--top">
<?php dynamic_sidebar('single_top_content'); ?>
</div>
<?php endif; ?>
<?php
if (function_exists('aksrt_single')) {
aksrt_single($ctx);
}
?>
<?php if (comments_open() || get_comments_number()) : ?>
<div class="theme-box box-body radius8 main-shadow comments-card">
<?php comments_template(); ?>
</div>
<?php endif; ?>
<?php if (is_active_sidebar('single_bottom_content')) : ?>
<div class="aksrt-single-widget-area aksrt-single-widget-area--bottom">
<?php dynamic_sidebar('single_bottom_content'); ?>
</div>
<?php endif; ?>
</div>
<div class="content-layout">
<?php if (is_active_sidebar('single_top_content')) : ?>
<?php dynamic_sidebar('single_top_content'); ?>
<?php endif; ?>
<?php
if (function_exists('aksrt_single_render_aside')) {
aksrt_single_render_aside($ctx);
if (function_exists('aksrt_single')) {
aksrt_single($ctx);
}
?>
<?php if (comments_open() || get_comments_number()) : ?>
<?php comments_template(); ?>
<?php endif; ?>
<?php if (is_active_sidebar('single_bottom_content')) : ?>
<?php dynamic_sidebar('single_bottom_content'); ?>
<?php endif; ?>
</div>
</div>
<?php
if (function_exists('aksrt_single_render_aside')) {
aksrt_single_render_aside($ctx);
}
?>
</main>
<?php if (function_exists('dynamic_sidebar')) : ?>
+98 -77
View File
@@ -1,6 +1,6 @@
<?php
/**
* Shared author info bar for single post content.
* Shared author info bar for single post content (Zibll article-avatar / user-info).
*
* Contract: get_template_part(..., null, $args)
*
@@ -20,94 +20,115 @@ $meta_items = is_array($args['meta_items'] ?? null) ? array_values(array_filter(
return is_string($meta_item) && $meta_item !== '';
})) : [];
$updated_text = sprintf(
esc_html__('%s前更新', 'aksrt'),
esc_html(human_time_diff((int) get_the_modified_time('U'), current_time('timestamp')))
);
$author_bio = trim((string) get_the_author_meta('description'));
$author_id = (int) get_the_author_meta('ID');
$classes = trim('article-avatar ' . $extra_class . ($show_actions ? ' article-avatar--with-actions' : ''));
$author_name = get_the_author();
$author_url = get_author_posts_url($author_id);
$modified_ts = (int) get_the_modified_time('U');
$published_ts = (int) get_the_time('U');
$now = (int) current_time('timestamp');
$use_modified = $modified_ts > $published_ts;
$rel_base = $use_modified ? $modified_ts : $published_ts;
$rel_label = $use_modified ? __('更新', 'aksrt') : __('发布', 'aksrt');
$abs_fmt = $use_modified
? sprintf(__('%s更新', 'aksrt'), get_the_modified_time('Y年m月d日 H:i'))
: sprintf(__('%s发布', 'aksrt'), get_the_time('Y年m月d日 H:i'));
$time_text = human_time_diff($rel_base, $now) . $rel_label;
$classes = trim('article-avatar ' . $extra_class);
$aksrt_pm_on = class_exists('AKSRT_Settings') && !empty(AKSRT_Settings::private_message_settings()['enabled']);
$aksrt_msg_url = function_exists('aksrt_get_messages_page_url') ? aksrt_get_messages_page_url() : '';
$login_url = function_exists('aksrt_get_login_url') ? aksrt_get_login_url() : wp_login_url(get_permalink());
$is_self = is_user_logged_in() && get_current_user_id() === $author_id;
?>
<div class="<?php echo esc_attr($classes); ?>">
<div class="author-box flex ac">
<div class="article-avatar__image">
<?php echo get_avatar($author_id, 52, '', esc_attr(get_the_author()), ['class' => 'article-avatar']); ?>
</div>
<div class="article-avatar__body">
<a href="<?php echo esc_url(get_author_posts_url($author_id)); ?>" class="article-avatar__name"><?php the_author(); ?></a>
<div class="comt-meta muted-2-color">
<item class="post-time"><i class="far fa-clock" aria-hidden="true"></i> <?php echo $updated_text; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></item>
<?php foreach ($meta_items as $meta_item) : ?>
<?php
$meta_text = is_array($meta_item) ? (string) ($meta_item['text'] ?? '') : (string) $meta_item;
$meta_icon = is_array($meta_item) ? (string) ($meta_item['icon'] ?? '') : '';
if ($meta_text === '') {
continue;
}
?>
<item class="meta-view"><?php if ($meta_icon !== '') : ?><i class="<?php echo esc_attr($meta_icon); ?>" aria-hidden="true"></i> <?php endif; ?><?php echo esc_html($meta_text); ?></item>
<?php endforeach; ?>
<div class="user-info flex ac">
<a class="avatar-img" href="<?php echo esc_url($author_url); ?>">
<?php echo get_avatar($author_id, 52, '', esc_attr($author_name), ['class' => 'avatar avatar-id-' . $author_id]); ?>
</a>
<div class="user-right flex flex1 ac jsb ml10">
<div class="flex1">
<a class="display-name text-ellipsis" href="<?php echo esc_url($author_url); ?>"><?php echo esc_html($author_name); ?></a>
<div class="px12-sm muted-2-color text-ellipsis">
<span class="icon-circle" title="<?php echo esc_attr($abs_fmt); ?>" data-toggle="tooltip"><?php echo esc_html($time_text); ?></span>
<?php if ($show_bio) : ?>
<?php $bio = trim((string) get_the_author_meta('description')); ?>
<?php if ($bio !== '') : ?>
<span class="icon-circle"><?php echo esc_html($bio); ?></span>
<?php endif; ?>
<?php endif; ?>
</div>
</div>
<?php if ($show_bio && $author_bio !== '') : ?>
<p class="article-avatar__bio"><?php echo esc_html($author_bio); ?></p>
<?php if ($show_actions) : ?>
<div class="flex0 user-action">
<?php if (!$is_self) : ?>
<?php if (is_user_logged_in()) : ?>
<button type="button" class="px12-sm ml10 follow but c-red" data-aksrt-follow="<?php echo (int) $author_id; ?>">
<i class="fa fa-heart em09" aria-hidden="true"></i> <?php esc_html_e('关注', 'aksrt'); ?>
</button>
<?php if ($aksrt_pm_on && $aksrt_msg_url !== '') : ?>
<a href="<?php echo esc_url(add_query_arg('msg_type', 'conversation', $aksrt_msg_url)); ?>" class="ml6 but c-blue px12-sm">
<i class="fa fa-comment em09" aria-hidden="true"></i> <?php esc_html_e('私信', 'aksrt'); ?>
</a>
<?php endif; ?>
<?php else : ?>
<a href="<?php echo esc_url($login_url); ?>" class="px12-sm ml10 follow but c-red">
<i class="fa fa-heart em09" aria-hidden="true"></i> <?php esc_html_e('关注', 'aksrt'); ?>
</a>
<?php endif; ?>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
</div>
<?php if ($show_actions) : ?>
<i class="line-form-line" aria-hidden="true"></i>
<div class="single-metabox abs-right" aria-label="<?php esc_attr_e('作者操作', 'aksrt'); ?>">
<?php if (is_user_logged_in() && $author_id !== get_current_user_id()) : ?>
<button type="button" class="author-action-btn author-action-btn--follow" data-aksrt-follow="<?php echo (int) $author_id; ?>">
<i class="far fa-heart" aria-hidden="true"></i>
<span><?php esc_html_e('关注', 'aksrt'); ?></span>
</button>
<?php
$aksrt_pm_on = class_exists('AKSRT_Settings') && !empty(AKSRT_Settings::private_message_settings()['enabled']);
$aksrt_msg_url = function_exists('aksrt_get_messages_page_url') ? aksrt_get_messages_page_url() : '';
if ($aksrt_pm_on && $aksrt_msg_url !== '') :
?>
<a href="<?php echo esc_url(add_query_arg('msg_type', 'conversation', $aksrt_msg_url)); ?>" class="author-action-btn author-action-btn--ghost">
<i class="far fa-comment-dots" aria-hidden="true"></i>
<span><?php esc_html_e('私信', 'aksrt'); ?></span>
</a>
<?php endif; ?>
<?php elseif (!is_user_logged_in()) : ?>
<a href="<?php echo esc_url(function_exists('aksrt_get_login_url') ? aksrt_get_login_url() : wp_login_url(get_permalink())); ?>" class="author-action-btn author-action-btn--follow">
<i class="far fa-heart" aria-hidden="true"></i>
<span><?php esc_html_e('登录后关注', 'aksrt'); ?></span>
</a>
<?php endif; ?>
<div class="post-drop-meta">
<button type="button" class="post-drop-meta__toggle author-action-btn author-action-btn--ghost" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-ellipsis-h" aria-hidden="true"></i>
<span><?php esc_html_e('更多', 'aksrt'); ?></span>
</button>
<div class="post-drop-meta__menu" aria-hidden="true">
<?php if (current_user_can('edit_post', get_the_ID())) : ?>
<a href="<?php echo esc_url(get_edit_post_link(get_the_ID())); ?>" class="post-drop-meta__item">
<i class="far fa-edit" aria-hidden="true"></i>
<span><?php esc_html_e('编辑文章', 'aksrt'); ?></span>
</a>
<?php endif; ?>
<button type="button" class="post-drop-meta__item" data-share-copy data-share-url="<?php echo esc_url(get_permalink()); ?>">
<i class="fas fa-link" aria-hidden="true"></i>
<span><?php esc_html_e('复制链接', 'aksrt'); ?></span>
</button>
<?php if (is_user_logged_in()) : ?>
<button type="button" class="post-drop-meta__item" data-aksrt-report='{"target_type":"post","target_id":<?php echo (int) get_the_ID(); ?>}'>
<i class="far fa-flag" aria-hidden="true"></i>
<span><?php esc_html_e('举报', 'aksrt'); ?></span>
<div class="relative">
<i class="line-form-line" aria-hidden="true"></i>
<?php if (!empty($meta_items)) : ?>
<div class="flex ac single-metabox abs-right">
<div class="post-metas">
<?php foreach ($meta_items as $meta_item) : ?>
<?php
$meta_text = is_array($meta_item) ? (string) ($meta_item['text'] ?? '') : (string) $meta_item;
$meta_icon = is_array($meta_item) ? (string) ($meta_item['icon'] ?? '') : '';
if ($meta_text === '') {
continue;
}
?>
<item class="meta-view"><?php if ($meta_icon !== '') : ?><i class="<?php echo esc_attr($meta_icon); ?>" aria-hidden="true"></i> <?php endif; ?><?php echo esc_html($meta_text); ?></item>
<?php endforeach; ?>
</div>
<div class="clearfix ml6 post-drop-meta">
<button type="button" class="but cir post-drop-meta__toggle" aria-haspopup="true" aria-expanded="false" aria-label="<?php esc_attr_e('更多', 'aksrt'); ?>">
<i class="fa fa-ellipsis-h" aria-hidden="true"></i>
</button>
<?php else : ?>
<a href="<?php echo esc_url(function_exists('aksrt_get_login_url') ? aksrt_get_login_url() : wp_login_url(get_permalink())); ?>" class="post-drop-meta__item">
<i class="far fa-flag" aria-hidden="true"></i>
<span><?php esc_html_e('登录后举报', 'aksrt'); ?></span>
</a>
<?php endif; ?>
<div class="post-drop-meta__menu" aria-hidden="true">
<?php if (current_user_can('edit_post', get_the_ID())) : ?>
<a href="<?php echo esc_url(get_edit_post_link(get_the_ID())); ?>" class="post-drop-meta__item">
<i class="fa fa-edit" aria-hidden="true"></i>
<span><?php esc_html_e('编辑文章', 'aksrt'); ?></span>
</a>
<?php endif; ?>
<button type="button" class="post-drop-meta__item" data-share-copy data-share-url="<?php echo esc_url(get_permalink()); ?>">
<i class="fa fa-link" aria-hidden="true"></i>
<span><?php esc_html_e('复制链接', 'aksrt'); ?></span>
</button>
<?php if (is_user_logged_in()) : ?>
<button type="button" class="post-drop-meta__item" data-aksrt-report='{"target_type":"post","target_id":<?php echo (int) get_the_ID(); ?>}'>
<i class="fa fa-flag" aria-hidden="true"></i>
<span><?php esc_html_e('举报', 'aksrt'); ?></span>
</button>
<?php else : ?>
<a href="<?php echo esc_url($login_url); ?>" class="post-drop-meta__item">
<i class="fa fa-flag" aria-hidden="true"></i>
<span><?php esc_html_e('登录后举报', 'aksrt'); ?></span>
</a>
<?php endif; ?>
</div>
</div>
</div>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
</div>