Merge pull request 'feat(pages): 1:1 文档导航 + 文章归档 (zibll documentnav/archives)' (#215) from worktree-docnav-archives-1to1 into main
Reviewed-on: CYL/wordpress-theme-aksrt#215
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Archives page (zibll archives) styles.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
.page-template-archives .content-wrap {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.page-template-archives .content-layout {
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.page-template-archives .sidebar {
|
||||
flex: 0 0 300px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.archives-month-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0 8px 8px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.archives-month-list .author-set-left {
|
||||
width: 3.2em;
|
||||
flex: 0 0 3.2em;
|
||||
padding: 6px 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.archives-month-list .author-set-right {
|
||||
flex: 1 1 calc(100% - 3.5em);
|
||||
min-width: 0;
|
||||
padding: 6px 0;
|
||||
border-bottom: 1px dashed var(--main-border-color, rgba(0, 0, 0, 0.06));
|
||||
}
|
||||
|
||||
.archives-month-list .author-set-right a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.archives-month-list .author-set-right a:hover {
|
||||
color: var(--focus-color, var(--color-primary));
|
||||
}
|
||||
|
||||
.title-h-center {
|
||||
position: relative;
|
||||
padding-bottom: 8px;
|
||||
margin: 12px 0 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title-h-center:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
bottom: 3px;
|
||||
width: 40px;
|
||||
height: 3px;
|
||||
border-radius: 5px;
|
||||
background: var(--theme-color, var(--color-primary));
|
||||
}
|
||||
|
||||
.ml6 {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
@media (max-width: 991px) {
|
||||
.page-template-archives .sidebar {
|
||||
flex: 1 1 100%;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
/**
|
||||
* Document navigation page (zibll documentnav) styles.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
.page-template-documentnav .document-nav-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.page-template-documentnav .document-nav-aside {
|
||||
flex: 0 0 32%;
|
||||
max-width: 100%;
|
||||
min-width: 220px;
|
||||
}
|
||||
|
||||
.page-template-documentnav .document-nav-main {
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.document-nav .panel-group {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.document-nav .panel {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
border-top: 1px solid var(--main-border-color, #eee);
|
||||
}
|
||||
|
||||
.document-nav .panel-title {
|
||||
margin: 0;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.document-nav .panel-toggle {
|
||||
padding: 10px;
|
||||
display: block;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.document-nav .panel-toggle:not(.collapsed) {
|
||||
color: var(--focus-color, var(--color-primary));
|
||||
}
|
||||
|
||||
.document-nav .panel-toggle .fa {
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.document-nav .panel-toggle:not(.collapsed) .fa {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.document-nav .panel-collapse {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.document-nav .panel-collapse.is-open,
|
||||
.document-nav .panel-collapse.in {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.document-nav .panel-child,
|
||||
.document-nav .category {
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.document-nav .cat-load {
|
||||
padding: 10px;
|
||||
display: block;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.document-nav > .panel-group > .cat-load {
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
.document-nav > .panel-group > .cat-load::before {
|
||||
content: '';
|
||||
width: 0.5em;
|
||||
height: 0.5em;
|
||||
border: 0.1em solid var(--focus-color, var(--color-primary));
|
||||
border-radius: 1em;
|
||||
margin: 0 0.5em;
|
||||
vertical-align: 0.1em;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.document-nav .cat-load.active {
|
||||
background: var(--main-border-color, rgba(0, 0, 0, 0.06));
|
||||
color: var(--focus-color, var(--color-primary));
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.document-nav .loading {
|
||||
overflow: hidden;
|
||||
width: 0;
|
||||
opacity: 0;
|
||||
transition: 0.3s;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.document-nav .is-loading .loading,
|
||||
.document-nav .cat-load.is-loading .loading {
|
||||
width: 0.7em;
|
||||
opacity: 1;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.document-nav-container {
|
||||
transition: 0.3s;
|
||||
min-height: 120px;
|
||||
}
|
||||
|
||||
.document-nav-container.is-loading {
|
||||
opacity: 0.55;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.document-search {
|
||||
position: relative;
|
||||
margin-bottom: 16px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.document-search .line-form {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.document-search .line-form-input {
|
||||
width: 100%;
|
||||
border: 1px solid var(--main-border-color, #ddd);
|
||||
border-radius: 8px;
|
||||
padding: 10px 40px 10px 12px;
|
||||
box-sizing: border-box;
|
||||
background: var(--main-bg-color, #fff);
|
||||
}
|
||||
|
||||
.document-search .abs-right {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
border: 0;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
color: var(--muted-2-color, #888);
|
||||
}
|
||||
|
||||
.document-search .search-loading {
|
||||
inset: 0;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 8px;
|
||||
background: color-mix(in srgb, var(--main-bg-color, #fff) 88%, transparent);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.document-search.is-loading .search-loading {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.list-group {
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
display: block;
|
||||
padding: 12px 14px;
|
||||
background: var(--main-bg-color, #fff);
|
||||
border-bottom: 1px solid var(--muted-border-color, #eee);
|
||||
color: var(--main-color, inherit);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.list-group-item:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
a.list-group-item:hover,
|
||||
a.list-group-item:focus {
|
||||
background: var(--body-bg-color, #f7f7f8);
|
||||
color: var(--focus-color, var(--color-primary));
|
||||
}
|
||||
|
||||
.list-group-item .pull-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.list-group-item .badg-sm {
|
||||
font-size: 12px;
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
.list-group-item .focus-color {
|
||||
color: var(--focus-color, var(--color-primary));
|
||||
}
|
||||
|
||||
.document-nav-container .pagenav a {
|
||||
display: inline-block;
|
||||
min-width: 32px;
|
||||
padding: 4px 8px;
|
||||
margin: 2px;
|
||||
border-radius: 4px;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
background: var(--surface-2, #f0f0f0);
|
||||
}
|
||||
|
||||
.document-nav-container .pagenav a.current {
|
||||
background: var(--focus-color, var(--color-primary));
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.history-search .search_keywords {
|
||||
display: inline-block;
|
||||
margin: 0 6px 6px 0;
|
||||
padding: 2px 8px;
|
||||
border-radius: 999px;
|
||||
background: var(--surface-2, #f0f0f0);
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.page-template-documentnav .document-nav-aside,
|
||||
.page-template-documentnav .document-nav-main {
|
||||
flex: 1 1 100%;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
/**
|
||||
* Document navigation AJAX (zibll page-template documentnav subset).
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function ajaxUrl() {
|
||||
if (window.aksrtData && window.aksrtData.ajaxUrl) return window.aksrtData.ajaxUrl;
|
||||
return '/wp-admin/admin-ajax.php';
|
||||
}
|
||||
|
||||
function toast(msg, type) {
|
||||
if (window.aksrt && typeof window.aksrt.toast === 'function') {
|
||||
window.aksrt.toast(msg, type || 'info');
|
||||
return;
|
||||
}
|
||||
// eslint-disable-next-line no-alert
|
||||
window.alert(msg);
|
||||
}
|
||||
|
||||
function qs(sel, root) {
|
||||
return (root || document).querySelector(sel);
|
||||
}
|
||||
|
||||
function qsa(sel, root) {
|
||||
return Array.prototype.slice.call((root || document).querySelectorAll(sel));
|
||||
}
|
||||
|
||||
function documentAjax(triggerEl, data, url) {
|
||||
var container = qs('.document-nav-container');
|
||||
var searchBox = qs('.document-search');
|
||||
if (!container) return;
|
||||
|
||||
container.classList.add('is-loading');
|
||||
if (searchBox && data && data.search) searchBox.classList.add('is-loading');
|
||||
|
||||
data = data || {};
|
||||
data.one_cat = container.getAttribute('data-one-cat') || '';
|
||||
data.action = 'aksrt_documentnav_posts';
|
||||
|
||||
var body = new URLSearchParams();
|
||||
Object.keys(data).forEach(function (k) {
|
||||
if (data[k] !== undefined && data[k] !== null) body.append(k, data[k]);
|
||||
});
|
||||
|
||||
fetch(url || ajaxUrl(), {
|
||||
method: 'POST',
|
||||
credentials: 'same-origin',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
|
||||
body: body.toString(),
|
||||
})
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (n) {
|
||||
if (!n || n.error || !n.html) {
|
||||
toast((n && n.msg) || '加载失败,请重试', 'danger');
|
||||
}
|
||||
if (n && n.html) container.innerHTML = n.html;
|
||||
if (n && n.history_search) {
|
||||
var hist = qs('.history-search > div');
|
||||
if (hist) hist.innerHTML = n.history_search;
|
||||
}
|
||||
})
|
||||
.catch(function () {
|
||||
toast('网络错误', 'danger');
|
||||
})
|
||||
.finally(function () {
|
||||
container.classList.remove('is-loading');
|
||||
if (searchBox) searchBox.classList.remove('is-loading');
|
||||
if (triggerEl && triggerEl.classList) triggerEl.classList.remove('is-loading');
|
||||
});
|
||||
}
|
||||
|
||||
function initAccordion() {
|
||||
var nav = qs('.document-nav');
|
||||
if (!nav) return;
|
||||
nav.addEventListener('click', function (e) {
|
||||
var toggle = e.target.closest('.panel-toggle[data-toggle="collapse"]');
|
||||
if (!toggle) return;
|
||||
e.preventDefault();
|
||||
var targetSel = toggle.getAttribute('data-target');
|
||||
var panel = targetSel ? qs(targetSel, nav) : null;
|
||||
if (!panel) return;
|
||||
var parentSel = toggle.getAttribute('data-parent');
|
||||
if (parentSel) {
|
||||
var parent = qs(parentSel, nav);
|
||||
if (parent) {
|
||||
qsa('.panel-collapse.is-open, .panel-collapse.in', parent).forEach(function (p) {
|
||||
if (p !== panel) {
|
||||
p.classList.remove('is-open', 'in');
|
||||
var t = parent.querySelector('[data-target="#' + p.id + '"]');
|
||||
if (t) t.classList.add('collapsed');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
var open = panel.classList.contains('is-open') || panel.classList.contains('in');
|
||||
if (open) {
|
||||
panel.classList.remove('is-open', 'in');
|
||||
toggle.classList.add('collapsed');
|
||||
} else {
|
||||
panel.classList.add('is-open', 'in');
|
||||
toggle.classList.remove('collapsed');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function initSearch() {
|
||||
var form = qs('.document-search-form');
|
||||
if (!form) return;
|
||||
form.addEventListener('submit', function (e) {
|
||||
e.preventDefault();
|
||||
var input = form.querySelector('[name="s"]');
|
||||
var search = input ? String(input.value || '').trim() : '';
|
||||
if (!search.length) {
|
||||
toast('请输入搜索关键词', 'warning');
|
||||
return;
|
||||
}
|
||||
if (search.length < 2) {
|
||||
toast('关键词太短', 'warning');
|
||||
return;
|
||||
}
|
||||
qsa('.cat-load').forEach(function (el) {
|
||||
el.classList.remove('is-loading', 'active');
|
||||
});
|
||||
documentAjax(qs('.document-search'), { search: search });
|
||||
});
|
||||
|
||||
document.addEventListener('click', function (e) {
|
||||
var kw = e.target.closest('.document-search .search_keywords');
|
||||
if (!kw) return;
|
||||
e.preventDefault();
|
||||
var text = (kw.textContent || '').trim();
|
||||
var input = qs('.document-search-form [name="s"]');
|
||||
if (input) {
|
||||
input.value = text;
|
||||
input.dispatchEvent(new Event('input', { bubbles: true }));
|
||||
}
|
||||
if (form) form.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true }));
|
||||
});
|
||||
}
|
||||
|
||||
function initCatLoad() {
|
||||
document.addEventListener('click', function (e) {
|
||||
var a = e.target.closest('.cat-load');
|
||||
if (!a) return;
|
||||
e.preventDefault();
|
||||
qsa('.cat-load').forEach(function (el) {
|
||||
el.classList.remove('is-loading', 'active');
|
||||
});
|
||||
a.classList.add('is-loading', 'active');
|
||||
var catId = a.getAttribute('data-cat-id') || a.getAttribute('cat-id') || '';
|
||||
documentAjax(a, { cat_id: catId });
|
||||
});
|
||||
}
|
||||
|
||||
function initPager() {
|
||||
document.addEventListener('click', function (e) {
|
||||
var a = e.target.closest('.document-nav-container .pagenav a');
|
||||
if (!a) return;
|
||||
e.preventDefault();
|
||||
var paged = a.getAttribute('data-paged') || '';
|
||||
var href = a.getAttribute('href') || '';
|
||||
if (paged) {
|
||||
// Prefer current context from last active cat or search.
|
||||
var active = qs('.cat-load.active');
|
||||
var searchInput = qs('.document-search-form [name="s"]');
|
||||
var data = { paged: paged };
|
||||
if (active) {
|
||||
data.cat_id = active.getAttribute('data-cat-id') || '';
|
||||
} else if (searchInput && searchInput.value) {
|
||||
data.search = searchInput.value.trim();
|
||||
}
|
||||
documentAjax(a, data);
|
||||
return;
|
||||
}
|
||||
if (href && href.indexOf('admin-ajax.php') !== -1) {
|
||||
documentAjax(a, {}, href);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function init() {
|
||||
if (!qs('.document-nav-container') && !qs('.document-nav')) return;
|
||||
initAccordion();
|
||||
initSearch();
|
||||
initCatLoad();
|
||||
initPager();
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
})();
|
||||
@@ -261,6 +261,9 @@ if (class_exists('\AKSRT\Core\PostsNavs')) {
|
||||
if (class_exists('\AKSRT\User\AuthApply')) {
|
||||
\AKSRT\User\AuthApply::get_instance()->init();
|
||||
}
|
||||
if (class_exists('\AKSRT\Core\DocumentNav')) {
|
||||
\AKSRT\Core\DocumentNav::get_instance()->init();
|
||||
}
|
||||
if (class_exists('\AKSRT\Messages\SiteNotice')) {
|
||||
\AKSRT\Messages\SiteNotice::get_instance()->init();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,316 @@
|
||||
<?php
|
||||
/**
|
||||
* Document navigation (zibll documentnav) — category tree + AJAX posts.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
namespace AKSRT\Core;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class DocumentNav {
|
||||
|
||||
private static $instance = null;
|
||||
|
||||
public static function get_instance(): self {
|
||||
if (null === self::$instance) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function init(): void {
|
||||
add_action('wp_ajax_aksrt_documentnav_posts', [$this, 'ajax_posts']);
|
||||
add_action('wp_ajax_nopriv_aksrt_documentnav_posts', [$this, 'ajax_posts']);
|
||||
add_action('add_meta_boxes', [$this, 'register_meta_box']);
|
||||
add_action('save_post_page', [$this, 'save_meta_box']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{cat:int,initial_content:string}
|
||||
*/
|
||||
public static function get_options(int $post_id): array {
|
||||
$raw = get_post_meta($post_id, 'documentnav_options', true);
|
||||
if (!is_array($raw)) {
|
||||
$raw = [];
|
||||
}
|
||||
$cat = isset($raw['cat']) ? absint($raw['cat']) : absint(get_post_meta($post_id, 'documentnav_cat', true));
|
||||
$initial = isset($raw['initial_content']) ? sanitize_key((string) $raw['initial_content']) : sanitize_key((string) get_post_meta($post_id, 'documentnav_initial_content', true));
|
||||
if (!in_array($initial, ['page_content', 'date_posts', 'updated_posts', 'views_posts'], true)) {
|
||||
$initial = 'updated_posts';
|
||||
}
|
||||
return [
|
||||
'cat' => $cat,
|
||||
'initial_content' => $initial,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render posts list HTML (zibll zib_get_documentnav_posts).
|
||||
*/
|
||||
public static function render_posts_html(\WP_Query $query): string {
|
||||
if (!$query->have_posts()) {
|
||||
$empty = function_exists('aksrt_get_null')
|
||||
? aksrt_get_null(__('暂无相应内容', 'aksrt'), 40)
|
||||
: '<p class="muted-2-color text-center">' . esc_html__('暂无相应内容', 'aksrt') . '</p>';
|
||||
return '<div class="zib-widget">' . $empty . '</div>';
|
||||
}
|
||||
|
||||
$html = '<div class="list-group main-shadow">';
|
||||
while ($query->have_posts()) {
|
||||
$query->the_post();
|
||||
$time_ago = human_time_diff(get_the_time('U'), current_time('timestamp')) . __('前', 'aksrt');
|
||||
$subtitle = (string) get_post_meta(get_the_ID(), 'subtitle', true);
|
||||
if ($subtitle === '') {
|
||||
$subtitle = (string) get_post_meta(get_the_ID(), 'aksrt_subtitle', true);
|
||||
}
|
||||
$html .= '<a class="list-group-item" href="' . esc_url(get_permalink()) . '">';
|
||||
$html .= '<span class="badg badg-sm pull-right" title="' . esc_attr(get_the_time('Y-m-d H:i:s')) . '">' . esc_html($time_ago) . '</span>';
|
||||
$html .= esc_html(get_the_title());
|
||||
if ($subtitle !== '') {
|
||||
$html .= '<span class="focus-color"> ' . esc_html($subtitle) . '</span>';
|
||||
}
|
||||
$html .= '</a>';
|
||||
}
|
||||
$html .= '</div>';
|
||||
wp_reset_postdata();
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple paginate links for document nav container.
|
||||
*/
|
||||
public static function render_paginate(int $total, int $current, int $page_size, array $args = []): string {
|
||||
$max = (int) ceil(max(0, $total) / max(1, $page_size));
|
||||
if ($max <= 1) {
|
||||
return '';
|
||||
}
|
||||
$current = max(1, min($current, $max));
|
||||
$html = '<div class="pagenav notop text-center mt15">';
|
||||
for ($i = 1; $i <= $max; $i++) {
|
||||
$url = add_query_arg(array_merge($args, ['paged' => $i]));
|
||||
$cls = $i === $current ? 'current' : '';
|
||||
$html .= '<a class="' . esc_attr($cls) . '" href="' . esc_url($url) . '" data-paged="' . (int) $i . '">' . (int) $i . '</a> ';
|
||||
}
|
||||
$html .= '</div>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive category accordion HTML.
|
||||
*/
|
||||
public static function render_panels(int $cat_id, string $data_parent = 'accordion', string $class = 'panel', bool &$is_on_open = true): string {
|
||||
if ($cat_id <= 0) {
|
||||
return '';
|
||||
}
|
||||
$terms = _get_term_hierarchy('category');
|
||||
if (empty($terms[$cat_id]) || !is_array($terms[$cat_id])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$html = '<div class="panel-group posts-panel-group" id="' . esc_attr($data_parent) . '">';
|
||||
foreach ($terms[$cat_id] as $child) {
|
||||
$child = (int) $child;
|
||||
if ($child === $cat_id) {
|
||||
continue;
|
||||
}
|
||||
$cat_obj = get_category($child);
|
||||
if (!$cat_obj || is_wp_error($cat_obj)) {
|
||||
continue;
|
||||
}
|
||||
$has_kids = !empty($terms[$child]);
|
||||
if ($has_kids) {
|
||||
$open = $is_on_open;
|
||||
$is_on_open = false;
|
||||
$html .= '<div class="' . esc_attr($class) . '">';
|
||||
$html .= '<h4 class="panel-title">';
|
||||
$html .= '<a class="panel-toggle' . ($open ? '' : ' collapsed') . ' text-ellipsis" href="javascript:;" data-toggle="collapse" data-target="#dosc-nav-catid_' . $child . '" data-parent="#' . esc_attr($data_parent) . '">';
|
||||
$html .= '<i class="fa fa-angle-right mr10" aria-hidden="true"></i>' . esc_html($cat_obj->name);
|
||||
$html .= '</a></h4>';
|
||||
$html .= '<div id="dosc-nav-catid_' . $child . '" class="panel-collapse' . ($open ? ' collapse in is-open' : ' collapse') . '">';
|
||||
$html .= '<div class="category">';
|
||||
$html .= self::render_panels($child, 'dosc-cat-nav-panel-' . $child, 'panel panel-child', $is_on_open);
|
||||
$html .= '</div></div></div>';
|
||||
} else {
|
||||
$html .= '<a class="cat-load text-ellipsis" data-cat-id="' . $child . '" href="javascript:;" title="' . esc_attr($cat_obj->name) . '">';
|
||||
$html .= '<i class="loading" aria-hidden="true"></i>' . esc_html($cat_obj->name);
|
||||
$html .= '</a>';
|
||||
}
|
||||
}
|
||||
$html .= '</div>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function ajax_posts(): void {
|
||||
$search = isset($_REQUEST['search']) ? sanitize_text_field(wp_unslash((string) $_REQUEST['search'])) : '';
|
||||
$cat_id = isset($_REQUEST['cat_id']) ? absint($_REQUEST['cat_id']) : 0;
|
||||
$one_cat = isset($_REQUEST['one_cat']) ? absint($_REQUEST['one_cat']) : 0;
|
||||
$paged = isset($_REQUEST['paged']) ? max(1, absint($_REQUEST['paged'])) : 1;
|
||||
$page_size = 12;
|
||||
|
||||
if ($search === '' && $cat_id <= 0) {
|
||||
wp_send_json(['error' => 1, 'ys' => 'danger', 'msg' => __('参数传入错误!', 'aksrt')]);
|
||||
}
|
||||
|
||||
$args = [
|
||||
'ignore_sticky_posts' => true,
|
||||
'paged' => $paged,
|
||||
'posts_per_page' => $page_size,
|
||||
'post_status' => 'publish',
|
||||
'post_type' => 'post',
|
||||
];
|
||||
|
||||
if ($search !== '') {
|
||||
$args['s'] = $search;
|
||||
$args['cat'] = $one_cat > 0 ? $one_cat : 0;
|
||||
// Persist simple history (user meta or cookie-less option list is optional).
|
||||
$this->remember_search($search);
|
||||
} else {
|
||||
$args['cat'] = $cat_id;
|
||||
}
|
||||
|
||||
$query = new \WP_Query($args);
|
||||
$html = self::render_posts_html($query);
|
||||
$html .= self::render_paginate(
|
||||
(int) $query->found_posts,
|
||||
$paged,
|
||||
$page_size,
|
||||
[
|
||||
'action' => 'aksrt_documentnav_posts',
|
||||
'cat_id' => $cat_id,
|
||||
'search' => $search,
|
||||
'one_cat' => $one_cat,
|
||||
]
|
||||
);
|
||||
|
||||
wp_send_json([
|
||||
'error' => 0,
|
||||
'html' => $html,
|
||||
'total' => (int) $query->found_posts,
|
||||
'history_search' => $this->history_buttons_html(),
|
||||
]);
|
||||
}
|
||||
|
||||
private function remember_search(string $term): void {
|
||||
$term = trim($term);
|
||||
if ($term === '' || mb_strlen($term) < 2) {
|
||||
return;
|
||||
}
|
||||
$key = is_user_logged_in() ? 'aksrt_doc_search_history_' . get_current_user_id() : '';
|
||||
$list = [];
|
||||
if ($key !== '') {
|
||||
$saved = get_user_meta(get_current_user_id(), 'aksrt_doc_search_history', true);
|
||||
$list = is_array($saved) ? $saved : [];
|
||||
} else {
|
||||
$cookie = isset($_COOKIE['aksrt_doc_search_history']) ? wp_unslash((string) $_COOKIE['aksrt_doc_search_history']) : '';
|
||||
$decoded = json_decode($cookie, true);
|
||||
$list = is_array($decoded) ? $decoded : [];
|
||||
}
|
||||
$list = array_values(array_unique(array_filter(array_map('strval', $list))));
|
||||
array_unshift($list, $term);
|
||||
$list = array_slice(array_values(array_unique($list)), 0, 8);
|
||||
if ($key !== '') {
|
||||
update_user_meta(get_current_user_id(), 'aksrt_doc_search_history', $list);
|
||||
} elseif (!headers_sent()) {
|
||||
setcookie('aksrt_doc_search_history', wp_json_encode($list), time() + WEEK_IN_SECONDS, COOKIEPATH ?: '/', COOKIE_DOMAIN, is_ssl(), true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<string>
|
||||
*/
|
||||
private function get_history(): array {
|
||||
if (is_user_logged_in()) {
|
||||
$saved = get_user_meta(get_current_user_id(), 'aksrt_doc_search_history', true);
|
||||
return is_array($saved) ? array_values(array_filter(array_map('strval', $saved))) : [];
|
||||
}
|
||||
$cookie = isset($_COOKIE['aksrt_doc_search_history']) ? wp_unslash((string) $_COOKIE['aksrt_doc_search_history']) : '';
|
||||
$decoded = json_decode($cookie, true);
|
||||
return is_array($decoded) ? array_values(array_filter(array_map('strval', $decoded))) : [];
|
||||
}
|
||||
|
||||
public function history_buttons_html(): string {
|
||||
$items = $this->get_history();
|
||||
if (!$items) {
|
||||
return '';
|
||||
}
|
||||
$html = '';
|
||||
foreach ($items as $term) {
|
||||
$html .= '<a href="javascript:;" class="search_keywords but badg mr6 mb6">' . esc_html($term) . '</a>';
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function register_meta_box(): void {
|
||||
add_meta_box(
|
||||
'aksrt_documentnav_meta',
|
||||
__('文档导航设置', 'aksrt'),
|
||||
[$this, 'render_meta_box'],
|
||||
'page',
|
||||
'side',
|
||||
'default'
|
||||
);
|
||||
}
|
||||
|
||||
public function render_meta_box(\WP_Post $post): void {
|
||||
$tpl = (string) get_post_meta($post->ID, '_wp_page_template', true);
|
||||
if ($tpl !== 'templates/pages/page-documentnav.php') {
|
||||
echo '<p class="description">' . esc_html__('将模板设为「AKSRT - 文档导航」后配置。', 'aksrt') . '</p>';
|
||||
return;
|
||||
}
|
||||
$opt = self::get_options((int) $post->ID);
|
||||
wp_nonce_field('aksrt_documentnav_meta', 'aksrt_documentnav_meta_nonce');
|
||||
$cats = get_categories(['hide_empty' => false, 'parent' => 0]);
|
||||
?>
|
||||
<p>
|
||||
<label for="documentnav_cat"><strong><?php esc_html_e('一级分类', 'aksrt'); ?></strong></label>
|
||||
<select name="documentnav_cat" id="documentnav_cat" class="widefat">
|
||||
<option value="0"><?php esc_html_e('请选择', 'aksrt'); ?></option>
|
||||
<?php foreach ($cats as $c) : ?>
|
||||
<option value="<?php echo (int) $c->term_id; ?>" <?php selected($opt['cat'], (int) $c->term_id); ?>>
|
||||
<?php echo esc_html($c->name); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<label for="documentnav_initial_content"><strong><?php esc_html_e('初始内容', 'aksrt'); ?></strong></label>
|
||||
<select name="documentnav_initial_content" id="documentnav_initial_content" class="widefat">
|
||||
<?php
|
||||
$opts = [
|
||||
'page_content' => __('显示页面内容', 'aksrt'),
|
||||
'date_posts' => __('最近发布文章', 'aksrt'),
|
||||
'updated_posts' => __('最近更新文章', 'aksrt'),
|
||||
'views_posts' => __('查看最多文章', 'aksrt'),
|
||||
];
|
||||
foreach ($opts as $k => $label) :
|
||||
?>
|
||||
<option value="<?php echo esc_attr($k); ?>" <?php selected($opt['initial_content'], $k); ?>><?php echo esc_html($label); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function save_meta_box(int $post_id): void {
|
||||
if (!isset($_POST['aksrt_documentnav_meta_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash((string) $_POST['aksrt_documentnav_meta_nonce'])), 'aksrt_documentnav_meta')) {
|
||||
return;
|
||||
}
|
||||
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
|
||||
return;
|
||||
}
|
||||
if (!current_user_can('edit_post', $post_id)) {
|
||||
return;
|
||||
}
|
||||
$cat = isset($_POST['documentnav_cat']) ? absint($_POST['documentnav_cat']) : 0;
|
||||
$initial = isset($_POST['documentnav_initial_content']) ? sanitize_key((string) wp_unslash($_POST['documentnav_initial_content'])) : 'updated_posts';
|
||||
if (!in_array($initial, ['page_content', 'date_posts', 'updated_posts', 'views_posts'], true)) {
|
||||
$initial = 'updated_posts';
|
||||
}
|
||||
update_post_meta($post_id, 'documentnav_options', [
|
||||
'cat' => $cat,
|
||||
'initial_content' => $initial,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -458,6 +458,42 @@ trait ScriptsPart1b {
|
||||
}
|
||||
}
|
||||
|
||||
// 文章归档页
|
||||
if (is_page_template('templates/pages/page-archives.php')) {
|
||||
$ar_css = get_template_directory() . '/assets/css/routes/archives.css';
|
||||
if (file_exists($ar_css)) {
|
||||
wp_enqueue_style(
|
||||
'aksrt-route-archives',
|
||||
$base_uri . '/assets/css/routes/archives.css',
|
||||
['aksrt-tokens'],
|
||||
(string) filemtime($ar_css)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 文档导航页(zibll documentnav.php)
|
||||
if (is_page_template('templates/pages/page-documentnav.php')) {
|
||||
$dn_css = get_template_directory() . '/assets/css/routes/documentnav.css';
|
||||
if (file_exists($dn_css)) {
|
||||
wp_enqueue_style(
|
||||
'aksrt-route-documentnav',
|
||||
$base_uri . '/assets/css/routes/documentnav.css',
|
||||
['aksrt-tokens'],
|
||||
(string) filemtime($dn_css)
|
||||
);
|
||||
}
|
||||
$dn_js = get_template_directory() . '/assets/js/documentnav-page.js';
|
||||
if (file_exists($dn_js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-documentnav-page',
|
||||
$base_uri . '/assets/js/documentnav-page.js',
|
||||
[],
|
||||
(string) filemtime($dn_js),
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 用户身份认证页(zibll user-auth.php)
|
||||
if (is_page_template('templates/pages/page-user-auth.php')) {
|
||||
$ua_css = get_template_directory() . '/assets/css/routes/user-auth.css';
|
||||
|
||||
@@ -40,6 +40,7 @@ class Templates {
|
||||
'templates/pages/page-profile.php' => __('AKSRT - 个人中心', 'aksrt'),
|
||||
'templates/pages/page-user-home.php' => __('AKSRT - 用户主页', 'aksrt'),
|
||||
'templates/pages/page-archives.php' => __('AKSRT - 文章归档', 'aksrt'),
|
||||
'templates/pages/page-documentnav.php' => __('AKSRT - 文档导航', 'aksrt'),
|
||||
'templates/pages/page-categories.php' => __('AKSRT - 分类汇总', 'aksrt'),
|
||||
'templates/pages/page-newposts.php' => __('AKSRT - 最新文章', 'aksrt'),
|
||||
// 注意:page-newposts = 最新文章列表;投稿页是 page-submit(写文章/投稿)
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - Archives
|
||||
* Template Name: AKSRT - 文章归档
|
||||
* Template Post Type: page
|
||||
*
|
||||
* 文章归档页:按年月分组展示全站文章。
|
||||
* Zibll pages/archives.php 1:1 — month groups with view/comment/like meta,
|
||||
* theme-box shell, sidebar + comments.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
@@ -11,65 +12,104 @@
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
get_header();
|
||||
global $wpdb;
|
||||
|
||||
if (function_exists('aksrt_archive_open_shell')) {
|
||||
aksrt_archive_open_shell([
|
||||
'main_class' => 'site-main container content-shell content-shell--page page-content-default',
|
||||
'has_sidebar' => false,
|
||||
'page_kind' => 'archives',
|
||||
]);
|
||||
}
|
||||
$header_style = (string) get_post_meta(get_queried_object_id(), 'page_header_style', true);
|
||||
?>
|
||||
<div class="content-main content-main--page content-main--archives">
|
||||
<?php
|
||||
get_template_part('templates/parts/page-header', null, [
|
||||
'title' => esc_html__('文章归档', 'aksrt'),
|
||||
]);
|
||||
?>
|
||||
<main class="container page-template-archives">
|
||||
<div class="content-wrap">
|
||||
<div class="content-layout">
|
||||
<?php if ($header_style !== '1' && $header_style !== 'not') : ?>
|
||||
<div class="theme-box radius8 main-bg main-shadow box-body mb20">
|
||||
<h1 class="article-title"><?php echo esc_html(get_the_title() ?: __('文章归档', 'aksrt')); ?></h1>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="aksrt-archives">
|
||||
<?php
|
||||
$years = $wpdb->get_results(
|
||||
"SELECT DISTINCT YEAR(post_date) AS year, MONTH(post_date) AS month, COUNT(*) AS count
|
||||
FROM {$wpdb->posts}
|
||||
WHERE post_type = 'post' AND post_status = 'publish'
|
||||
GROUP BY YEAR(post_date), MONTH(post_date)
|
||||
ORDER BY year DESC, month DESC"
|
||||
); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
|
||||
|
||||
$current_year = 0;
|
||||
foreach ($years as $row) :
|
||||
if ((int) $row->year !== $current_year) :
|
||||
$current_year = (int) $row->year;
|
||||
?>
|
||||
<h2 class="aksrt-archives__year"><?php echo esc_html((string) $current_year); ?></h2>
|
||||
<?php endif; ?>
|
||||
<h3 class="aksrt-archives__month">
|
||||
<?php echo esc_html(sprintf('%d 月 (%d 篇)', (int) $row->month, (int) $row->count)); ?>
|
||||
</h3>
|
||||
<ul class="aksrt-archives__list">
|
||||
<?php
|
||||
$month_posts = get_posts([
|
||||
'year' => (int) $row->year,
|
||||
'monthnum' => (int) $row->month,
|
||||
'posts_per_page' => -1,
|
||||
'post_status' => 'publish',
|
||||
]);
|
||||
foreach ($month_posts as $mp) :
|
||||
?>
|
||||
<li class="aksrt-archives__item">
|
||||
<span class="aksrt-archives__date"><?php echo esc_html(get_the_date('m-d', $mp)); ?></span>
|
||||
<a href="<?php echo esc_url(get_permalink($mp->ID)); ?>" class="aksrt-archives__link"><?php echo esc_html($mp->post_title); ?></a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<div class="theme-box radius8 main-bg main-shadow">
|
||||
<?php if ($header_style === '1') : ?>
|
||||
<div class="box-body">
|
||||
<h1 class="article-title"><?php echo esc_html(get_the_title() ?: __('文章归档', 'aksrt')); ?></h1>
|
||||
</div>
|
||||
<?php
|
||||
if (function_exists('aksrt_archive_close_shell')) {
|
||||
aksrt_archive_close_shell(['has_sidebar' => false]);
|
||||
}
|
||||
<?php endif; ?>
|
||||
<article class="box-body">
|
||||
<?php
|
||||
$previous_year = 0;
|
||||
$previous_month = 0;
|
||||
$ul_open = false;
|
||||
|
||||
$myposts = get_posts([
|
||||
'numberposts' => -1,
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'post_status' => 'publish',
|
||||
'post_type' => 'post',
|
||||
'suppress_filters' => false,
|
||||
]);
|
||||
|
||||
foreach ($myposts as $post) :
|
||||
setup_postdata($post);
|
||||
$year = (int) get_the_time('Y', $post);
|
||||
$month = (int) get_the_time('n', $post);
|
||||
$day = (int) get_the_time('j', $post);
|
||||
|
||||
if ($year !== $previous_year || $month !== $previous_month) :
|
||||
if ($ul_open) {
|
||||
echo '</ul></div>';
|
||||
}
|
||||
echo '<div class="zib-widget mb20"><h4 class="text-center title-h-center">';
|
||||
echo esc_html(get_the_time('Y年n月', $post));
|
||||
echo '</h4><ul class="list-inline archives-month-list">';
|
||||
$ul_open = true;
|
||||
$previous_year = $year;
|
||||
$previous_month = $month;
|
||||
endif;
|
||||
|
||||
$views = function_exists('aksrt_get_post_views') ? (int) aksrt_get_post_views($post->ID) : 0;
|
||||
$likes = (int) get_post_meta($post->ID, 'like', true);
|
||||
if ($likes <= 0) {
|
||||
$likes = (int) get_post_meta($post->ID, 'aksrt_like', true);
|
||||
}
|
||||
$comments = (int) get_comments_number($post->ID);
|
||||
?>
|
||||
<li class="author-set-left muted-color">
|
||||
<time datetime="<?php echo esc_attr(get_the_date('c', $post)); ?>"><?php echo esc_html((string) $day); ?><?php esc_html_e('日', 'aksrt'); ?></time>
|
||||
</li>
|
||||
<li class="author-set-right">
|
||||
<a href="<?php echo esc_url(get_permalink($post)); ?>"><?php echo esc_html(get_the_title($post)); ?></a>
|
||||
<span class="muted-2-color ml6" title="<?php esc_attr_e('阅读', 'aksrt'); ?>">
|
||||
<i class="fa fa-eye" aria-hidden="true"></i><?php echo esc_html((string) $views); ?>
|
||||
</span>
|
||||
<?php if ($comments > 0) : ?>
|
||||
<span class="muted-2-color ml6" title="<?php esc_attr_e('评论', 'aksrt'); ?>">
|
||||
<i class="fa fa-comment-o" aria-hidden="true"></i><?php echo esc_html((string) $comments); ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
<?php if ($likes > 0) : ?>
|
||||
<span class="muted-2-color ml6" title="<?php esc_attr_e('点赞', 'aksrt'); ?>">
|
||||
<i class="fa fa-thumbs-o-up" aria-hidden="true"></i><?php echo esc_html((string) $likes); ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<?php
|
||||
endforeach;
|
||||
wp_reset_postdata();
|
||||
if ($ul_open) {
|
||||
echo '</ul></div>';
|
||||
}
|
||||
if (empty($myposts)) {
|
||||
echo '<p class="muted-2-color text-center">' . esc_html__('暂无文章', 'aksrt') . '</p>';
|
||||
}
|
||||
?>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
if (comments_open() || get_comments_number()) {
|
||||
comments_template();
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php get_sidebar(); ?>
|
||||
</main>
|
||||
<?php
|
||||
get_footer();
|
||||
|
||||
@@ -1,167 +1,116 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - Document Navigation
|
||||
* Template Name: AKSRT - 文档导航
|
||||
* Template Post Type: page
|
||||
*
|
||||
* 文档导航页:文档站式导航。
|
||||
* 支持侧边章节树、当前章节高亮、索引卡片、最近更新列表、基础搜索。
|
||||
* Zibll pages/documentnav.php 1:1 — category accordion + search + AJAX posts.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
use AKSRT\Core\DocumentNav;
|
||||
|
||||
$post_id = (int) get_queried_object_id();
|
||||
$opt = class_exists(DocumentNav::class)
|
||||
? DocumentNav::get_options($post_id)
|
||||
: ['cat' => 0, 'initial_content' => 'updated_posts'];
|
||||
$one_cat = (int) ($opt['cat'] ?? 0);
|
||||
$initial = (string) ($opt['initial_content'] ?? 'updated_posts');
|
||||
|
||||
get_header();
|
||||
|
||||
// Read doc mode settings
|
||||
$doc_settings = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_docs_mode_settings() : [];
|
||||
$default_order = $doc_settings['default_order'] ?? 'menu_order';
|
||||
|
||||
$presenter = class_exists('\AKSRT\Core\DocsPresenter') ? \AKSRT\Core\DocsPresenter::get_instance() : null;
|
||||
|
||||
// Get root-level pages
|
||||
$pages = $presenter
|
||||
? $presenter->get_root_pages($default_order)
|
||||
: get_pages([
|
||||
'sort_column' => $default_order === 'title' ? 'post_title' : ($default_order === 'date' ? 'post_date' : 'menu_order, post_title'),
|
||||
'sort_order' => 'ASC',
|
||||
'parent' => 0,
|
||||
'hierarchical' => 0,
|
||||
'post_status' => 'publish',
|
||||
]);
|
||||
|
||||
// Recent updates
|
||||
$recent_pages = $presenter
|
||||
? $presenter->get_recent_pages(8)
|
||||
: get_pages([
|
||||
'sort_column' => 'post_modified',
|
||||
'sort_order' => 'DESC',
|
||||
'number' => 8,
|
||||
'post_status' => 'publish',
|
||||
]);
|
||||
|
||||
$show_sidebar = !empty($doc_settings['toc_enabled']) || !empty($recent_pages);
|
||||
?>
|
||||
<main class="container page-template-documentnav">
|
||||
<div class="content-wrap">
|
||||
<div class="content-layout">
|
||||
<div class="theme-box radius8 main-bg main-shadow box-body mb20">
|
||||
<h1 class="article-title"><?php echo esc_html(get_the_title() ?: __('文档导航', 'aksrt')); ?></h1>
|
||||
</div>
|
||||
|
||||
<main id="main-content" class="container page-content-default" tabindex="-1">
|
||||
<div class="row document-nav-row">
|
||||
<div class="col-sm-4 document-nav-aside">
|
||||
<div class="theme-box zib-widget dosc-nav document-nav">
|
||||
<?php
|
||||
if ($one_cat > 0 && class_exists(DocumentNav::class)) {
|
||||
$open = true;
|
||||
echo DocumentNav::render_panels($one_cat, 'accordion', 'panel', $open); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
} elseif (current_user_can('edit_pages')) {
|
||||
echo '<p class="muted-2-color box-body">' . esc_html__('请在页面设置中选择一级分类。', 'aksrt') . '</p>';
|
||||
} else {
|
||||
echo '<p class="muted-2-color box-body">' . esc_html__('暂无文档分类', 'aksrt') . '</p>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-8 document-nav-main" role="main">
|
||||
<div class="theme-box zib-widget document-search relative-h">
|
||||
<form class="document-search-form" action="javascript:;" method="get">
|
||||
<div class="line-form">
|
||||
<input type="search" name="s" class="line-form-input document-search-input" placeholder="<?php esc_attr_e('搜索文档…', 'aksrt'); ?>" autocomplete="off" required minlength="2">
|
||||
<button type="submit" class="abs-right null" aria-label="<?php esc_attr_e('搜索', 'aksrt'); ?>">
|
||||
<i class="fa fa-search" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="history-search mt10">
|
||||
<div>
|
||||
<?php
|
||||
if (class_exists(DocumentNav::class)) {
|
||||
echo DocumentNav::get_instance()->history_buttons_html(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-loading absolute main-bg flex jc" hidden>
|
||||
<i class="loading mr10 em12" aria-hidden="true"></i> <?php esc_html_e('正在搜索', 'aksrt'); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<header class="aksrt-doc-nav-header">
|
||||
<h1 class="aksrt-doc-nav-header__title"><?php echo esc_html(get_the_title() ?: __('文档导航', 'aksrt')); ?></h1>
|
||||
<?php $desc = get_the_excerpt(); if ($desc) : ?>
|
||||
<p class="aksrt-doc-nav-header__desc"><?php echo esc_html($desc); ?></p>
|
||||
<?php endif; ?>
|
||||
</header>
|
||||
<div class="document-nav-container" data-one-cat="<?php echo (int) $one_cat; ?>">
|
||||
<?php
|
||||
if ($initial === 'page_content') {
|
||||
while (have_posts()) {
|
||||
the_post();
|
||||
echo '<div class="nopw-sm box-body theme-box radius8 main-bg main-shadow">';
|
||||
echo '<article class="article wp-posts-content">';
|
||||
the_content();
|
||||
echo '</article></div>';
|
||||
}
|
||||
} elseif ($one_cat > 0 && class_exists(DocumentNav::class)) {
|
||||
$args = [
|
||||
'cat' => $one_cat,
|
||||
'order' => 'DESC',
|
||||
'orderby' => 'modified',
|
||||
'posts_per_page' => 12,
|
||||
'no_found_rows' => true,
|
||||
'ignore_sticky_posts' => true,
|
||||
'post_status' => 'publish',
|
||||
];
|
||||
if ($initial === 'date_posts') {
|
||||
$args['orderby'] = 'date';
|
||||
} elseif ($initial === 'views_posts') {
|
||||
$args['orderby'] = 'meta_value_num';
|
||||
$args['meta_key'] = 'aksrt_post_views';
|
||||
}
|
||||
$q = new WP_Query($args);
|
||||
echo DocumentNav::render_posts_html($q); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
} else {
|
||||
echo '<div class="zib-widget"><p class="muted-2-color text-center">' . esc_html__('请配置文档分类', 'aksrt') . '</p></div>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="aksrt-doc-nav container" data-aksrt-doc-page-id="<?php echo (int) get_the_ID(); ?>">
|
||||
<div class="content-wrap">
|
||||
<div class="content-layout<?php echo $show_sidebar && !empty($recent_pages) ? '' : ' content-layout--no-sidebar'; ?>">
|
||||
<div class="content-layout__primary">
|
||||
<!-- Quick search -->
|
||||
<div class="aksrt-doc-nav__search">
|
||||
<input type="text" class="aksrt-doc-nav__search-input" placeholder="<?php esc_attr_e('搜索文档...', 'aksrt'); ?>" id="aksrt-doc-search">
|
||||
<i class="fas fa-search aksrt-doc-nav__search-icon"></i>
|
||||
</div>
|
||||
<div class="aksrt-doc-search__results" data-aksrt-doc-search-results hidden></div>
|
||||
|
||||
<?php if (!empty($pages)) : ?>
|
||||
<!-- Toolbar: category chips -->
|
||||
<div class="aksrt-doc-toolbar">
|
||||
<div class="aksrt-doc-toolbar__chips">
|
||||
<button type="button" class="aksrt-doc-toolbar__chip is-active" data-cat-id="0"><?php esc_html_e('全部', 'aksrt'); ?></button>
|
||||
<?php foreach ($pages as $p) : ?>
|
||||
<button type="button" class="aksrt-doc-toolbar__chip" data-cat-id="<?php echo (int) $p->ID; ?>"><?php echo esc_html($p->post_title); ?></button>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<span class="aksrt-doc-toolbar__meta"><?php printf(esc_html__('%d 篇文档', 'aksrt'), count($pages)); ?></span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="aksrt-doc-nav__layout">
|
||||
<!-- Document index cards -->
|
||||
<div class="aksrt-doc-nav__main">
|
||||
<?php if (!empty($pages)) : ?>
|
||||
<div class="aksrt-doc-nav__grid">
|
||||
<?php foreach ($pages as $p) :
|
||||
$children = $presenter
|
||||
? $presenter->get_flat_tree($p->ID, 1)
|
||||
: get_pages([
|
||||
'child_of' => $p->ID,
|
||||
'sort_column' => 'menu_order',
|
||||
'sort_order' => 'ASC',
|
||||
'parent' => $p->ID,
|
||||
'post_status' => 'publish',
|
||||
]);
|
||||
$child_count = count($children);
|
||||
$thumb = get_the_post_thumbnail_url($p->ID, 'medium');
|
||||
$excerpt = wp_trim_words($p->post_excerpt, 30, '...');
|
||||
?>
|
||||
<a href="<?php echo esc_url(get_permalink($p->ID)); ?>" class="aksrt-doc-index-card" data-cat-id="<?php echo (int) $p->ID; ?>">
|
||||
<?php if ($thumb) : ?>
|
||||
<div class="aksrt-doc-index-card__thumb">
|
||||
<img src="<?php echo esc_url($thumb); ?>" alt=""<?php echo function_exists('aksrt_lazy_loading') ? aksrt_lazy_loading('other') : ' loading="lazy"'; ?>>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="aksrt-doc-index-card__icon">
|
||||
<i class="fas fa-book-open"></i>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="aksrt-doc-index-card__body">
|
||||
<h3 class="aksrt-doc-index-card__title"><?php echo esc_html($p->post_title); ?></h3>
|
||||
<?php if ($excerpt) : ?>
|
||||
<p class="aksrt-doc-index-card__desc"><?php echo esc_html($excerpt); ?></p>
|
||||
<?php endif; ?>
|
||||
<div class="aksrt-doc-index-card__meta">
|
||||
<?php if ($child_count > 0) : ?>
|
||||
<span class="aksrt-doc-index-card__count">
|
||||
<i class="fas fa-file-alt"></i>
|
||||
<?php printf(esc_html__('%d 篇文章', 'aksrt'), $child_count); ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
<span class="aksrt-doc-index-card__date">
|
||||
<i class="fas fa-clock"></i>
|
||||
<?php echo esc_html(get_the_date('', $p->ID)); ?>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<i class="fas fa-chevron-right aksrt-doc-index-card__arrow"></i>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="aksrt-doc-nav__empty">
|
||||
<i class="fas fa-book-open"></i>
|
||||
<p><?php esc_html_e('暂无文档页面。', 'aksrt'); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Sidebar: Recent updates -->
|
||||
<?php if ($show_sidebar && !empty($recent_pages)) : ?>
|
||||
<aside class="aksrt-doc-nav__sidebar sidebar">
|
||||
<div class="aksrt-doc-nav__recent">
|
||||
<h3 class="aksrt-doc-nav__recent-title">
|
||||
<i class="fas fa-clock"></i>
|
||||
<?php esc_html_e('最近更新', 'aksrt'); ?>
|
||||
</h3>
|
||||
<ul class="aksrt-doc-nav__recent-list">
|
||||
<?php foreach ($recent_pages as $rp) : ?>
|
||||
<li class="aksrt-doc-nav__recent-item">
|
||||
<a href="<?php echo esc_url(get_permalink($rp->ID)); ?>">
|
||||
<span class="aksrt-doc-nav__recent-name"><?php echo esc_html($rp->post_title); ?></span>
|
||||
<time class="aksrt-doc-nav__recent-date"><?php echo esc_html(get_the_date('', $rp->ID)); ?></time>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
if (comments_open() || get_comments_number()) {
|
||||
comments_template();
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php get_sidebar(); ?>
|
||||
</main>
|
||||
|
||||
<?php
|
||||
get_footer();
|
||||
|
||||
Reference in New Issue
Block a user