调整到老博客的程度
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
{{- $enableComments := site.Params.comments.enable | default false -}}
|
||||
|
||||
{{ if not (eq .Params.comments nil) }}
|
||||
{{ $enableComments = .Params.comments }}
|
||||
{{ end }}
|
||||
|
||||
{{- if $enableComments -}}
|
||||
{{- if eq site.Params.comments.type "giscus" -}}
|
||||
{{ partial "components/giscus.html" . }}
|
||||
{{- else if eq site.Params.comments.type "remark42" -}}
|
||||
{{ partial "components/remark42.html" . }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,59 @@
|
||||
{{- with site.Params.comments.remark42 -}}
|
||||
<div id="remark42"></div>
|
||||
<script>
|
||||
var remark42_config = {
|
||||
host: '{{ .host }}',
|
||||
site_id: '{{ .site_id }}',
|
||||
max_shown_comments: 15,
|
||||
theme: 'light',
|
||||
page_title: '{{ $.Title }}',
|
||||
locale: '{{ site.Language.Lang | default "zh" }}',
|
||||
};
|
||||
</script>
|
||||
<script src="{{ .host }}/web/embed.js"></script>
|
||||
<script>
|
||||
(function () {
|
||||
function getRemark42Theme() {
|
||||
var stored = localStorage.getItem('color-theme');
|
||||
if (stored === 'light' || stored === 'dark') return stored;
|
||||
if (stored === 'system') {
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||
}
|
||||
var defaultTheme = '{{ site.Params.theme.default }}';
|
||||
if (defaultTheme === 'light' || defaultTheme === 'dark') return defaultTheme;
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||
}
|
||||
|
||||
function setRemark42Theme() {
|
||||
var frame = document.querySelector('iframe#remark42-frame');
|
||||
if (frame && frame.contentWindow) {
|
||||
frame.contentWindow.postMessage(
|
||||
{ theme: getRemark42Theme() },
|
||||
remark42_config.host
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
remark42_config.theme = getRemark42Theme();
|
||||
|
||||
window.addEventListener('message', function (e) {
|
||||
if (e.data && e.data.remark42) {
|
||||
setRemark42Theme();
|
||||
}
|
||||
});
|
||||
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', setRemark42Theme);
|
||||
|
||||
var toggles = document.querySelectorAll('.hextra-theme-toggle-options [data-item]');
|
||||
if (toggles) {
|
||||
toggles.forEach(function (toggle) {
|
||||
toggle.addEventListener('click', function () {
|
||||
setTimeout(setRemark42Theme, 200);
|
||||
});
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
{{- else -}}
|
||||
{{ warnf "remark42 is not configured" }}
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,55 @@
|
||||
<div style="height:48px"></div>
|
||||
|
||||
<div>
|
||||
<h2 class="hx:text-2xl hx:font-bold hx:tracking-tight hx:text-slate-900 hx:dark:text-slate-100">子站动态</h2>
|
||||
</div>
|
||||
|
||||
<div style="height:16px"></div>
|
||||
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px" class="hx:w-full">
|
||||
<a href="/daily" class="hextra-feature-card not-prose hx:block hx:relative hx:overflow-hidden hx:rounded-3xl hx:border hx:border-gray-200 hx:hover:border-gray-300 hx:dark:border-neutral-800 hx:dark:hover:border-neutral-700 hx:before:pointer-events-none hx:before:absolute hx:before:inset-0 hx:before:bg-glass-gradient">
|
||||
<div class="hx:relative hx:w-full hx:p-6">
|
||||
<h3 class="hx:text-2xl hx:font-medium hx:leading-6 hx:mb-2 hx:flex hx:items-center">
|
||||
<span class="hx:pr-2">
|
||||
<svg height="1.5rem" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
</span>
|
||||
<span>Daily 最新</span>
|
||||
</h3>
|
||||
<p class="hx:text-gray-500 hx:dark:text-gray-400 hx:text-sm hx:leading-6">查看日记最新更新</p>
|
||||
</div>
|
||||
</a>
|
||||
<a href="/photograph" class="hextra-feature-card not-prose hx:block hx:relative hx:overflow-hidden hx:rounded-3xl hx:border hx:border-gray-200 hx:hover:border-gray-300 hx:dark:border-neutral-800 hx:dark:hover:border-neutral-700 hx:before:pointer-events-none hx:before:absolute hx:before:inset-0 hx:before:bg-glass-gradient">
|
||||
<div class="hx:relative hx:w-full hx:p-6">
|
||||
<h3 class="hx:text-2xl hx:font-medium hx:leading-6 hx:mb-2 hx:flex hx:items-center">
|
||||
<span class="hx:pr-2">
|
||||
<svg height="1.5rem" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 13a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
|
||||
</span>
|
||||
<span>Photograph 最新</span>
|
||||
</h3>
|
||||
<p class="hx:text-gray-500 hx:dark:text-gray-400 hx:text-sm hx:leading-6">查看摄影最新作品</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div style="height:48px"></div>
|
||||
|
||||
<div>
|
||||
<h2 class="hx:text-2xl hx:font-bold hx:tracking-tight hx:text-slate-900 hx:dark:text-slate-100">关于我</h2>
|
||||
</div>
|
||||
|
||||
<div style="height:16px"></div>
|
||||
|
||||
{{- $card := site.GetPage "about-card.md" -}}
|
||||
{{- if $card }}
|
||||
<a href="/about" style="display:block;text-decoration:none;color:inherit;padding:24px;border-radius:24px;border:1px solid #e5e7eb;background:radial-gradient(ellipse at 50% 80%,rgba(234,179,8,0.08),hsla(0,0%,100%,0));transition:border-color 0.2s" onmouseover="this.style.borderColor='#d1d5db'" onmouseout="this.style.borderColor='#e5e7eb'" class="hextra-feature-card not-prose hx:before:pointer-events-none hx:before:absolute hx:before:inset-0 hx:before:bg-glass-gradient">
|
||||
<div style="display:flex;align-items:center;gap:24px">
|
||||
<div style="flex-shrink:0;width:96px;height:96px;border-radius:50%;overflow:hidden;border:2px solid #e5e7eb">
|
||||
<img src="{{ $card.Params.avatar }}" alt="{{ $card.Title }}" style="width:100%;height:100%;object-fit:cover;display:block" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 style="margin:0 0 8px 0;font-size:1.5rem;font-weight:600;color:#1e293b" class="hx:dark:text-slate-100">{{ $card.Title }}</h3>
|
||||
<p style="margin:0;font-size:0.875rem;color:#6b7280;line-height:1.7" class="hx:dark:text-gray-400">{{ $card.Params.bio }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{{- end }}
|
||||
@@ -0,0 +1 @@
|
||||
<link rel="stylesheet" href="/css/custom.css" />
|
||||
@@ -0,0 +1,3 @@
|
||||
<link rel="icon shortcut" href="{{ "resources/icon_32x32.png" | relURL }}" sizes="32x32" />
|
||||
<link rel="icon" href="{{ "resources/icon_180x180.png" | relURL }}" type="image/png" sizes="180x180" />
|
||||
<link rel="apple-touch-icon" href="{{ "resources/icon_180x180.png" | relURL }}" sizes="180x180" />
|
||||
@@ -0,0 +1,16 @@
|
||||
<footer class="hextra-footer hx:bg-gray-100 hx:pb-[env(safe-area-inset-bottom)] hx:dark:bg-neutral-900 hx:print:bg-transparent">
|
||||
<div class="hextra-max-footer-width hx:mx-auto hx:flex hx:justify-center hx:text-gray-500 hx:dark:text-gray-400 hx:text-xs" style="padding:24px 16px">
|
||||
<div style="text-align:center;line-height:1.8">
|
||||
<div>
|
||||
{{ site.Params.footer.startYear }}-{{ now.Year }} © {{ site.Params.footer.author }} ·
|
||||
Powered by <a href="https://github.com/imfing/hextra" target="_blank" rel="noreferrer" style="text-decoration:none" class="hx:hover:text-gray-700 hx:dark:hover:text-gray-200">Hextra</a> and
|
||||
<a href="https://gohugo.io/" target="_blank" rel="noreferrer" style="text-decoration:none" class="hx:hover:text-gray-700 hx:dark:hover:text-gray-200">Hugo</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://beian.miit.gov.cn/" target="_blank" rel="noreferrer" style="text-decoration:none" class="hx:hover:text-gray-700 hx:dark:hover:text-gray-200">{{ site.Params.footer.icp }}</a>
|
||||
  
|
||||
<a href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode={{ site.Params.footer.policeCode }}" target="_blank" rel="noreferrer" style="text-decoration:none" class="hx:hover:text-gray-700 hx:dark:hover:text-gray-200">{{ site.Params.footer.police }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
@@ -0,0 +1,95 @@
|
||||
{{- $navWidth := "hx:max-w-[90rem]" -}}
|
||||
{{- with .Site.Params.navbar.width -}}
|
||||
{{ if eq . "normal" -}}
|
||||
{{ $navWidth = "hx:max-w-screen-xl" -}}
|
||||
{{ else if eq . "full" -}}
|
||||
{{ $navWidth = "max-w-full" -}}
|
||||
{{ end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- $page := . -}}
|
||||
{{- $iconHeight := 24 -}}
|
||||
|
||||
<div id="hextra-nav-wrapper" class="hextra-nav-container hx:sticky hx:top-0 hx:z-20 hx:w-full hx:bg-transparent hx:print:hidden" style="transition:transform 0.3s ease">
|
||||
<div
|
||||
class="hextra-nav-container-blur hx:pointer-events-none hx:absolute hx:z-[-1] hx:h-full hx:w-full hx:bg-white hx:dark:bg-dark hx:shadow-[0_2px_4px_rgba(0,0,0,.02),0_1px_0_rgba(0,0,0,.06)] hx:contrast-more:shadow-[0_0_0_1px_#000] hx:dark:shadow-[0_-1px_0_rgba(255,255,255,.1)_inset] hx:contrast-more:dark:shadow-[0_0_0_1px_#fff]"
|
||||
></div>
|
||||
|
||||
<nav class="hextra-max-navbar-width hx:mx-auto hx:flex hx:items-center hx:justify-end hx:gap-1 hx:md:gap-2 hx:h-[var(--hextra-navbar-height)] hx:px-6">
|
||||
{{ partial "navbar-title.html" . }}
|
||||
|
||||
{{- $currentPage := . -}}
|
||||
{{- range .Site.Menus.main -}}
|
||||
{{- if eq .Params.type "search" -}}
|
||||
{{- partial "search.html" (dict "icon" .Params.icon) -}}
|
||||
{{- else -}}
|
||||
{{- $link := .URL -}}
|
||||
{{- $external := strings.HasPrefix $link "http" -}}
|
||||
{{- with .PageRef -}}
|
||||
{{- if hasPrefix . "/" -}}
|
||||
{{- $link = relLangURL (strings.TrimPrefix "/" .) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- if eq .Params.type "link" -}}
|
||||
{{- partial "navbar-link.html" (dict "currentPage" $currentPage "link" $link "external" $external "item" . "icon" .Params.icon) -}}
|
||||
{{- else if eq .Params.type "theme-toggle" -}}
|
||||
{{- partial "theme-toggle.html" (dict "iconHeight" $iconHeight "hideLabel" (not .Params.label) "iconHeight" $iconHeight "location" "top" "class" "hx:p-1 hx:md:p-2") -}}
|
||||
{{- else if eq .Params.type "language-switch" -}}
|
||||
{{- partial "language-switch" (dict "context" $page "grow" false "hideLabel" (not .Params.label) "iconName" (.Params.icon | default "translate") "iconHeight" $iconHeight "location" "top" "class" "hx:p-1 hx:md:p-2") -}}
|
||||
{{- else if .Params.icon -}}
|
||||
{{- /* Display icon menu item */ -}}
|
||||
{{- if not $link -}}{{ warnf "Icon menu item '%s' has no URL" .Name }}{{- end -}}
|
||||
{{- $rel := cond (eq .Params.icon "mastodon") "noreferrer me" "noreferrer" }}
|
||||
<a class="hx:p-1 hx:md:p-2 hx:text-current" {{ if $external }}target="_blank" rel="{{ $rel }}"{{ end }} href="{{ $link }}" title="{{ or (T .Identifier) .Name | safeHTML }}">
|
||||
{{- partial "utils/icon.html" (dict "name" .Params.icon "attributes" (printf "height=%d" $iconHeight)) -}}
|
||||
<span class="hx:sr-only">{{ or (T .Identifier) .Name | safeHTML }}</span>
|
||||
</a>
|
||||
{{- else -}}
|
||||
{{- partial "navbar-link.html" (dict "currentPage" $currentPage "link" $link "external" $external "item" .) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* Quick links - only on non-homepage, separated from menu by spacer */}}
|
||||
{{- with .Site.Params.quickLinks -}}
|
||||
{{- if not $.IsHome -}}
|
||||
<div style="flex-grow:1"></div>
|
||||
<div class="hx:flex hx:items-center hx:text-sm hx:text-gray-500 hx:dark:text-gray-400" style="gap:1.25rem;padding-right:0.5rem;padding-top:0.5rem;padding-bottom:0.5rem">
|
||||
{{- range . -}}
|
||||
{{- $qlink := .url -}}
|
||||
{{- $qexternal := hasPrefix $qlink "http" -}}
|
||||
<a
|
||||
href="{{ $qlink }}"
|
||||
class="hx:whitespace-nowrap hx:hover:text-gray-900 hx:dark:hover:text-gray-100 hx:transition-colors"
|
||||
{{ if $qexternal }}target="_blank" rel="noreferrer"{{ end }}
|
||||
>{{ .name }}</a>
|
||||
{{- end -}}
|
||||
</div>
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
<button type="button" aria-label="{{ (T "menu") | default "Menu" }}" aria-expanded="false" class="hextra-hamburger-menu hx:cursor-pointer hx:-mr-1 hx:rounded-sm hx:p-1 hx:active:bg-gray-400/20 hx:md:hidden hx:hextra-focus-visible-inset">
|
||||
{{- partial "utils/icon.html" (dict "name" "hamburger-menu" "attributes" (printf "height=%d" $iconHeight)) -}}
|
||||
</button>
|
||||
</nav>
|
||||
</div>
|
||||
<script>
|
||||
(function(){
|
||||
var nav = document.getElementById('hextra-nav-wrapper');
|
||||
if(!nav) return;
|
||||
var lastScroll = 0;
|
||||
var threshold = 10;
|
||||
window.addEventListener('scroll', function(){
|
||||
var st = window.pageYOffset || document.documentElement.scrollTop;
|
||||
if(st <= 0){ nav.style.transform = 'translateY(0)'; return; }
|
||||
if(Math.abs(st - lastScroll) < threshold) return;
|
||||
if(st > lastScroll && st > 300){
|
||||
nav.style.transform = 'translateY(-100%)';
|
||||
} else {
|
||||
nav.style.transform = 'translateY(0)';
|
||||
}
|
||||
lastScroll = st;
|
||||
}, {passive:true});
|
||||
})();
|
||||
</script>
|
||||
@@ -0,0 +1,106 @@
|
||||
{{/* Table of Contents */}}
|
||||
{{- $toc := .Params.toc | default true -}}
|
||||
{{- $onThisPage := (T "onThisPage") | default "On this page"}}
|
||||
{{- $tags := (T "tags") | default "Tags"}}
|
||||
{{- $editThisPage := (T "editThisPage") | default "Edit this page"}}
|
||||
{{- $backToTop := (T "backToTop") | default "Scroll to top" -}}
|
||||
|
||||
<nav class="hextra-toc hx:order-last hx:hidden hx:w-64 hx:shrink-0 hx:xl:block hx:print:hidden hx:px-4" aria-label="{{ (T "tableOfContents") | default "Table of contents" }}">
|
||||
{{- if $toc }}
|
||||
<div class="hextra-scrollbar hx:sticky hx:top-[var(--hextra-navbar-height)] hx:overflow-y-auto hx:pr-4 hx:pt-6 hx:text-sm [hyphens:auto] hx:max-h-[calc(100vh-var(--hextra-navbar-height)-env(safe-area-inset-bottom))] hx:ltr:-mr-4 hx:rtl:-ml-4">
|
||||
{{- with .Fragments.Headings -}}
|
||||
<p class="hx:mb-4 hx:font-semibold hx:tracking-tight">{{ $onThisPage }}</p>
|
||||
{{- range . -}}
|
||||
<ul>
|
||||
{{- with .Headings -}}{{ template "toc-subheading" (dict "headings" . "level" 0) }}{{- end -}}
|
||||
</ul>
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- $borderClass := "hx:mt-8 hx:border-t hx:bg-white hx:pt-8 hx:shadow-[0_-12px_16px_white] hx:dark:bg-dark hx:dark:shadow-[0_-12px_16px_#111]" -}}
|
||||
|
||||
{{- if not .Fragments.Headings -}}
|
||||
{{- $borderClass = "" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* TOC bottom part */}}
|
||||
<div class="{{ $borderClass }} hx:sticky hx:bottom-0 hx:flex hx:flex-col hx:items-start hx:gap-3 hx:pb-8 hx:border-gray-200 hx:dark:border-neutral-800 hx:contrast-more:border-t hx:contrast-more:border-neutral-400 hx:contrast-more:shadow-none hx:contrast-more:dark:border-neutral-400">
|
||||
|
||||
{{/* Categories */}}
|
||||
{{- with .Params.categories -}}
|
||||
<div class="hx:text-xs hx:w-full">
|
||||
<div class="hx:font-semibold hx:text-gray-700 hx:dark:text-gray-300 hx:mb-1.5">分类</div>
|
||||
<div class="hx:flex hx:flex-wrap hx:gap-1.5">
|
||||
{{- range . -}}
|
||||
<a href="{{ "categories/" | relLangURL }}{{ . | urlize }}/" class="hx:inline-block hx:px-2 hx:py-0.5 hx:rounded hx:bg-blue-50 hx:text-blue-700 hx:dark:bg-blue-900/30 hx:dark:text-blue-300 hx:text-xs hx:hover:bg-blue-100 hx:dark:hover:bg-blue-900/50 hx:transition-colors">{{ . }}</a>
|
||||
{{- end -}}
|
||||
</div>
|
||||
</div>
|
||||
{{- end -}}
|
||||
|
||||
{{/* Tags */}}
|
||||
{{- with .Params.tags -}}
|
||||
<div class="hx:text-xs hx:w-full">
|
||||
<div class="hx:font-semibold hx:text-gray-700 hx:dark:text-gray-300 hx:mb-1.5">标签</div>
|
||||
<div class="hx:flex hx:flex-wrap hx:gap-1.5">
|
||||
{{- range . -}}
|
||||
<a href="{{ "tags/" | relLangURL }}{{ . | urlize }}/" class="hx:inline-block hx:px-2 hx:py-0.5 hx:rounded hx:bg-gray-100 hx:text-gray-600 hx:dark:bg-neutral-800 hx:dark:text-gray-400 hx:text-xs hx:hover:bg-gray-200 hx:dark:hover:bg-neutral-700 hx:transition-colors">{{ . }}</a>
|
||||
{{- end -}}
|
||||
</div>
|
||||
</div>
|
||||
{{- end -}}
|
||||
|
||||
{{- if site.Params.editURL.enable -}}
|
||||
{{- $editURL := site.Params.editURL.base | default "" -}}
|
||||
{{- with .Params.editURL -}}
|
||||
{{- $editURL = . -}}
|
||||
{{- else -}}
|
||||
{{- with .File -}}
|
||||
{{- $sourceDir := replace (strings.TrimPrefix .FileInfo.Meta.BaseDir .FileInfo.Meta.SourceRoot) "\\" "/" -}}
|
||||
{{- $sourceDir = strings.TrimPrefix "/content" $sourceDir -}}
|
||||
{{- $path := replace .Path "\\" "/" -}}
|
||||
{{- $editURL = urls.JoinPath $editURL $sourceDir $path -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
<a class="hx:inline-block hx:rounded-sm hx:text-xs hx:font-medium hx:text-gray-500 hx:hover:text-gray-900 hx:dark:text-gray-400 hx:dark:hover:text-gray-100 hx:contrast-more:text-gray-800 hx:contrast-more:dark:text-gray-50 hx:hextra-focus-visible-inset" href="{{ $editURL }}" target="_blank" rel="noreferrer">{{ $editThisPage }}</a>
|
||||
{{- end -}}
|
||||
|
||||
{{/* Scroll To Top */}}
|
||||
<button id="backToTop" tabindex="-1" class="hx:cursor-pointer hx:transition-all hx:duration-75 hx:opacity-0 hx:text-xs hx:font-medium hx:text-gray-500 hx:hover:text-gray-900 hx:dark:text-gray-400 hx:dark:hover:text-gray-100 hx:contrast-more:text-gray-800 hx:contrast-more:dark:text-gray-50">
|
||||
<span>
|
||||
{{- $backToTop -}}
|
||||
</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" focusable="false" class="hx:inline hx:ltr:ml-1 hx:rtl:mr-1 hx:h-3.5 hx:w-3.5 hx:rounded-full hx:border hx:border-gray-500 hx:hover:border-gray-900 hx:dark:border-gray-400 hx:dark:hover:border-gray-100 hx:contrast-more:border-gray-800 hx:contrast-more:dark:border-gray-50">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 15.75l7.5-7.5 7.5 7.5" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{{ end -}}
|
||||
</nav>
|
||||
|
||||
{{/* TOC subheadings component. This is a recursive component that renders a list of headings. */}}
|
||||
{{- define "toc-subheading" -}}
|
||||
{{- $headings := .headings -}}
|
||||
{{- $level := .level -}}
|
||||
{{- if ge $level 6 -}}
|
||||
{{ return }}
|
||||
{{- end -}}
|
||||
|
||||
{{- $padding := (mul $level 4) -}}
|
||||
{{- $class := cond (eq $level 0) "hx:font-medium" (printf "hx:ltr:pl-%d hx:rtl:pr-%d" $padding $padding) -}}
|
||||
|
||||
{{- range $headings }}
|
||||
{{- if .Title }}
|
||||
<li class="hx:my-2 hx:scroll-my-6 hx:scroll-py-6">
|
||||
<a class="{{ $class }} hx:inline-block hx:rounded-sm hx:text-gray-500 hx:hover:text-gray-900 hx:dark:text-gray-400 hx:dark:hover:text-gray-300 hx:contrast-more:text-gray-900 hx:contrast-more:underline hx:contrast-more:dark:text-gray-50 hx:w-full hx:wrap-break-word hx:hextra-focus-visible-inset" href="#{{ anchorize .ID }}">
|
||||
{{- .Title | safeHTML | plainify | htmlUnescape }}
|
||||
</a>
|
||||
</li>
|
||||
{{- end -}}
|
||||
{{- with .Headings -}}
|
||||
{{ template "toc-subheading" (dict "headings" . "level" (add $level 1)) }}
|
||||
{{- end -}}
|
||||
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,37 @@
|
||||
{{- $title := .Get "title" -}}
|
||||
{{- $subtitle := .Get "subtitle" -}}
|
||||
{{- $class := .Get "class" -}}
|
||||
{{- $image := .Get "image" -}}
|
||||
{{- $imageClass := .Get "imageClass" -}}
|
||||
{{- $imageStyle := .Get "imageStyle" -}}
|
||||
{{- $style := .Get "style" -}}
|
||||
{{- $icon := .Get "icon" -}}
|
||||
{{- $link := .Get "link" -}}
|
||||
|
||||
{{- $external := hasPrefix $link "http" -}}
|
||||
{{- $href := cond (strings.HasPrefix $link "/") ($link | relURL) $link -}}
|
||||
|
||||
{{- if hasPrefix $image "/" -}}
|
||||
{{- $image = relURL (strings.TrimPrefix "/" $image) -}}
|
||||
{{- end -}}
|
||||
|
||||
<a
|
||||
{{ with $link }}href="{{ $href }}" {{ with $external }} target="_blank" rel="noreferrer"{{ end }}{{ end }}
|
||||
{{ with $style }}style="{{ . | safeCSS }}"{{ end }}
|
||||
class="{{ $class }} hextra-feature-card not-prose hx:block hx:relative hx:overflow-hidden hx:rounded-3xl hx:border hx:border-gray-200 hx:hover:border-gray-300 hx:dark:border-neutral-800 hx:dark:hover:border-neutral-700 hx:before:pointer-events-none hx:before:absolute hx:before:inset-0 hx:before:bg-glass-gradient"
|
||||
>
|
||||
<div class="hx:relative hx:w-full hx:p-6">
|
||||
<h3 class="hx:text-2xl hx:font-medium hx:leading-6 hx:mb-2 hx:flex hx:items-center">
|
||||
{{ with $icon -}}
|
||||
<span class="hx:pr-2">
|
||||
{{- partial "utils/icon.html" (dict "name" . "attributes" "height=1.5rem") -}}
|
||||
</span>
|
||||
{{ end -}}
|
||||
<span>{{ $title }}</span>
|
||||
</h3>
|
||||
<p class="hx:text-gray-500 hx:dark:text-gray-400 hx:text-sm hx:leading-6">{{ $subtitle | markdownify }}</p>
|
||||
</div>
|
||||
{{- with $image -}}
|
||||
<img src="{{ . }}" {{ with $imageStyle }}style="{{ . | safeCSS }}"{{ end }} class="hx:absolute hx:max-w-none {{ $imageClass }}" alt="{{ $title }}" />
|
||||
{{- end -}}
|
||||
</a>
|
||||
@@ -0,0 +1,47 @@
|
||||
{{ define "main" }}
|
||||
<div class="hx:mx-auto hx:flex hextra-max-page-width">
|
||||
{{ partial "sidebar.html" (dict "context" . "disableSidebar" true "displayPlaceholder" true) }}
|
||||
<article class="hx:w-full hx:break-words hx:flex hx:min-h-[calc(100vh-var(--hextra-navbar-height))] hx:min-w-0 hx:justify-center hx:pb-8 hx:pr-[calc(env(safe-area-inset-right)-1.5rem)]">
|
||||
<main id="content" class="hx:w-full hx:min-w-0 hextra-max-content-width hx:px-6 hx:pt-4 hx:md:px-12">
|
||||
{{ partial "custom/page-begin.html" . }}
|
||||
{{ partial "breadcrumb.html" (dict "page" . "enable" false) }}
|
||||
<br class="hx:mt-1.5 hx:text-sm" />
|
||||
{{ if .Title }}<h1 class="hx:text-center hx:mt-2 hx:text-4xl hx:font-bold hx:tracking-tight hx:text-slate-900 hx:dark:text-slate-100">{{ .Title }}</h1>{{ end }}
|
||||
<div class="content">
|
||||
{{ partial "custom/content-begin.html" . }}
|
||||
{{ .Content }}
|
||||
</div>
|
||||
{{- $pages := partial "utils/sort-pages" (dict "page" . "by" site.Params.blog.list.sortBy "order" site.Params.blog.list.sortOrder) -}}
|
||||
{{- $pagerSize := site.Params.blog.list.pagerSize | default 10 -}}
|
||||
{{- $paginator := .Paginate $pages $pagerSize -}}
|
||||
{{- $pageCount := len $paginator.Pages -}}
|
||||
{{- range $index, $page := $paginator.Pages }}
|
||||
<a href="{{ .RelPermalink }}" style="color:inherit;text-decoration:none;display:block" class="hx:mb-10 hx:group hx:block hx:rounded-lg hx:-mx-2 hx:px-2 hx:py-3 hx:hover:bg-gray-50 hx:dark:hover:bg-neutral-800/50 hx:transition-colors">
|
||||
<h3 class="hx:font-semibold hx:mt-8 hx:text-2xl hx:group-hover:text-[color:hsl(var(--primary-hue),100%,50%)] hx:transition-colors">{{ .Title }}</h3>
|
||||
{{ if site.Params.blog.list.displayTags }}
|
||||
<div class="hx:text-sm hx:leading-7">
|
||||
{{ partial "tags.html" (dict "context" .) }}
|
||||
</div>
|
||||
{{ end }}
|
||||
<p class="hx:opacity-80 hx:mt-4 hx:leading-7">{{- partial "utils/page-description" . -}}</p>
|
||||
<p class="hx:opacity-50 hx:text-sm hx:mt-4 hx:leading-7">
|
||||
{{ partial "utils/format-date" .Date }}
|
||||
{{ if and .Lastmod (ne (.Date.Format "2006-01-02") (.Lastmod.Format "2006-01-02")) }}
|
||||
<span style="margin-left:8px">修改于 {{ partial "utils/format-date" .Lastmod }}</span>
|
||||
{{ end }}
|
||||
</p>
|
||||
</a>
|
||||
{{- if lt (add $index 1) $pageCount }}
|
||||
<div style="width:80%;margin:0 auto;border-top:1px solid #e5e7eb"></div>
|
||||
{{- end -}}
|
||||
{{ end -}}
|
||||
|
||||
{{- if gt $paginator.TotalPages 1 -}}
|
||||
{{ partial "components/blog-pager.html" $paginator }}
|
||||
{{- end -}}
|
||||
{{ partial "custom/page-end.html" . }}
|
||||
</main>
|
||||
</article>
|
||||
<div class="hx:max-xl:hidden hx:h-0 hx:w-64 hx:shrink-0"></div>
|
||||
</div>
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,58 @@
|
||||
{{ define "main" }}
|
||||
<div class="hx:mx-auto hx:flex hextra-max-page-width">
|
||||
{{ partial "sidebar.html" (dict "context" . "disableSidebar" true "displayPlaceholder" true) }}
|
||||
{{ partial "toc.html" . }}
|
||||
<article class="hx:w-full hx:break-words hx:flex hx:min-h-[calc(100vh-var(--hextra-navbar-height))] hx:min-w-0 hx:justify-center hx:pb-8 hx:pr-[calc(env(safe-area-inset-right)-1.5rem)]">
|
||||
<main id="content" class="hx:w-full hx:min-w-0 hextra-max-content-width hx:px-6 hx:pt-4 hx:md:px-12">
|
||||
{{ partial "custom/page-begin.html" . }}
|
||||
{{ partial "breadcrumb.html" (dict "page" . "enable" true) }}
|
||||
{{ if .Title }}
|
||||
<div class="hx:flex hx:flex-col hx:sm:flex-row hx:items-start hx:sm:items-center hx:sm:justify-between hx:gap-4 hx:mt-2">
|
||||
<h1 class="hx:mb-0 hx:text-4xl hx:font-bold hx:tracking-tight hx:text-slate-900 hx:dark:text-slate-100">{{ .Title }}</h1>
|
||||
{{ partial "components/page-context-menu" . }}
|
||||
</div>
|
||||
{{ end }}
|
||||
<div class="hx:mt-4 hx:mb-16 hx:text-gray-500 hx:dark:text-gray-400 hx:text-sm hx:flex hx:items-center hx:flex-wrap hx:gap-y-2">
|
||||
{{- with $date := .Date }}<span class="hx:mr-1">{{ partial "utils/format-date" $date }}</span>{{ end -}}
|
||||
{{- $lazyLoading := site.Params.enableImageLazyLoading | default true -}}
|
||||
{{ if and .Date .Params.authors }}<span class="hx:mx-1">·</span>{{ end -}}
|
||||
{{- with $.Params.authors -}}
|
||||
{{- range $i, $author := . -}}
|
||||
{{- if reflect.IsMap $author -}}
|
||||
{{- if and $i (not $author.image) }}<span class="hx:mr-1">,</span>{{ end -}}
|
||||
<a
|
||||
{{ with $author.link }}href="{{ . }}" target="_blank"{{ end }}
|
||||
class="hx:group hx:inline-flex hx:items-center hx:text-current hx:gap-x-1.5 hx:mx-1"
|
||||
{{ with $author.name }}title="{{ . }}"{{ end }}
|
||||
>
|
||||
{{- with $image := $author.image }}
|
||||
{{- $isLocal := not (urls.Parse $image).Scheme -}}
|
||||
{{- $startsWithSlash := hasPrefix $image "/" -}}
|
||||
{{- if and $isLocal $startsWithSlash }}
|
||||
{{- $image = (relURL (strings.TrimPrefix "/" $image)) -}}
|
||||
{{ end -}}
|
||||
<img src="{{ $image | safeURL }}" alt="{{ $author.name }}" class="hx:inline-block hx:h-4 hx:w-4 hx:rounded-full" {{ if $lazyLoading }}loading="lazy"{{ end }} />
|
||||
{{ end -}}
|
||||
<div class="hx:group-hover:underline">{{ $author.name }}</div>
|
||||
</a>
|
||||
{{- else -}}
|
||||
{{- if $i }}<span class="hx:mr-1">,</span>{{ end -}}<a href="/about" class="hx:mx-1 hx:hover:underline">{{ $author }}</a>
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
</div>
|
||||
<div class="content">
|
||||
{{ partial "custom/content-begin.html" . }}
|
||||
{{ .Content }}
|
||||
</div>
|
||||
{{- partial "components/last-updated.html" . -}}
|
||||
{{- if (site.Params.blog.article.displayPagination | default true) -}}
|
||||
{{- .Store.Set "reversePagination" (.Params.reversePagination | default true) -}}
|
||||
{{- partial "components/pager.html" . -}}
|
||||
{{ end }}
|
||||
{{- partial "components/comments.html" . -}}
|
||||
{{ partial "custom/page-end.html" . }}
|
||||
</main>
|
||||
</article>
|
||||
</div>
|
||||
{{ end }}
|
||||
@@ -0,0 +1,42 @@
|
||||
{{ define "main" }}
|
||||
<div class="hx:mx-auto hx:flex hextra-max-page-width">
|
||||
{{ partial "sidebar.html" (dict "context" . "disableSidebar" true) }}
|
||||
<main
|
||||
id="content"
|
||||
class="hx:w-full hx:break-words hx:min-h-[calc(100vh-var(--hextra-navbar-height))] hx:min-w-0 hx:pb-8 hx:pt-8 hx:md:pt-12 hx:pl-[max(env(safe-area-inset-left),1.5rem)] hx:pr-[max(env(safe-area-inset-right),1.5rem)]"
|
||||
>
|
||||
{{ partial "custom/page-begin.html" . }}
|
||||
<div class="hx:flex hx:flex-col hx:items-start">
|
||||
{{ partial "custom/content-begin.html" . }}
|
||||
{{ .Content }}
|
||||
|
||||
{{/* Blog posts section */}}
|
||||
{{ $posts := where site.RegularPages "Section" "posts" }}
|
||||
{{ if $posts }}
|
||||
<div style="height:48px"></div>
|
||||
<div>
|
||||
<h2 class="hx:text-2xl hx:font-bold hx:tracking-tight hx:text-slate-900 hx:dark:text-slate-100">最近文章</h2>
|
||||
</div>
|
||||
<div style="height:16px"></div>
|
||||
<div class="hx:w-full" style="display:flex;flex-direction:column;gap:20px">
|
||||
{{ range first 5 $posts }}
|
||||
<a href="{{ .RelPermalink }}" style="display:block;text-decoration:none;color:inherit;padding:16px;border-radius:12px;border:1px solid #e5e7eb;transition:border-color 0.2s,box-shadow 0.2s" onmouseover="this.style.borderColor='#1f2937';this.style.boxShadow='0 2px 8px rgba(0,0,0,0.06)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.boxShadow='none'">
|
||||
<h3 style="margin:0 0 4px 0;font-size:1.125rem;font-weight:600;color:#1e293b" class="hx:dark:text-slate-100">{{ .Title }}</h3>
|
||||
{{ with .Description }}<p style="margin:0;font-size:0.875rem;color:#6b7280;line-height:1.6;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden" class="hx:dark:text-gray-400">{{ . }}</p>{{ end }}
|
||||
<div style="margin-top:8px;display:flex;align-items:center;gap:8px;font-size:0.75rem;color:#9ca3af" class="hx:dark:text-gray-500">
|
||||
<time>{{ .Date.Format "2006/01/02" }}</time>
|
||||
{{ range .Params.tags }}
|
||||
<span style="padding:2px 6px;border-radius:4px;background:#f3f4f6;color:#4b5563" class="hx:dark:bg-neutral-800 hx:dark:text-gray-400">{{ . }}</span>
|
||||
{{ end }}
|
||||
</div>
|
||||
</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
{{ partial "custom/content-end.html" . }}
|
||||
</div>
|
||||
{{ partial "custom/page-end.html" . }}
|
||||
</main>
|
||||
</div>
|
||||
{{ end }}
|
||||
Reference in New Issue
Block a user