diff --git a/Plugin.php b/Plugin.php new file mode 100644 index 0000000..81cd99d --- /dev/null +++ b/Plugin.php @@ -0,0 +1,429 @@ +footer = array('SimpleBreadcrumb_Plugin', 'footer'); + return _t('面包屑导航插件已激活,请在文章页面使用 SimpleBreadcrumb_Plugin::show() 调用'); + } + + /** + * 禁用插件 + */ + public static function deactivate() + { + return _t('面包屑导航插件已禁用'); + } + + /** + * 插件配置面板(简化版) + */ + public static function config(Typecho_Widget_Helper_Form $form) + { + // 是否显示面包屑 + $showBreadcrumb = new Typecho_Widget_Helper_Form_Element_Radio( + 'showBreadcrumb', + array( + '1' => _t('显示'), + '0' => _t('不显示') + ), + '1', + _t('是否显示面包屑导航') + ); + $form->addInput($showBreadcrumb); + + // 首页文字 + $homeText = new Typecho_Widget_Helper_Form_Element_Text( + 'homeText', + NULL, + '首页', + _t('首页显示文字') + ); + $form->addInput($homeText); + + // 分隔符 + $separator = new Typecho_Widget_Helper_Form_Element_Select( + 'separator', + array( + '»' => '»', + '>' => '>', + '/' => '/', + '→' => '→' + ), + '»', + _t('分隔符样式') + ); + $form->addInput($separator); + + // 是否显示当前页面 + $showCurrent = new Typecho_Widget_Helper_Form_Element_Radio( + 'showCurrent', + array( + '1' => _t('显示'), + '0' => _t('不显示') + ), + '1', + _t('是否显示当前页面') + ); + $form->addInput($showCurrent); + + // 是否显示分类 + $showCategory = new Typecho_Widget_Helper_Form_Element_Radio( + 'showCategory', + array( + '1' => _t('显示'), + '0' => _t('不显示') + ), + '1', + _t('文章页面是否显示分类') + ); + $form->addInput($showCategory); + } + + /** + * 个人配置面板 + */ + public static function personalConfig(Typecho_Widget_Helper_Form $form) {} + + /** + * 输出面包屑导航(前端调用方法) + */ + public static function show($widget = null) + { + $options = Helper::options(); + $config = $options->plugin('SimpleBreadcrumb'); + + // 检查是否显示 + if (!$config->showBreadcrumb) { + return; + } + + // 如果没有传递widget,使用全局 + if ($widget === null) { + $widget = Typecho_Widget::widget('Widget_Archive'); + } + + // 检查是否在首页且需要显示 + if ($widget->is('index')) { + return; + } + + // 获取面包屑HTML + $breadcrumb = self::generateBreadcrumb($widget, $config); + + if (!empty($breadcrumb)) { + // 输出CSS和面包屑HTML + $html = ''; + $html .= '
'; + + echo $html; + } + } + + /** + * 生成面包屑HTML + */ + private static function generateBreadcrumb($widget, $config) + { + $breadcrumbs = array(); + $options = Helper::options(); + + // 添加首页 + $homeText = isset($config->homeText) ? $config->homeText : '首页'; + $breadcrumbs[] = '' . + htmlspecialchars($homeText) . ''; + + $separator = isset($config->separator) ? $config->separator : '»'; + $showCurrent = isset($config->showCurrent) ? $config->showCurrent : '1'; + $showCategory = isset($config->showCategory) ? $config->showCategory : '1'; + + // 分类页面 + if ($widget->is('category')) { + $category = $widget->getArchiveTitle(); + if ($showCurrent) { + $breadcrumbs[] = ''; + } + } + + // 文章页面 + elseif ($widget->is('post')) { + // 添加分类 + if ($showCategory) { + $categories = $widget->categories; + if ($categories && count($categories) > 0) { + $category = current($categories); + $breadcrumbs[] = '' . + htmlspecialchars($category['name']) . ''; + } + } + + // 添加当前文章 + if ($showCurrent) { + $breadcrumbs[] = ''; + } + } + + // 独立页面 + elseif ($widget->is('page')) { + // 处理父页面(如果有) + if ($widget->parent > 0) { + $parent = $widget->widget('Widget_Archive', "type=page&pageId={$widget->parent}"); + if ($parent->have()) { + $breadcrumbs[] = '' . + htmlspecialchars($parent->title) . ''; + } + } + + if ($showCurrent) { + $breadcrumbs[] = ''; + } + } + + // 标签页面 + elseif ($widget->is('tag')) { + if ($showCurrent) { + $tag = $widget->getArchiveTitle(); + $breadcrumbs[] = ''; + } + } + + // 作者页面 + elseif ($widget->is('author')) { + if ($showCurrent) { + $author = $widget->getArchiveTitle(); + $breadcrumbs[] = ''; + } + } + + // 日期归档 + elseif ($widget->is('archive') && !$widget->is('category') && !$widget->is('tag') && !$widget->is('author')) { + if ($showCurrent) { + $archive = $widget->getArchiveTitle(); + $breadcrumbs[] = ''; + } + } + + // 搜索页面 + elseif ($widget->is('search')) { + if ($showCurrent) { + $keywords = $widget->keywords; + $breadcrumbs[] = ''; + } + } + + // 如果没有面包屑内容(只有首页),根据设置决定是否显示 + if (count($breadcrumbs) <= 1) { + return ''; // 只显示首页时不输出 + } + + // 组合HTML + $html = ''; + + return $html; + } + + /** + * 输出CSS样式到footer(保持空,避免重复加载) + */ + public static function footer() + { + // CSS已经在show()方法中内联输出 + } + + /** + * 获取CSS样式 - 简化版,专门适配.dark夜间模式 + */ + private static function getStyles() + { + return ' + /* Simple Breadcrumb Navigation CSS - v3.0.0 */ + + /* 基础样式 */ + .simple-breadcrumb { + margin: 20px 0; + padding: 15px 0; + font-size: 14px; + line-height: 1.5; + clear: both; + text-align: center; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + } + + /* 导航结构 */ + .breadcrumb-nav { + display: inline-block; + max-width: 100%; + } + + .breadcrumb-list { + list-style: none; + padding: 0; + margin: 0; + display: inline-flex; + flex-wrap: wrap; + align-items: center; + justify-content: center; + } + + .breadcrumb-item { + display: inline-flex; + align-items: center; + margin: 5px 0; + } + + .breadcrumb-item a { + text-decoration: none; + padding: 4px 8px; + border-radius: 4px; + transition: all 0.2s ease; + font-weight: 500; + color: #1e87f0; + background-color: rgba(30, 135, 240, 0.1); + } + + .breadcrumb-item a:hover { + color: #0d6efd; + background-color: rgba(30, 135, 240, 0.2); + transform: translateY(-1px); + } + + .breadcrumb-item span.breadcrumb-current { + font-weight: 600; + padding: 4px 8px; + border-radius: 4px; + color: #333; + background-color: rgba(0, 0, 0, 0.05); + } + + .breadcrumb-separator { + margin: 0 10px; + opacity: 0.6; + font-weight: 300; + color: #666; + } + + /* ========== .dark 夜间模式适配 ========== */ + .dark .simple-breadcrumb { + background-color: #1a1d21; + border-radius: 8px; + padding: 15px 20px; + border: 1px solid #343a40; + } + + .dark .breadcrumb-item a { + color: #4dabf7; + background-color: rgba(77, 171, 247, 0.1); + } + + .dark .breadcrumb-item a:hover { + color: #339af0; + background-color: rgba(77, 171, 247, 0.2); + } + + .dark .breadcrumb-item span.breadcrumb-current { + color: #e9ecef; + background-color: rgba(255, 255, 255, 0.05); + } + + .dark .breadcrumb-separator { + color: #adb5bd; + } + + /* ========== 响应式设计 ========== */ + @media (max-width: 768px) { + .simple-breadcrumb { + margin: 15px 0; + padding: 12px 15px; + font-size: 13px; + text-align: left; + } + + .breadcrumb-list { + justify-content: flex-start; + overflow-x: auto; + white-space: nowrap; + -webkit-overflow-scrolling: touch; + padding-bottom: 5px; + } + + .breadcrumb-item { + flex-shrink: 0; + } + + .breadcrumb-separator { + margin: 0 8px; + } + + .dark .simple-breadcrumb { + padding: 12px 15px; + } + } + + @media (max-width: 480px) { + .simple-breadcrumb { + margin: 10px 0; + padding: 10px 12px; + font-size: 12px; + } + + .breadcrumb-item a, + .breadcrumb-item span.breadcrumb-current { + padding: 3px 6px; + } + + .breadcrumb-separator { + margin: 0 6px; + } + + .dark .simple-breadcrumb { + padding: 10px 12px; + border-radius: 6px; + } + } + + /* ========== 打印样式 ========== */ + @media print { + .simple-breadcrumb { + display: none; + } + } + + /* ========== 无障碍支持 ========== */ + .breadcrumb-item a:focus { + outline: 2px solid #1e87f0; + outline-offset: 2px; + } + + .dark .breadcrumb-item a:focus { + outline-color: #4dabf7; + } + '; + } +} +?> \ No newline at end of file