导入 AKSRT 主题开发源码
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/**
|
||||
* Document Chapter Navigation
|
||||
*
|
||||
* Shows previous/next chapter navigation at the bottom of a document page.
|
||||
* Uses AKSRT_Docs_Presenter for chapter resolution.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$current_id = get_the_ID();
|
||||
|
||||
$presenter = class_exists('AKSRT_Docs_Presenter') ? AKSRT_Docs_Presenter::get_instance() : null;
|
||||
|
||||
if ($presenter) {
|
||||
$nav = $presenter->get_chapter_nav($current_id);
|
||||
$prev_page = $nav['prev'];
|
||||
$next_page = $nav['next'];
|
||||
} else {
|
||||
$parent_id = wp_get_post_parent_id($current_id);
|
||||
$siblings = get_pages([
|
||||
'parent' => $parent_id ?: 0,
|
||||
'sort_column' => 'menu_order, post_title',
|
||||
'sort_order' => 'ASC',
|
||||
'post_status' => 'publish',
|
||||
]);
|
||||
|
||||
$current_index = -1;
|
||||
foreach ($siblings as $i => $sibling) {
|
||||
if ((int) $sibling->ID === $current_id) {
|
||||
$current_index = $i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$prev_page = $current_index > 0 ? $siblings[$current_index - 1] : null;
|
||||
$next_page = ($current_index >= 0 && $current_index < count($siblings) - 1)
|
||||
? $siblings[$current_index + 1]
|
||||
: null;
|
||||
}
|
||||
|
||||
if (!$prev_page && !$next_page) return;
|
||||
?>
|
||||
<nav class="aksrt-doc-chapter-nav" aria-label="<?php esc_attr_e('章节导航', 'aksrt'); ?>">
|
||||
<?php if ($prev_page) : ?>
|
||||
<a href="<?php echo esc_url(get_permalink($prev_page->ID)); ?>" class="aksrt-doc-chapter-nav__prev">
|
||||
<span class="aksrt-doc-chapter-nav__label">
|
||||
<i class="fas fa-arrow-left"></i>
|
||||
<?php esc_html_e('上一篇', 'aksrt'); ?>
|
||||
</span>
|
||||
<span class="aksrt-doc-chapter-nav__title"><?php echo esc_html($prev_page->post_title); ?></span>
|
||||
</a>
|
||||
<?php else : ?>
|
||||
<div class="aksrt-doc-chapter-nav__prev aksrt-doc-chapter-nav__prev--disabled"></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($next_page) : ?>
|
||||
<a href="<?php echo esc_url(get_permalink($next_page->ID)); ?>" class="aksrt-doc-chapter-nav__next">
|
||||
<span class="aksrt-doc-chapter-nav__label">
|
||||
<?php esc_html_e('下一篇', 'aksrt'); ?>
|
||||
<i class="fas fa-arrow-right"></i>
|
||||
</span>
|
||||
<span class="aksrt-doc-chapter-nav__title"><?php echo esc_html($next_page->post_title); ?></span>
|
||||
</a>
|
||||
<?php else : ?>
|
||||
<div class="aksrt-doc-chapter-nav__next aksrt-doc-chapter-nav__next--disabled"></div>
|
||||
<?php endif; ?>
|
||||
</nav>
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* Document Index Card
|
||||
*
|
||||
* Shows a card for a document page on the document navigation index.
|
||||
* Used in the document navigation page to list available documents.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$page_id = get_the_ID();
|
||||
$children = get_pages([
|
||||
'parent' => $page_id,
|
||||
'sort_column' => 'menu_order',
|
||||
'sort_order' => 'ASC',
|
||||
'post_status' => 'publish',
|
||||
]);
|
||||
$child_count = count($children);
|
||||
$thumb = get_the_post_thumbnail_url($page_id, 'medium');
|
||||
$excerpt = wp_trim_words(get_the_excerpt(), 30, '...');
|
||||
?>
|
||||
<a href="<?php the_permalink(); ?>" class="aksrt-doc-index-card">
|
||||
<?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 the_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('', $page_id)); ?>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<i class="fas fa-chevron-right aksrt-doc-index-card__arrow"></i>
|
||||
</a>
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/**
|
||||
* Docs Mode: Sidebar Navigation
|
||||
*
|
||||
* 文档模式侧边栏:显示文档目录树,当前章节高亮。
|
||||
* Uses AKSRT_Docs_Presenter for tree construction.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$current_id = get_the_ID();
|
||||
$parent_id = wp_get_post_parent_id($current_id);
|
||||
$root_id = $parent_id ?: $current_id;
|
||||
|
||||
$presenter = class_exists('AKSRT_Docs_Presenter') ? AKSRT_Docs_Presenter::get_instance() : null;
|
||||
|
||||
if ($presenter) {
|
||||
$doc_pages = $presenter->get_flat_tree($root_id, 3);
|
||||
} else {
|
||||
$doc_pages = get_pages([
|
||||
'child_of' => $root_id,
|
||||
'sort_column' => 'menu_order, post_title',
|
||||
'sort_order' => 'ASC',
|
||||
'parent' => $root_id,
|
||||
]);
|
||||
}
|
||||
|
||||
$root_page = get_post($root_id);
|
||||
|
||||
// Quick search for docs
|
||||
$doc_settings = class_exists('AKSRT_Settings') ? AKSRT_Settings::get_docs_mode_settings() : [];
|
||||
$show_search = !empty($doc_settings['toc_enabled']);
|
||||
?>
|
||||
<aside class="aksrt-doc-sidebar" role="navigation" aria-label="<?php esc_attr_e('文档导航', 'aksrt'); ?>">
|
||||
<div class="aksrt-doc-sidebar__header">
|
||||
<a href="<?php echo esc_url(get_permalink($root_id)); ?>" class="aksrt-doc-sidebar__root">
|
||||
<i class="fas fa-book aksrt-doc-sidebar__root-icon"></i>
|
||||
<span><?php echo esc_html($root_page->post_title ?? __('文档', 'aksrt')); ?></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<?php if ($show_search) : ?>
|
||||
<div class="aksrt-doc-sidebar__search">
|
||||
<input type="text" class="aksrt-doc-sidebar__search-input" placeholder="<?php esc_attr_e('搜索文档...', 'aksrt'); ?>" aria-label="<?php esc_attr_e('搜索文档', 'aksrt'); ?>">
|
||||
<i class="fas fa-search aksrt-doc-sidebar__search-icon"></i>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($doc_pages)) : ?>
|
||||
<ul class="aksrt-doc-sidebar__nav">
|
||||
<?php foreach ($doc_pages as $dp) :
|
||||
$depth = isset($dp->_depth) ? (int) $dp->_depth : 0;
|
||||
$is_current = ((int) $dp->ID === $current_id);
|
||||
$is_ancestor = ((int) $dp->ID === $parent_id);
|
||||
$li_class = 'aksrt-doc-sidebar__item';
|
||||
if ($is_current) $li_class .= ' is-current';
|
||||
if ($is_ancestor) $li_class .= ' is-ancestor';
|
||||
if ($depth > 0) $li_class .= ' aksrt-doc-sidebar__item--depth-' . $depth;
|
||||
|
||||
$has_children = false;
|
||||
if ($presenter) {
|
||||
$sub = get_pages(['parent' => $dp->ID, 'post_status' => 'publish', 'fields' => 'ids']);
|
||||
$has_children = !empty($sub);
|
||||
} else {
|
||||
$sub_pages = get_pages(['child_of' => $dp->ID, 'sort_column' => 'menu_order', 'sort_order' => 'ASC', 'parent' => $dp->ID]);
|
||||
$has_children = !empty($sub_pages);
|
||||
}
|
||||
$is_open = $is_current || $is_ancestor;
|
||||
?>
|
||||
<li class="<?php echo esc_attr($li_class); ?>" style="<?php echo $depth > 0 ? 'padding-left:' . ($depth * 16) . 'px;' : ''; ?>">
|
||||
<a href="<?php echo esc_url(get_permalink($dp->ID)); ?>" class="aksrt-doc-sidebar__link<?php echo $is_current ? ' is-active' : ''; ?>">
|
||||
<?php if ($has_children) : ?>
|
||||
<i class="fas fa-chevron-<?php echo $is_open ? 'down' : 'right'; ?> aksrt-doc-sidebar__toggle" aria-hidden="true"></i>
|
||||
<?php endif; ?>
|
||||
<span><?php echo esc_html($dp->post_title); ?></span>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</aside>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* Docs Mode: Table of Contents
|
||||
*
|
||||
* 文档模式目录:从文章内容中提取 h2/h3 生成右侧目录。
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
$content = get_the_content();
|
||||
if (empty($content)) return;
|
||||
|
||||
// 提取 h2/h3 标题
|
||||
$headings = [];
|
||||
if (preg_match_all('/<h([2-3])[^>]*(?:id="([^"]*)")?[^>]*>(.*?)<\/h\1>/is', $content, $matches, PREG_SET_ORDER)) {
|
||||
foreach ($matches as $m) {
|
||||
$level = (int) $m[1];
|
||||
$id = !empty($m[2]) ? $m[2] : '';
|
||||
$text = wp_strip_all_tags($m[3]);
|
||||
if ($text === '') continue;
|
||||
if ($id === '') {
|
||||
$id = 'toc-' . sanitize_title($text);
|
||||
}
|
||||
$headings[] = ['level' => $level, 'id' => $id, 'text' => $text];
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($headings)) return;
|
||||
?>
|
||||
<nav class="aksrt-doc-toc" aria-label="<?php esc_attr_e('文章目录', 'aksrt'); ?>">
|
||||
<div class="aksrt-doc-toc__title"><?php esc_html_e('目录', 'aksrt'); ?></div>
|
||||
<ul class="aksrt-doc-toc__list">
|
||||
<?php foreach ($headings as $h) : ?>
|
||||
<li class="aksrt-doc-toc__item aksrt-doc-toc__item--h<?php echo esc_attr((string) $h['level']); ?>">
|
||||
<a href="#<?php echo esc_attr($h['id']); ?>"><?php echo esc_html($h['text']); ?></a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</nav>
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* Docs Mode: Document Tree
|
||||
*
|
||||
* 文档模式树形导航:递归展示文档层级结构。
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
if (!function_exists('aksrt_render_doc_tree')) {
|
||||
function aksrt_render_doc_tree($parent_id, $current_id, $depth = 0) {
|
||||
$children = get_pages([
|
||||
'parent' => $parent_id,
|
||||
'sort_column' => 'menu_order, post_title',
|
||||
'sort_order' => 'ASC',
|
||||
]);
|
||||
if (empty($children)) return;
|
||||
|
||||
$indent = str_repeat(' ', $depth);
|
||||
echo $indent . '<ul class="aksrt-doc-tree__level aksrt-doc-tree__level--' . esc_attr((string) ($depth + 1)) . '">';
|
||||
foreach ($children as $child) {
|
||||
$is_current = ($child->ID === $current_id);
|
||||
$has_children = (int) get_pages(['child_of' => $child->ID, 'parent' => $child->ID, 'hide_empty' => true, 'fields' => 'ids']) > 0;
|
||||
echo $indent . ' <li class="aksrt-doc-tree__item' . ($is_current ? ' is-current' : '') . '">';
|
||||
echo '<a href="' . esc_url(get_permalink($child->ID)) . '">' . esc_html($child->post_title) . '</a>';
|
||||
if ($has_children && $depth < 3) {
|
||||
aksrt_render_doc_tree($child->ID, $current_id, $depth + 1);
|
||||
}
|
||||
echo '</li>';
|
||||
}
|
||||
echo $indent . '</ul>';
|
||||
}
|
||||
}
|
||||
|
||||
$current_id = get_the_ID();
|
||||
$root_id = wp_get_post_parent_id($current_id) ?: $current_id;
|
||||
?>
|
||||
|
||||
<nav class="aksrt-doc-tree" aria-label="<?php esc_attr_e('文档树', 'aksrt'); ?>">
|
||||
<div class="aksrt-doc-tree__root">
|
||||
<a href="<?php echo esc_url(get_permalink($root_id)); ?>"><?php echo esc_html(get_the_title($root_id)); ?></a>
|
||||
</div>
|
||||
<?php aksrt_render_doc_tree($root_id, $current_id); ?>
|
||||
</nav>
|
||||
Reference in New Issue
Block a user