Compare commits
10
Commits
96202fea2b
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e123a30b7 | ||
|
|
e409eddf5c | ||
|
|
03bf8b0c3f | ||
|
|
e294e4ed70 | ||
|
|
d3eacc9daf | ||
|
|
c0f57bab7a | ||
|
|
752fd5805f | ||
|
|
0fc8264927 | ||
|
|
55340540b5 | ||
|
|
df9253a8e9 |
@@ -0,0 +1,80 @@
|
|||||||
|
@import "../../breakpoints";
|
||||||
|
@import "../../mixins";
|
||||||
|
|
||||||
|
.artalk-container {
|
||||||
|
@include card-style;
|
||||||
|
padding: 5px;
|
||||||
|
|
||||||
|
@include respond(md) {
|
||||||
|
padding: var(--card-padding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.artalk {
|
||||||
|
--at-color-bg: var(--card-background);
|
||||||
|
--at-color-font: var(--card-text-color-main);
|
||||||
|
--at-color-sub: var(--card-text-color-secondary);
|
||||||
|
--at-color-main: var(--accent-color);
|
||||||
|
--at-color-border: var(--card-separator-color);
|
||||||
|
--at-border-radius: var(--card-border-radius);
|
||||||
|
--at-color-link: var(--accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.artalk a {
|
||||||
|
color: var(--at-color-link);
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color 0.3s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--accent-color-darker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.artalk .atk-content a,
|
||||||
|
.artalk .atk-editor-plug-preview a {
|
||||||
|
color: var(--accent-color);
|
||||||
|
box-shadow: 0px -2px 0px rgba(var(--link-background-color), var(--link-background-opacity)) inset;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--accent-color-darker);
|
||||||
|
box-shadow: 0px calc(-1rem * var(--article-line-height)) 0px rgba(var(--link-background-color), var(--link-background-opacity-hover)) inset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-scheme="dark"] .artalk {
|
||||||
|
--at-color-main: var(--accent-color);
|
||||||
|
--at-color-link: var(--accent-color);
|
||||||
|
--at-color-bg: var(--card-background);
|
||||||
|
--at-color-bg-transl: rgba(66, 66, 66, 0.95);
|
||||||
|
--at-color-bg-grey: rgba(255, 255, 255, 0.08);
|
||||||
|
--at-color-bg-grey-transl: rgba(255, 255, 255, 0.06);
|
||||||
|
--at-color-bg-light: rgba(255, 255, 255, 0.08);
|
||||||
|
--at-color-border: var(--card-separator-color);
|
||||||
|
--at-color-font: var(--card-text-color-main);
|
||||||
|
--at-color-deep: var(--card-text-color-main);
|
||||||
|
--at-color-sub: var(--card-text-color-secondary);
|
||||||
|
--at-color-meta: var(--card-text-color-secondary);
|
||||||
|
--at-color-grey: var(--card-text-color-secondary);
|
||||||
|
--at-color-gradient: linear-gradient(
|
||||||
|
180deg,
|
||||||
|
transparent,
|
||||||
|
var(--card-background)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.artalk code {
|
||||||
|
font-family: var(--code-font-family);
|
||||||
|
}
|
||||||
|
|
||||||
|
.artalk .atk-avatar img {
|
||||||
|
border-radius: var(--card-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-scheme="dark"] .artalk .atk-avatar img {
|
||||||
|
filter: brightness(0.75);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-scheme="dark"] .artalk .atk-send-btn {
|
||||||
|
color: var(--accent-color-text);
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
right: 0;
|
right: 0;
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
padding: var(--container-padding);
|
padding: var(--container-padding);
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
&[aria-hidden="true"] {
|
&[aria-hidden="true"] {
|
||||||
display: none;
|
display: none;
|
||||||
@@ -21,6 +22,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: var(--spacing-md);
|
gap: var(--spacing-md);
|
||||||
|
pointer-events: auto;
|
||||||
|
|
||||||
@include respond(md) {
|
@include respond(md) {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|||||||
@@ -95,13 +95,6 @@
|
|||||||
-webkit-mask-image: var(--subsection-mask-image);
|
-webkit-mask-image: var(--subsection-mask-image);
|
||||||
mask-image: var(--subsection-mask-image);
|
mask-image: var(--subsection-mask-image);
|
||||||
|
|
||||||
// CSS-only: left fade ramps in quickly once horizontal scrolling starts,
|
|
||||||
// and right fade turns off near the end of horizontal scroll.
|
|
||||||
animation: subsection-left-fade linear both, subsection-right-fade linear both;
|
|
||||||
animation-timeline: scroll(self inline);
|
|
||||||
animation-range: 1px 24px, 0% 100%;
|
|
||||||
animation-timing-function: ease-out, linear;
|
|
||||||
|
|
||||||
[dir="rtl"] & {
|
[dir="rtl"] & {
|
||||||
margin-left: calc(var(--overlap-x) * -1);
|
margin-left: calc(var(--overlap-x) * -1);
|
||||||
margin-right: calc(var(--overlap-x) * -1);
|
margin-right: calc(var(--overlap-x) * -1);
|
||||||
@@ -132,6 +125,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only apply scroll-driven edge fades in browsers that support scroll timelines.
|
||||||
|
// Browsers without support (e.g. Firefox) fall back to the static right-edge fade
|
||||||
|
// defined by the explicit CSS variable declarations above.
|
||||||
|
@supports (animation-timeline: scroll(self inline)) {
|
||||||
|
.subsection-list {
|
||||||
|
animation: subsection-left-fade linear both, subsection-right-fade linear both;
|
||||||
|
animation-timeline: scroll(self inline);
|
||||||
|
animation-range: 1px 24px, 0% 100%;
|
||||||
|
animation-timing-function: ease-out, linear;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes subsection-left-fade {
|
@keyframes subsection-left-fade {
|
||||||
from {
|
from {
|
||||||
--left-edge-fade-size: 0px;
|
--left-edge-fade-size: 0px;
|
||||||
|
|||||||
@@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* Consent-gated comments bootstrap.
|
||||||
|
*
|
||||||
|
* This module controls whether third-party comments are rendered based on
|
||||||
|
* functional cookie consent, and injects template scripts in sequence to
|
||||||
|
* avoid eager or duplicate script execution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Consent event payload used by the comments gate.
|
||||||
|
* It mirrors cookie consent state shape but keeps optional fields for safety.
|
||||||
|
*/
|
||||||
|
interface CommentsConsentState {
|
||||||
|
necessary?: boolean;
|
||||||
|
analytics?: boolean;
|
||||||
|
functional?: boolean;
|
||||||
|
timestamp?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve functional consent with layered fallback:
|
||||||
|
* 1) explicit event detail, 2) CookieConsent public API, 3) dataset mirror.
|
||||||
|
*/
|
||||||
|
const hasFunctionalConsent = (consentDetail?: CommentsConsentState | null): boolean => {
|
||||||
|
const cookieConsent = (window as Window & {
|
||||||
|
cookieConsent?: {
|
||||||
|
hasConsent?: (category: 'necessary' | 'analytics' | 'functional') => boolean;
|
||||||
|
};
|
||||||
|
}).cookieConsent;
|
||||||
|
|
||||||
|
return (
|
||||||
|
consentDetail?.functional ??
|
||||||
|
cookieConsent?.hasConsent?.('functional') ??
|
||||||
|
document.documentElement.dataset.consentFunctional === 'true'
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
interface DeferredScript {
|
||||||
|
placeholder: Comment;
|
||||||
|
script: HTMLScriptElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
const prepareDeferredScripts = (fragment: DocumentFragment): DeferredScript[] => {
|
||||||
|
return Array.from(fragment.querySelectorAll('script')).map(script => {
|
||||||
|
const placeholder = document.createComment('comments-script-placeholder');
|
||||||
|
script.replaceWith(placeholder);
|
||||||
|
return { placeholder, script };
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const activateDeferredScripts = async (scripts: DeferredScript[]): Promise<void> => {
|
||||||
|
// Inject scripts sequentially so third-party embeds can rely on execution order.
|
||||||
|
for (const { placeholder, script } of scripts) {
|
||||||
|
if (!placeholder.parentNode) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newScript = document.createElement('script');
|
||||||
|
Array.from(script.attributes).forEach(attr => {
|
||||||
|
newScript.setAttribute(attr.name, attr.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (script.textContent) {
|
||||||
|
newScript.text = script.textContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
let done: Promise<void> = Promise.resolve();
|
||||||
|
if (newScript.src) {
|
||||||
|
done = new Promise<void>(resolve => {
|
||||||
|
newScript.onload = newScript.onerror = () => resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
placeholder.replaceWith(newScript);
|
||||||
|
await done;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const initCommentsConsent = (): void => {
|
||||||
|
// Main entry: gate comments rendering by functional cookie consent.
|
||||||
|
const placeholder = document.getElementById('comments-consent-placeholder') as HTMLElement | null;
|
||||||
|
const container = document.getElementById('comments-container') as HTMLElement | null;
|
||||||
|
const template = document.getElementById('comments-template') as HTMLTemplateElement | null;
|
||||||
|
|
||||||
|
if (!placeholder || !container || !template) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let commentsLoaded = false;
|
||||||
|
let commentsLoading = false;
|
||||||
|
|
||||||
|
const showComments = async (): Promise<void> => {
|
||||||
|
placeholder.style.display = 'none';
|
||||||
|
container.style.display = 'block';
|
||||||
|
|
||||||
|
if (commentsLoaded || commentsLoading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent duplicate template hydration while scripts are still loading.
|
||||||
|
commentsLoading = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const clone = template.content.cloneNode(true) as DocumentFragment;
|
||||||
|
const scripts = prepareDeferredScripts(clone);
|
||||||
|
|
||||||
|
container.appendChild(clone);
|
||||||
|
await activateDeferredScripts(scripts);
|
||||||
|
commentsLoaded = true;
|
||||||
|
} finally {
|
||||||
|
commentsLoading = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const hideComments = (): void => {
|
||||||
|
placeholder.style.display = 'block';
|
||||||
|
container.style.display = 'none';
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('onCookieConsentChange', (event: Event) => {
|
||||||
|
// Cross-module contract: this event is dispatched by cookies.ts.
|
||||||
|
const customEvent = event as CustomEvent<CommentsConsentState | null>;
|
||||||
|
if (hasFunctionalConsent(customEvent.detail)) {
|
||||||
|
showComments();
|
||||||
|
} else {
|
||||||
|
hideComments();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasFunctionalConsent()) {
|
||||||
|
showComments();
|
||||||
|
} else {
|
||||||
|
hideComments();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (document.readyState === 'loading') {
|
||||||
|
document.addEventListener('DOMContentLoaded', initCommentsConsent, { once: true });
|
||||||
|
} else {
|
||||||
|
initCommentsConsent();
|
||||||
|
}
|
||||||
@@ -175,6 +175,7 @@ class CookieConsent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private dispatchConsentEvent(): void {
|
private dispatchConsentEvent(): void {
|
||||||
|
// Cross-module event consumed by consent-gated features (for example commentsConsent.ts).
|
||||||
const event = new CustomEvent('onCookieConsentChange', {
|
const event = new CustomEvent('onCookieConsentChange', {
|
||||||
detail: this.state
|
detail: this.state
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -101,6 +101,10 @@ SortBy = "default"
|
|||||||
enabled = true
|
enabled = true
|
||||||
provider = "disqus"
|
provider = "disqus"
|
||||||
|
|
||||||
|
[comments.artalk]
|
||||||
|
serverUrl = ""
|
||||||
|
site = ""
|
||||||
|
|
||||||
[comments.disqusjs]
|
[comments.disqusjs]
|
||||||
shortname = ""
|
shortname = ""
|
||||||
apiUrl = ""
|
apiUrl = ""
|
||||||
|
|||||||
@@ -13,3 +13,7 @@ Cactus = [
|
|||||||
Style = "https://cdn.jsdelivr.net/npm/photoswipe@5.4.4/dist/photoswipe.css"
|
Style = "https://cdn.jsdelivr.net/npm/photoswipe@5.4.4/dist/photoswipe.css"
|
||||||
Core = "https://cdn.jsdelivr.net/npm/photoswipe@5.4.4/dist/photoswipe.esm.min.js"
|
Core = "https://cdn.jsdelivr.net/npm/photoswipe@5.4.4/dist/photoswipe.esm.min.js"
|
||||||
Lightbox = "https://cdn.jsdelivr.net/npm/photoswipe@5.4.4/dist/photoswipe-lightbox.esm.min.js"
|
Lightbox = "https://cdn.jsdelivr.net/npm/photoswipe@5.4.4/dist/photoswipe-lightbox.esm.min.js"
|
||||||
|
|
||||||
|
[Artalk]
|
||||||
|
Style = "https://cdn.jsdelivr.net/npm/artalk@2.9.1/dist/Artalk.css"
|
||||||
|
Script = "https://cdn.jsdelivr.net/npm/artalk@2.9.1/+esm"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
baseURL = "https://demo.stack.cai.im/"
|
baseURL = "https://demo.stack.cai.im/"
|
||||||
languageCode = "en-us"
|
locale = "en-us"
|
||||||
title = "Hugo Theme Stack"
|
title = "Hugo Theme Stack"
|
||||||
# Theme i18n support
|
# Theme i18n support
|
||||||
# See i18n folder for available languages
|
# See i18n folder for available languages
|
||||||
|
|||||||
@@ -1,31 +1,31 @@
|
|||||||
[en]
|
[en]
|
||||||
languageName = "English"
|
label = "English"
|
||||||
title = "Hugo Theme Stack"
|
title = "Hugo Theme Stack"
|
||||||
weight = 1
|
weight = 1
|
||||||
|
|
||||||
[en.params.sidebar]
|
[en.params.sidebar]
|
||||||
subtitle = "Card-style Hugo theme designed for bloggers"
|
subtitle = "Card-style Hugo theme designed for bloggers"
|
||||||
|
|
||||||
[zh]
|
[zh]
|
||||||
languageName = "简体中文"
|
label = "简体中文"
|
||||||
title = "Hugo 主题 Stack"
|
title = "Hugo 主题 Stack"
|
||||||
weight = 2
|
weight = 2
|
||||||
|
|
||||||
[zh.params.sidebar]
|
[zh.params.sidebar]
|
||||||
subtitle = "为博客设计的卡片式 Hugo 主题"
|
subtitle = "为博客设计的卡片式 Hugo 主题"
|
||||||
|
|
||||||
[zh-hant-tw]
|
[zh-hant-tw]
|
||||||
languageName = "正體中文"
|
label = "正體中文"
|
||||||
title = "Hugo 主題 Stack"
|
title = "Hugo 主題 Stack"
|
||||||
weight = 3
|
weight = 3
|
||||||
|
|
||||||
[zh-hant-tw.params.sidebar]
|
[zh-hant-tw.params.sidebar]
|
||||||
subtitle = "為博客設計的卡片式 Hugo 主題"
|
subtitle = "為博客設計的卡片式 Hugo 主題"
|
||||||
|
|
||||||
[ja]
|
[ja]
|
||||||
languageName = "日本語"
|
label = "日本語"
|
||||||
title = "Hugo Theme Stack"
|
title = "Hugo Theme Stack"
|
||||||
weight = 4
|
weight = 4
|
||||||
|
|
||||||
[ja.params.sidebar]
|
[ja.params.sidebar]
|
||||||
subtitle = "ブログ用のカードスタイルの Hugo テーマ"
|
subtitle = "ブログ用のカードスタイルの Hugo テーマ"
|
||||||
|
|||||||
@@ -58,7 +58,7 @@
|
|||||||
<div class="inline-meta">
|
<div class="inline-meta">
|
||||||
{{ partial "helper/icon" "language" }}
|
{{ partial "helper/icon" "language" }}
|
||||||
{{ range $Page.Translations }}
|
{{ range $Page.Translations }}
|
||||||
<a href="{{ .RelPermalink }}" class="link">{{ .Language.LanguageName }}</a>
|
<a href="{{ .RelPermalink }}" class="link">{{ .Language.Label }}</a>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
{{/*
|
||||||
|
Comments include entry.
|
||||||
|
- If functional cookie consent is required, render a placeholder + template and load commentsConsent.ts.
|
||||||
|
- Otherwise, render provider partial directly.
|
||||||
|
*/}}
|
||||||
{{ if .Site.Params.comments.enabled }}
|
{{ if .Site.Params.comments.enabled }}
|
||||||
{{- $needsConsent := and .Site.Params.cookies.enabled .Site.Params.cookies.categories.functional -}}
|
{{- $needsConsent := and .Site.Params.cookies.enabled .Site.Params.cookies.categories.functional -}}
|
||||||
{{- if $needsConsent -}}
|
{{- if $needsConsent -}}
|
||||||
@@ -8,38 +13,14 @@
|
|||||||
{{ T "cookies.managePreferences" }}
|
{{ T "cookies.managePreferences" }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="comments-container" style="display: none;">
|
<div id="comments-container" style="display: none;"></div>
|
||||||
|
<template id="comments-template">
|
||||||
{{ partial (printf "comments/provider/%s" .Site.Params.comments.provider) . }}
|
{{ partial (printf "comments/provider/%s" .Site.Params.comments.provider) . }}
|
||||||
</div>
|
</template>
|
||||||
<script>
|
{{- $opts := dict "minify" hugo.IsProduction -}}
|
||||||
(function() {
|
{{/* commentsConsent.ts is intentionally built and loaded here as an independent entry */}}
|
||||||
var placeholder = document.getElementById('comments-consent-placeholder');
|
{{- $commentsScript := resources.Get "ts/commentsConsent.ts" | js.Build $opts | fingerprint -}}
|
||||||
var container = document.getElementById('comments-container');
|
<script type="text/javascript" src="{{ $commentsScript.RelPermalink }}" integrity="{{ $commentsScript.Data.Integrity }}" defer></script>
|
||||||
|
|
||||||
function showComments() {
|
|
||||||
if (placeholder) placeholder.style.display = 'none';
|
|
||||||
if (container) container.style.display = 'block';
|
|
||||||
}
|
|
||||||
|
|
||||||
function hideComments() {
|
|
||||||
if (placeholder) placeholder.style.display = 'block';
|
|
||||||
if (container) container.style.display = 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('onCookieConsentChange', function(e) {
|
|
||||||
if (e.detail && e.detail.functional) {
|
|
||||||
showComments();
|
|
||||||
} else {
|
|
||||||
hideComments();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Check if already consented
|
|
||||||
if (window.cookieConsent && window.cookieConsent.hasConsent('functional')) {
|
|
||||||
showComments();
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
{{/* No consent required - load comments normally */}}
|
{{/* No consent required - load comments normally */}}
|
||||||
{{ partial (printf "comments/provider/%s" .Site.Params.comments.provider) . }}
|
{{ partial (printf "comments/provider/%s" .Site.Params.comments.provider) . }}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
{{- $style := resources.Get "scss/partials/comments/artalk.scss" | toCSS | minify -}}
|
||||||
|
{{- with .Site.Params.comments.artalk -}}
|
||||||
|
<link rel="stylesheet" href="{{ hugo.Data.external.Artalk.Style }}">
|
||||||
|
<link rel="stylesheet" href="{{ $style.RelPermalink }}">
|
||||||
|
|
||||||
|
<div id="Comments" class="artalk-container"></div>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
import Artalk from '{{ hugo.Data.external.Artalk.Script }}';
|
||||||
|
|
||||||
|
function isDarkMode() {
|
||||||
|
return document.documentElement.dataset.scheme === 'dark';
|
||||||
|
}
|
||||||
|
|
||||||
|
const artalkInstance = Artalk.init({
|
||||||
|
el: '#Comments',
|
||||||
|
pageKey: '{{ $.RelPermalink }}',
|
||||||
|
pageTitle: '{{ $.Title }}',
|
||||||
|
server: '{{ .serverUrl }}',
|
||||||
|
site: '{{ .site }}',
|
||||||
|
darkMode: isDarkMode(),
|
||||||
|
locale: 'auto',
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('onColorSchemeChange', (e) => {
|
||||||
|
if (!artalkInstance || typeof artalkInstance.setDarkMode !== 'function') return;
|
||||||
|
artalkInstance.setDarkMode(e.detail === 'dark');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{{- end -}}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
{{- $ThemeVersion := "4.0.0" -}}
|
{{- $ThemeVersion := "4.0.3" -}}
|
||||||
<footer class="site-footer">
|
<footer class="site-footer">
|
||||||
<section class="copyright">
|
<section class="copyright">
|
||||||
©
|
©
|
||||||
|
|||||||
@@ -14,12 +14,14 @@
|
|||||||
{{ if .Image }}
|
{{ if .Image }}
|
||||||
{{ $url := urls.Parse .Image }}
|
{{ $url := urls.Parse .Image }}
|
||||||
{{ $permalink := .Image }}
|
{{ $permalink := .Image }}
|
||||||
{{ $resource := dict
|
|
||||||
|
{{ $result = dict
|
||||||
"Resource" nil
|
"Resource" nil
|
||||||
"Permalink" $permalink
|
"Permalink" $permalink
|
||||||
"Height" nil
|
"Height" nil
|
||||||
"Width" nil
|
"Width" nil
|
||||||
}}
|
}}
|
||||||
|
{{ $resource := dict }}
|
||||||
{{ $local := true }}
|
{{ $local := true }}
|
||||||
|
|
||||||
{{ if not (in (slice "https" "http") $url.Scheme) }}
|
{{ if not (in (slice "https" "http") $url.Scheme) }}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
{{ end }}
|
{{ end }}
|
||||||
<li class="menu-bottom-section">
|
<li class="menu-bottom-section">
|
||||||
<ol class="menu">
|
<ol class="menu">
|
||||||
{{- $currentLanguageCode := .Language.Lang -}}
|
{{- $currentLanguageCode := .Language.Name -}}
|
||||||
{{ if hugo.IsMultilingual }}
|
{{ if hugo.IsMultilingual }}
|
||||||
<li id="i18n-switch">
|
<li id="i18n-switch">
|
||||||
{{ partial "helper/icon" "language" }}
|
{{ partial "helper/icon" "language" }}
|
||||||
@@ -72,11 +72,11 @@
|
|||||||
{{ range .Site.Home.AllTranslations }}
|
{{ range .Site.Home.AllTranslations }}
|
||||||
{{ $target := . }}
|
{{ $target := . }}
|
||||||
{{ range $.AllTranslations }}
|
{{ range $.AllTranslations }}
|
||||||
{{ if eq .Language.Lang $target.Language.Lang }}
|
{{ if eq .Language.Name $target.Language.Name }}
|
||||||
{{ $target = . }}
|
{{ $target = . }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
<option value="{{ $target.RelPermalink }}" {{ if eq $target.Language.Lang $currentLanguageCode }}selected{{ end }}>{{ .Language.LanguageName }}</option>
|
<option value="{{ $target.RelPermalink }}" {{ if eq $target.Language.Name $currentLanguageCode }}selected{{ end }}>{{ .Language.Label }}</option>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</select>
|
</select>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="{{ .Site.LanguageCode }}" dir="{{ default `ltr` .Language.LanguageDirection }}">
|
<html lang="{{ .Site.Language.Locale }}" dir="{{ default `ltr` .Language.Direction }}">
|
||||||
<head>
|
<head>
|
||||||
{{- partial "head/head.html" . -}}
|
{{- partial "head/head.html" . -}}
|
||||||
{{- block "head" . -}}{{ end }}
|
{{- block "head" . -}}{{ end }}
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@
|
|||||||
<link>{{ .Permalink }}</link>
|
<link>{{ .Permalink }}</link>
|
||||||
<description>Recent content {{ if ne .Title .Site.Title }}{{ with .Title }}in {{ . }} {{ end }}{{ end }}on {{ .Site.Title }}</description>
|
<description>Recent content {{ if ne .Title .Site.Title }}{{ with .Title }}in {{ . }} {{ end }}{{ end }}on {{ .Site.Title }}</description>
|
||||||
<generator>Hugo -- gohugo.io</generator>
|
<generator>Hugo -- gohugo.io</generator>
|
||||||
<language>{{ site.Language.LanguageCode }}</language>{{ with $authorEmail }}
|
<language>{{ site.Language.Locale }}</language>{{ with $authorEmail }}
|
||||||
<managingEditor>{{.}}{{ with $authorName }} ({{ . }}){{ end }}</managingEditor>{{ end }}{{ with $authorEmail }}
|
<managingEditor>{{.}}{{ with $authorName }} ({{ . }}){{ end }}</managingEditor>{{ end }}{{ with $authorEmail }}
|
||||||
<webMaster>{{ . }}{{ with $authorName }} ({{ . }}){{ end }}</webMaster>{{ end }}{{ with .Site.Copyright }}
|
<webMaster>{{ . }}{{ with $authorName }} ({{ . }}){{ end }}</webMaster>{{ end }}{{ with .Site.Copyright }}
|
||||||
<copyright>{{ . }}</copyright>{{ end }}{{ if not .Date.IsZero }}
|
<copyright>{{ . }}</copyright>{{ end }}{{ if not .Date.IsZero }}
|
||||||
|
|||||||
+1
-2
@@ -15,8 +15,7 @@
|
|||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
{{- $TOCManuallyDisabled := eq .Params.toc false -}}
|
{{- $TOCEnabled := and (default .Site.Params.article.toc .Params.toc) $TOCWidgetEnabled -}}
|
||||||
{{- $TOCEnabled := and (not $TOCManuallyDisabled) $TOCWidgetEnabled -}}
|
|
||||||
{{- $hasTOC := ge (len .TableOfContents) 100 -}}
|
{{- $hasTOC := ge (len .TableOfContents) 100 -}}
|
||||||
{{- .Scratch.Set "TOCEnabled" (and $TOCEnabled $hasTOC) -}}
|
{{- .Scratch.Set "TOCEnabled" (and $TOCEnabled $hasTOC) -}}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user