diff options
Diffstat (limited to 'layouts/partials')
| -rw-r--r-- | layouts/partials/archives-list.html | 30 | ||||
| -rw-r--r-- | layouts/partials/custom_body.html | 5 | ||||
| -rw-r--r-- | layouts/partials/custom_head.html | 11 | ||||
| -rw-r--r-- | layouts/partials/favicon.html | 2 | ||||
| -rw-r--r-- | layouts/partials/footer.html | 1 | ||||
| -rw-r--r-- | layouts/partials/header.html | 4 | ||||
| -rw-r--r-- | layouts/partials/nav.html | 7 | ||||
| -rw-r--r-- | layouts/partials/seo_tags.html | 15 | ||||
| -rw-r--r-- | layouts/partials/style.html | 531 | ||||
| -rw-r--r-- | layouts/partials/toc.html | 91 |
10 files changed, 697 insertions, 0 deletions
diff --git a/layouts/partials/archives-list.html b/layouts/partials/archives-list.html new file mode 100644 index 0000000..b9767f7 --- /dev/null +++ b/layouts/partials/archives-list.html @@ -0,0 +1,30 @@ +{{ $allPages := where .Site.RegularPages "Type" "in" (slice "posts" "blog") }} +{{ $visiblePages := where $allPages "Params.hidden" "!=" true }} +{{ $pagesToShow := $visiblePages.ByDate.Reverse }} + +<div class="archives-content"> + <h2>归档</h2> + + <p>共有 {{ len $pagesToShow }} 篇文章</p> + + <ul class="blog-posts"> + {{ $currentYear := 0 }} + {{ range $pagesToShow }} + {{ $year := .Date.Year }} + {{ if ne $year $currentYear }} + <h3>{{ $year }}</h3> + {{ $currentYear = $year }} + {{ end }} + <li> + <span> + <i> + <time datetime='{{ .Date.Format "2006-01-02" }}'> + {{ .Date.Format "2006-01-02" }} + </time> + </i> + </span> + <a href="{{ .Permalink }}">{{ .Title }}</a> + </li> + {{ end }} + </ul> +</div> diff --git a/layouts/partials/custom_body.html b/layouts/partials/custom_body.html new file mode 100644 index 0000000..529771a --- /dev/null +++ b/layouts/partials/custom_body.html @@ -0,0 +1,5 @@ + <!-- A partial to be overwritten by the user. + Simply place a custom_body.html into + your local /layouts/partials-directory --> + + diff --git a/layouts/partials/custom_head.html b/layouts/partials/custom_head.html new file mode 100644 index 0000000..4ea89a1 --- /dev/null +++ b/layouts/partials/custom_head.html @@ -0,0 +1,11 @@ +<meta name="msvalidate.01" content="2E1AACF009206F2DDBAAD4B98E881460" /> +<link + rel="prefetch" + as="image" + href="https://www.blogsclub.org/badge/www.glowisle.me" +/> +<link href="https://github.com/yingyu5658" rel="me" /> +<link + rel="webmention" + href="https://webmention.io/www.glowisle.me/webmention" +/> diff --git a/layouts/partials/favicon.html b/layouts/partials/favicon.html new file mode 100644 index 0000000..ccf1a5d --- /dev/null +++ b/layouts/partials/favicon.html @@ -0,0 +1,2 @@ +{{ with .Site.Params.favicon }} +<link rel="shortcut icon" href="{{ . | absURL }}" />{{ end }} diff --git a/layouts/partials/footer.html b/layouts/partials/footer.html new file mode 100644 index 0000000..cc5e269 --- /dev/null +++ b/layouts/partials/footer.html @@ -0,0 +1 @@ +<p>© 2024 - 2025 | Made with ❤️ by Verdant.</p> diff --git a/layouts/partials/header.html b/layouts/partials/header.html new file mode 100644 index 0000000..66fa74b --- /dev/null +++ b/layouts/partials/header.html @@ -0,0 +1,4 @@ +<a href="{{ "" | relURL }}" class="title"> + <h1 class="site-name">{{ .Site.Title }}</h1> +</a> +<nav>{{- partial "nav.html" . -}}</nav> diff --git a/layouts/partials/nav.html b/layouts/partials/nav.html new file mode 100644 index 0000000..5b9d089 --- /dev/null +++ b/layouts/partials/nav.html @@ -0,0 +1,7 @@ +<a href="{{ "" | relURL }}">首页</a> +{{ range .Site.Menus.main }} +<a href="{{ .URL }}">{{ .Name }}</a> +{{ end }} +{{ with .Site.GetPage "/blog" }} +<a href="{{ "posts/" | relURL }}">Blog</a> +{{ end }} diff --git a/layouts/partials/seo_tags.html b/layouts/partials/seo_tags.html new file mode 100644 index 0000000..06e90cd --- /dev/null +++ b/layouts/partials/seo_tags.html @@ -0,0 +1,15 @@ +<!-- Primary Meta Tags --> +<meta name="title" content="{{ with .Title }}{{ . }}{{ else }}{{ .Site.Title }}{{ end }}" /> +<meta name="description" content="{{ with .Description }}{{ . }}{{ else }}{{ if .IsPage }}{{ .Summary }}{{ else }}{{ with .Site.Params.Description }}{{ . }}{{ end }}{{ end }}{{ end }}" /> +<meta name="keywords" content="{{ if .IsPage }}{{ range $index, $tag := .Params.tags }}{{ $tag }},{{ end }}{{ else }}{{ range $plural, $terms := .Site.Taxonomies }}{{ range $term, $val := $terms }}{{ printf "%s," $term }}{{ end }}{{ end }}{{ end }}" /> + +<link rel="canonical" href="{{ .Permalink }}"> + +<!-- Open Graph / Facebook --> +{{ template "_internal/opengraph.html" . }} + +<!-- Twitter --> +{{ template "_internal/twitter_cards.html" . }} + +<!-- Microdata --> +{{ template "_internal/schema.html" . }} diff --git a/layouts/partials/style.html b/layouts/partials/style.html new file mode 100644 index 0000000..f108da6 --- /dev/null +++ b/layouts/partials/style.html @@ -0,0 +1,531 @@ +<style> + /* light theme */ + :root { + --width-max: 720px; + --font-primary: "Noto Serif SC", "Source Han Serif SC", serif; + --font-secondary: monospace; + --font-size-primary: 1em; + --font-size-secondary: 0.8em; + --body-bg-color: #ffffff; + --bold-text-color: #222; + --body-text-color: #444; + --link-color: #222; + --link-visited-color: #222; + --table-border-color: #f2f2f2; + --table-th-bg-color: #f2f2f2; + --img-border-color: #f2f2f2; + --code-bg-color: #f2f2f2; + --code-text-color: #222; + --blockquote-border-color: #666; + --blockquote-text-color: #666; + --upvoted-color: #fa8072; + --caption-text-color: #666; + --toc-text-color: #e5e5e5; + --toc-hover-color: #655e5e; + } + + .wm { + border: 1px #d0d7de solid; + border-radius: 0.25em; + padding-top: 0; + padding: 1.5vw; + background-color: #f6f8fa; + margin-top: 1vh; + } + + .wm p { + margin-top: 1px; + } + + .item-link { + white-space: nowrap; + overflow: hidden; + } + + .post-info { + text-align: center; + margin-bottom: 3vh; + } + .category-link { + color: #999; + } + + h1.post-title { + margin-top: 5vh; + margin-bottom: 10px; + text-align: center; + } + + h1.post-title a { + font-size: 30px; + font-weight: 700; + } + + .recent-list { + padding-left: 2vw; + } + + .recent-item { + list-style-type: none; + } + + .post-date { + display: inline; + } + + .post-date, + .post-date-shortcode { + margin-left: auto; + color: #999; + } + + article .post-date::after { + content: "/"; + } + + .site-name:hover { + background-color: transparent; + text-decoration: none; + color: #fff; + background-color: #7e4fa0; + } + + .site-name { + transition: 0.3s; + width: 66px; + border-radius: 5px; + text-transform: uppercase; + } + + @media (prefers-color-scheme: dark) { + :root { + --body-bg-color: #121212; + --bold-text-color: #eee; + --body-text-color: #ddd; + --link-color: #ddd; + --link-visited-color: #c3b1ee; + --table-border-color: #999; + --table-th-bg-color: #999; + --img-border-color: #999; + --code-bg-color: #141414; + --code-text-color: #ddd; + --blockquote-border-color: #ccc; + --blockquote-text-color: #ccc; + --caption-text-color: #aaa; + --toc-text-color: #373737; + --toc-hover-color: #cac3c3; + } + + .wm { + background-color: #161b22; + border-color: #30363d; + color: var(--body-text-color); + padding: 10px; + } + + .wm input { + background-color: #010409; + border: #30363d 1px solid; + color: var(--body-text-color); + outline: none; + transition: border-color 0.2s ease-in-out; + } + + #webmention-source:focus { + border-color: var(--color-accent-fg, #0969da); + box-shadow: 0 0 0 3px rgba(9, 105, 218, 0.1); + } + + .wm button { + color: var(--body-text-color); + background-color: #161b22; + border: #30363d 1px solid; + } + + .post-title a { + color: #fff !important; + } + + .post-summary { + color: var(--text-color-primary) !important; + } + + .post-item { + border-bottom: 1px solid #414141 !important; + } + + .pagination-link { + border: 1px solid #414141 !important; + } + + nav a, + h1.post-title a, + .category-link, + .blog-posts li a { + text-decoration: none !important; + } + + a { + font-weight: 700 !important; + } + + a:hover { + color: #ddd !important; + } + } + + body { + font-family: var(--font-primary); + font-size: var(--font-size-primary); + margin: auto; + padding: 20px; + max-width: var(--width-max); + text-align: left; + background-color: var(--body-bg-color); + word-wrap: break-word; + overflow-wrap: break-word; + line-height: 1.6; + color: var(--body-text-color); + } + + h1, + h2, + h3, + h4, + h5, + h6, + strong, + b { + color: var(--bold-text-color); + } + + h1, + h2, + h3, + h4, + h5, + h6 { + margin: 16px 0; + } + + a { + color: var(--link-color); + cursor: pointer; + text-decoration: underline 0.2px #d4d4d4; + transition-duration: 0.3s; + font-weight: 600; + } + + a:hover { + color: #3273dc; + } + + .posts-list li { + margin-bottom: 12px; + } + + .title { + text-decoration: none; + border: 0; + } + + .title:hover { + text-decoration: none; + } + + .title span { + font-weight: 400; + } + + nav { + margin-bottom: 15px; + } + + nav a { + margin-right: 8px; + } + + textarea { + width: 100%; + font-size: 16px; + } + + input { + font-size: 14px; + } + + article { + line-height: 1.6; + } + + table { + width: 100%; + border-collapse: collapse; + border: 1px solid var(--table-border-color); + border-radius: 4px; + margin-top: 16px; + } + + th, + td { + border: 1px solid var(--table-border-color); + padding: 4px; + } + + th { + background-color: var(--table-th-bg-color); + } + + hr { + border: 0; + border-top: 1px dashed; + } + + img { + max-width: 100%; + display: block; + margin-left: auto; + margin-right: auto; + border: 1px solid var(--img-border-color); + border-radius: 4px; + content-visibility: auto; + loading: lazy; + } + + img[src*="#minipic"] { + max-width: 50%; + margin-left: 0; + margin-right: auto; + } + + .image-caption figcaption { + text-align: center; + font-style: italic; + font-size: 0.8em; + margin-top: 0.6em; + color: var(--caption-text-color); + } + + .image-caption { + margin: auto; + } + + i { + font-style: normal; + } + + time { + font-family: var(--font-secondary); + font-size: 15px; + color: rgb(163, 163, 163); + } + + code { + font-family: var(--font-secondary); + background-color: var(--code-bg-color); + color: var(--code-text-color); + padding: 2px; + border-radius: 4px; + } + + pre code { + display: block; + padding: 16px; + white-space: pre-wrap; + overflow-x: auto; + } + + div.highlight pre { + border-radius: 4px; + } + + div.highlight code { + background-color: var(--code-bg-color); + color: var(--code-text-color); + } + + blockquote { + border-left: 2px solid var(--blockquote-border-color); + color: var(--blockquote-text-color); + margin: 0; + padding-left: 16px; + font-style: normal; + } + + blockquote p { + margin: 0; + } + + footer { + padding: 25px 0; + text-align: left; + font-size: var(--font-size-secondary); + } + + ul li:has(input) { + list-style-type: none; + margin-left: -25.5px; + } + + /* blog post list */ + ul.blog-posts { + list-style-type: none; + padding: unset; + } + + ul.blog-posts li { + display: flex; + margin-bottom: 8px; + } + + ul.blog-posts li span { + flex: 0 0 130px; + } + + ul.blog-posts li span.grouped { + flex: 0 0 80px; + } + + ul.blog-posts li a:visited { + color: var(--link-visited-color); + } + + ul.blog-posts a { + margin-left: 10px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + /* TOC 样式 */ + div.toc { + position: fixed; /* 固定定位 */ + top: 50%; /* 垂直居中 */ + left: calc( + (100vw + var(--width-max)) / 2 + ); /* 水平定位,根据视口宽度和最大内容宽度计算 */ + transform: translateY(-50%); /* 垂直居中调整 */ + width: calc((90vw - var(--width-max)) / 2); /* 宽度计算 */ + max-height: 80vh; /* 最大高度为视口高度的80% */ + overflow-y: auto; /* 垂直方向内容溢出时显示滚动条 */ + border: none; /* 无边框 */ + padding: 0; /* 无内边距 */ + margin: 0; /* 无外边距 */ + z-index: 99; /* 设置堆叠顺序,确保在其他元素之上 */ + + /* 隐藏滚动条 */ + &::-webkit-scrollbar { + /* Webkit 浏览器(Chrome, Safari)滚动条样式 */ + display: none; /* 隐藏滚动条 */ + } + + -ms-overflow-style: none; /* IE 和 Edge 隐藏滚动条 */ + scrollbar-width: none; /* Firefox 隐藏滚动条 */ + } + + .toc-nav { + /* 目录导航容器样式 */ + padding: 1.5rem; /* 内边距 */ + } + + .toc-nav ul { + /* 目录导航无序列表样式 */ + list-style: none; /* 移除列表项标记 */ + padding: 0; /* 移除内边距 */ + margin: 0; /* 移除外边距 */ + } + + .toc-nav li { + /* 目录导航列表项样式 */ + margin: 8px 0; /* 上下外边距 */ + } + + .toc-nav a { + /* 目录链接样式 */ + display: block; /* 块级显示 */ + text-decoration: none; /* 无下划线 */ + color: transparent; /* 默认透明 */ + padding: 0 12px; /* 内边距 */ + transition: all 0.2s ease; /* 所有属性过渡效果 */ + font-size: 0.9rem; /* 字体大小 */ + line-height: 1.4; /* 行高 */ + text-align: left; /* 文本左对齐 */ + white-space: nowrap; /* 禁止换行 */ + overflow: hidden; /* 隐藏溢出内容 */ + text-overflow: ellipsis; /* 显示省略号 */ + max-width: 100%; /* 限制最大宽度 */ + } + + .toc-nav:hover a { + color: var(--toc-text-color); /* hover时显示文字颜色 */ + } + + .toc-nav a::before { + /* 目录链接前的小横线样式 */ + content: ""; /* 生成内容 */ + display: inline-block; /* 行内块级显示 */ + width: 16px; /* 宽度 */ + height: 4px; /* 高度 */ + background-color: var(--toc-text-color); /* 灰色背景 */ + border-radius: 16px; /* 圆角 */ + margin-right: 12px; /* 右外边距 */ + vertical-align: middle; /* 垂直居中对齐 */ + } + + .toc-nav ul ul a::before { + /* 二级目录链接前的小横线样式 */ + width: 12px; /* 显示宽度 */ + margin-right: 16px; /* 调整右外边距,使其与默认 a::before 占据的总宽度一致 (12px + 12px = 24px) */ + } + + .toc-nav ul ul ul a::before { + /* 三级目录链接前的小横线样式 */ + width: 8px; /* 显示宽度 */ + margin-right: 20px; /* 调整右外边距,使其与默认 a::before 占据的总宽度一致 (8px + 16px = 24px) */ + } + + .toc-nav a.active, /* 活跃状态和鼠标悬停状态的目录链接样式 */ + .toc-nav a:hover { + text-decoration: none; /* 无下划线 */ + color: var(--toc-hover-color); /* 文字颜色变为深灰色 */ + } + + .toc-nav a.active::before, /* 活跃状态和鼠标悬停状态的目录链接前小横线样式 */ + .toc-nav a:hover::before { + background-color: var(--toc-hover-color); /* 背景颜色变为深灰色 */ + } + + /* upvote button style */ + button.upvote-btn { + margin: 0; + margin-left: auto; + padding: 0; + border: none; + background: none; + cursor: pointer; + display: flex; + flex-direction: column; + align-items: center; + color: var(--body-text-color); + } + + button.upvoted { + color: var(--upvoted-color); + } + + span.upvote-count { + margin-top: -4px; + font-size: smaller; + } + + @media (max-width: 800px) { + img[src*="#minipic"] { + max-width: 100%; + margin-left: auto; + margin-right: auto; + } + + div.toc { + display: none; + } + } +</style> diff --git a/layouts/partials/toc.html b/layouts/partials/toc.html new file mode 100644 index 0000000..66936a4 --- /dev/null +++ b/layouts/partials/toc.html @@ -0,0 +1,91 @@ +{{/* 根据页面内容生成目录 */}} +{{ if and .TableOfContents (ne .TableOfContents "<nav id=\"TableOfContents\"></nav>") }} +<nav class="toc-nav"> + {{ .TableOfContents }} +</nav> + +<script> + // 为目录添加平滑滚动和当前位置高亮 + document.addEventListener('DOMContentLoaded', function () { + const tocLinks = document.querySelectorAll('.toc-nav a'); + const headings = Array.from(tocLinks).map(link => { + const id = link.getAttribute('href').replace('#', ''); + return document.getElementById(id); + }).filter(h => h); + + // 平滑滚动 + tocLinks.forEach(link => { + link.addEventListener('click', function (e) { + e.preventDefault(); + const targetId = this.getAttribute('href').replace('#', ''); + const target = document.getElementById(targetId); + if (target) { + target.scrollIntoView({ + behavior: 'smooth', + block: 'start' + }); + + // 更新活动状态 + tocLinks.forEach(l => l.classList.remove('active')); + this.classList.add('active'); + } + }); + }); + + // 滚动时更新当前位置 + function updateActiveLink() { + const scrollTop = window.pageYOffset || document.documentElement.scrollTop; + const windowHeight = window.innerHeight; + + for (let i = headings.length - 1; i >= 0; i--) { + const heading = headings[i]; + const rect = heading.getBoundingClientRect(); + + if (rect.top <= 100) { + // 移除所有活动状态 + tocLinks.forEach(link => link.classList.remove('active')); + + // 高亮当前标题 + const activeLink = document.querySelector(`.toc-nav a[href="#${heading.id}"]`); + if (activeLink) { + activeLink.classList.add('active'); + + // 高亮所有父级标题 + let currentLi = activeLink.closest('li'); + while (currentLi) { + const parentLi = currentLi.parentElement.closest('li'); + if (parentLi) { + const parentLink = parentLi.querySelector('a'); + if (parentLink) { + parentLink.classList.add('active'); + } + currentLi = parentLi; + } else { + break; + } + } + } + break; + } + } + } + + // 节流函数 + let ticking = false; + function throttleScroll() { + if (!ticking) { + requestAnimationFrame(function () { + updateActiveLink(); + ticking = false; + }); + ticking = true; + } + } + + window.addEventListener('scroll', throttleScroll); + + // 初始化时更新一次 + updateActiveLink(); + }); +</script> +{{ end }}
\ No newline at end of file |
