refactor: 完成Handlebars模板组件化

This commit is contained in:
Zuoling Rong
2025-05-08 01:32:14 +08:00
parent 6474fa3635
commit 9ea6cb1f09
24 changed files with 1440 additions and 598 deletions

View File

@@ -1,6 +1,6 @@
{{#each this}}
<div class="nav-item-wrapper">
<a href="#" class="nav-item{{#if active}} active{{/if}}" data-page="{{id}}">
<a href="#" class="nav-item{{#if isActive}} active{{/if}}{{#if active}} active{{/if}}" data-page="{{id}}">
<div class="icon-container">
<i class="{{icon}}"></i>
</div>

View File

@@ -0,0 +1,11 @@
<!-- 搜索结果组件 -->
<div class="welcome-section">
<h2>搜索结果</h2>
<p class="subtitle">在所有页面中找到的匹配项</p>
</div>
{{#each navigation}}
<section class="category search-section" data-section="{{id}}" style="display: none;">
<h2><i class="{{icon}}"></i> {{name}}匹配项</h2>
<div class="sites-grid"></div>
</section>
{{/each}}

View File

@@ -1,5 +1,5 @@
{{#if url}}
<a href="{{url}}" class="site-card" title="{{name}} - {{description}}">
<a href="{{url}}" class="site-card{{#if style}} site-card-{{style}}{{/if}}" title="{{name}} - {{description}}" {{#if external}}target="_blank" rel="noopener"{{/if}}>
<i class="{{#if icon}}{{icon}}{{else}}fas fa-link{{/if}}"></i>
<h3>{{#if name}}{{name}}{{else}}未命名站点{{/if}}</h3>
<p>{{description}}</p>

View File

@@ -0,0 +1,11 @@
{{#if this}}
{{#each this}}
<a href="{{url}}" class="nav-item" target="_blank" rel="noopener">
<div class="icon-container">
<i class="{{icon}}"></i>
</div>
<span class="nav-text">{{name}}</span>
<i class="fas fa-external-link-alt external-icon"></i>
</a>
{{/each}}
{{/if}}

View File

@@ -1,103 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{SITE_TITLE}}</title>
<link rel="icon" href="./favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon">
{{GOOGLE_FONTS}}
<style>
{{{FONT_VARIABLES}}}
</style>
<!-- 预设主题和侧边栏状态,避免闪烁 -->
<script>
(function() {
// 读取并应用主题设置
var savedTheme = localStorage.getItem('theme');
if (savedTheme === 'light') {
document.documentElement.classList.add('theme-preload');
}
// 读取并应用侧边栏状态
var sidebarCollapsed = localStorage.getItem('sidebarCollapsed') === 'true';
var isMobile = window.innerWidth <= 768;
if (sidebarCollapsed && !isMobile) {
document.documentElement.classList.add('sidebar-collapsed-preload');
}
// 添加这个类用于控制初始渲染
document.documentElement.classList.add('preload');
})();
</script>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
</head>
<body class="loading">
<!-- 滚动进度指示条 -->
<div class="scroll-progress"></div>
<div class="layout">
<!-- 移动端按钮 -->
<div class="mobile-buttons">
<button class="menu-toggle" aria-label="切换菜单">
<i class="fas fa-bars"></i>
</button>
<button class="search-toggle" aria-label="切换搜索">
<i class="fas fa-search"></i>
</button>
</div>
<!-- 遮罩层 -->
<div class="overlay"></div>
<!-- 左侧导航 -->
<nav class="sidebar">
<div class="logo">
<h1>{{SITE_LOGO_TEXT}}</h1>
<button class="sidebar-toggle" aria-label="收起/展开侧边栏">
<i class="fas fa-chevron-left toggle-icon"></i>
</button>
</div>
<div class="sidebar-content">
<div class="nav-section">
{{NAVIGATION}}
</div>
<div class="nav-section">
<div class="section-title">
<i class="fas fa-link"></i>
</div>
{{SOCIAL_LINKS}}
</div>
</div>
<div class="copyright">
<p>© {{CURRENT_YEAR}} <a href="https://github.com/rbetree/menav" target="_blank" rel="noopener">MeNav</a></p>
<p>by <a href="https://github.com/rbetree" target="_blank" rel="noopener">rbetree</a></p>
</div>
</nav>
<!-- 右侧内容区 -->
<main class="content">
<!-- 搜索框容器 -->
<div class="search-container">
<div class="search-box">
<input type="text" id="search" placeholder="搜索...">
<i class="fas fa-search"></i>
</div>
</div>
{{ALL_PAGES}}
{{SEARCH_RESULTS}}
</main>
<!-- 主题切换按钮 -->
<button class="theme-toggle" aria-label="切换主题">
<i class="fas fa-moon"></i>
</button>
</div>
<script src="script.js"></script>
</body>
</html>

View File

@@ -72,7 +72,11 @@
<div class="section-title">
<i class="fas fa-link"></i>
</div>
{{#if social}}
{{> social-links social}}
{{else}}
{{{socialLinks}}}
{{/if}}
</div>
</div>
@@ -92,21 +96,12 @@
</div>
</div>
{{{body}}}
<!-- 搜索结果页 -->
<div class="page" id="search-results">
<div class="welcome-section">
<h2>搜索结果</h2>
<p class="subtitle">在所有页面中找到的匹配项</p>
</div>
{{#each navigation}}
<section class="category search-section" data-section="{{id}}" style="display: none;">
<h2><i class="{{icon}}"></i> {{name}}匹配项</h2>
<div class="sites-grid"></div>
</section>
{{/each}}
<!-- 页面容器 -->
{{#each pages}}
<div class="page {{@key}}{{#if @first}} active{{/if}}" id="{{@key}}">
{{{this}}}
</div>
{{/each}}
</main>
<!-- 主题切换按钮 -->

View File

@@ -0,0 +1,7 @@
<div class="welcome-section">
<h2>{{title}}</h2>
<p class="subtitle">{{subtitle}}</p>
</div>
{{#each categories}}
{{> category}}
{{/each}}

View File

@@ -0,0 +1,7 @@
<div class="welcome-section">
<h2>{{title}}</h2>
<p class="subtitle">{{subtitle}}</p>
</div>
{{#each categories}}
{{> category}}
{{/each}}

View File

@@ -0,0 +1,7 @@
<div class="welcome-section">
<h2>{{title}}</h2>
<p class="subtitle">{{subtitle}}</p>
</div>
{{#each categories}}
{{> category}}
{{/each}}

View File

@@ -1,10 +1,8 @@
<div class="page active" id="home">
<div class="welcome-section">
<h2>{{profile.title}}</h2>
<h3>{{profile.subtitle}}</h3>
<p class="subtitle">{{profile.description}}</p>
</div>
{{#each categories}}
{{> category}}
{{/each}}
</div>
<div class="welcome-section">
<h2>{{profile.title}}</h2>
<h3>{{profile.subtitle}}</h3>
<p class="subtitle">{{profile.description}}</p>
</div>
{{#each categories}}
{{> category}}
{{/each}}

142
templates/pages/index.hbs Normal file
View File

@@ -0,0 +1,142 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{site.title}}</title>
<link rel="icon" href="./{{site.favicon}}" type="image/x-icon">
<link rel="shortcut icon" href="./{{site.favicon}}" type="image/x-icon">
<link href="{{{googleFontsLink}}}" rel="stylesheet">
<style>
{{{fontVariables}}}
</style>
<!-- 预设主题和侧边栏状态,避免闪烁 -->
<script>
(function() {
// 读取并应用主题设置
var savedTheme = localStorage.getItem('theme');
if (savedTheme === 'light') {
document.documentElement.classList.add('theme-preload');
}
// 读取并应用侧边栏状态
var sidebarCollapsed = localStorage.getItem('sidebarCollapsed') === 'true';
var isMobile = window.innerWidth <= 768;
if (sidebarCollapsed && !isMobile) {
document.documentElement.classList.add('sidebar-collapsed-preload');
}
// 添加这个类用于控制初始渲染
document.documentElement.classList.add('preload');
})();
</script>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
</head>
<body class="loading">
<!-- 滚动进度指示条 -->
<div class="scroll-progress"></div>
<div class="layout">
<!-- 移动端按钮 -->
<div class="mobile-buttons">
<button class="menu-toggle" aria-label="切换菜单">
<i class="fas fa-bars"></i>
</button>
<button class="search-toggle" aria-label="切换搜索">
<i class="fas fa-search"></i>
</button>
</div>
<!-- 遮罩层 -->
<div class="overlay"></div>
<!-- 左侧导航 -->
<nav class="sidebar">
<div class="logo">
<h1>{{site.logo_text}}</h1>
<button class="sidebar-toggle" aria-label="收起/展开侧边栏">
<i class="fas fa-chevron-left toggle-icon"></i>
</button>
</div>
<div class="sidebar-content">
<div class="nav-section">
{{#each navigationData}}
{{> navigation}}
{{/each}}
</div>
<div class="social-links">
{{> social-links}}
</div>
</div>
</nav>
<!-- 右侧内容区 -->
<main class="content">
<!-- 顶部操作栏 -->
<div class="main-header">
<div class="left-actions">
<button class="theme-toggle" aria-label="切换主题">
<i class="fas fa-moon"></i>
</button>
</div>
<div class="search-container">
<div class="search-input-container">
<i class="fas fa-search"></i>
<input type="text" class="search-input" placeholder="搜索..." aria-label="搜索">
<button class="search-clear" aria-label="清除搜索">
<i class="fas fa-times"></i>
</button>
</div>
</div>
<div class="right-actions">
<button class="fullscreen-toggle" aria-label="切换全屏模式">
<i class="fas fa-expand"></i>
</button>
</div>
</div>
<!-- 主要内容 -->
<div class="main-content">
<!-- home页 -->
<div class="page active" id="home">
{{{pages.home}}}
</div>
<!-- 项目页 -->
<div class="page" id="projects">
{{{pages.projects}}}
</div>
<!-- 文章页 -->
<div class="page" id="articles">
{{{pages.articles}}}
</div>
<!-- 朋友页 -->
<div class="page" id="friends">
{{{pages.friends}}}
</div>
<!-- 书签页 -->
<div class="page" id="bookmarks">
{{{pages.bookmarks}}}
</div>
<!-- 搜索结果页 -->
<div class="page" id="search-results">
{{{pages.search-results}}}
</div>
</div>
<!-- 页脚 -->
<footer class="main-footer">
<p>© {{currentYear}} {{site.title}} | {{site.footer}}</p>
</footer>
</main>
</div>
<script src="script.js"></script>
</body>
</html>

9
templates/pages/page.hbs Normal file
View File

@@ -0,0 +1,9 @@
<div class="page" id="{{pageId}}">
<div class="welcome-section">
<h2>{{title}}</h2>
<p class="subtitle">{{subtitle}}</p>
</div>
{{#each categories}}
{{> category}}
{{/each}}
</div>

View File

@@ -0,0 +1,7 @@
<div class="welcome-section">
<h2>{{title}}</h2>
<p class="subtitle">{{subtitle}}</p>
</div>
{{#each categories}}
{{> category}}
{{/each}}

View File

@@ -0,0 +1,11 @@
<!-- 搜索结果页 -->
<div class="welcome-section">
<h2>搜索结果</h2>
<p class="subtitle">在所有页面中找到的匹配项</p>
</div>
{{#each navigation}}
<section class="category search-section" data-section="{{id}}" style="display: none;">
<h2><i class="{{icon}}"></i> {{name}}匹配项</h2>
<div class="sites-grid"></div>
</section>
{{/each}}