导入 AKSRT 主题开发源码

This commit is contained in:
Claude Code
2026-07-03 22:50:34 +08:00
parent 9681dd3d48
commit 1268a55dd0
595 changed files with 127705 additions and 0 deletions
+70
View File
@@ -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>
+55
View File
@@ -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>
+83
View File
@@ -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>
+41
View File
@@ -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>
+46
View File
@@ -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>