mirror of
https://github.com/CaiJimmy/hugo-theme-stack.git
synced 2025-04-29 03:53:30 +08:00
commit
dd5b966a94
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@ -1 +1 @@
|
|||||||
custom: ['https://www.buymeacoffee.com/jimmycai']
|
ko_fi: jimmycai
|
54
.github/release-drafter.yml
vendored
54
.github/release-drafter.yml
vendored
@ -1,31 +1,33 @@
|
|||||||
name-template: 'v$RESOLVED_VERSION 🌈'
|
name-template: "v$RESOLVED_VERSION 🌈"
|
||||||
tag-template: 'v$RESOLVED_VERSION'
|
tag-template: "v$RESOLVED_VERSION"
|
||||||
categories:
|
categories:
|
||||||
- title: '🚀 Features'
|
- title: "🚀 Features"
|
||||||
labels:
|
labels:
|
||||||
- 'feature'
|
- "feature"
|
||||||
- 'enhancement'
|
- "enhancement"
|
||||||
- title: '🐛 Bug Fixes'
|
- title: "🐛 Bug Fixes"
|
||||||
labels:
|
labels:
|
||||||
- 'fix'
|
- "fix"
|
||||||
- 'bugfix'
|
- "bugfix"
|
||||||
- 'bug'
|
- "bug"
|
||||||
- title: '🧰 Maintenance'
|
- title: "🧰 Maintenance"
|
||||||
label: 'chore'
|
label: "chore"
|
||||||
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
|
- title: "♻️ Refactor"
|
||||||
|
label: refactor
|
||||||
|
change-template: "- $TITLE @$AUTHOR (#$NUMBER)"
|
||||||
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
|
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
|
||||||
version-resolver:
|
version-resolver:
|
||||||
major:
|
major:
|
||||||
labels:
|
labels:
|
||||||
- 'major'
|
- "major"
|
||||||
minor:
|
minor:
|
||||||
labels:
|
labels:
|
||||||
- 'minor'
|
- "minor"
|
||||||
patch:
|
patch:
|
||||||
labels:
|
labels:
|
||||||
- 'patch'
|
- "patch"
|
||||||
default: patch
|
default: patch
|
||||||
template: |
|
template: |
|
||||||
## Changes
|
## Changes
|
||||||
|
|
||||||
$CHANGES
|
$CHANGES
|
||||||
|
17
README.md
17
README.md
@ -20,22 +20,19 @@ Stack is a simple card-style Hugo theme designed for bloggers, some of its featu
|
|||||||
- Responsive images support
|
- Responsive images support
|
||||||
- Lazy load images
|
- Lazy load images
|
||||||
- Dark mode
|
- Dark mode
|
||||||
|
- Local search
|
||||||
- [PhotoSwipe](https://photoswipe.com/) integration
|
- [PhotoSwipe](https://photoswipe.com/) integration
|
||||||
- Archive page template
|
- Archive page template
|
||||||
- Full native JavaScript, no jQuery or any other frameworks are used
|
- Full native JavaScript, no jQuery or any other frameworks are used
|
||||||
- No CSS framework, keep it simple and minimal
|
- No CSS framework, keep it simple and minimal
|
||||||
- External dependencies (like PhotoSwipe's library) are being loaded selectively, or asynchronously
|
|
||||||
- Properly cropped thumbnails
|
- Properly cropped thumbnails
|
||||||
|
- Subsection support
|
||||||
The only JavaScript library being used is [node-vibrant](https://github.com/Vibrant-Colors/node-vibrant) for generating colour schemes for articles.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
This theme uses SCSS and TypeScript. For that reason, it's necessary to use **Hugo ≥ 0.74.0**.
|
It's necessary to use **Hugo ≥ 0.78.0**.
|
||||||
|
|
||||||
Use Hugo Extended version if you want to:
|
Use Hugo Extended version (recommended) if you want to:
|
||||||
|
|
||||||
* Use the latest feature/fix from `master` branch
|
* Use the latest feature/fix from `master` branch
|
||||||
* Edit SCSS files
|
* Edit SCSS files
|
||||||
@ -46,7 +43,7 @@ Use Hugo Extended version if you want to:
|
|||||||
|
|
||||||
Clone / Download this repository to `theme` folder, and edit your site config following `exampleSite/config.toml`.
|
Clone / Download this repository to `theme` folder, and edit your site config following `exampleSite/config.toml`.
|
||||||
|
|
||||||
Check [documentation](https://www.notion.so/jimmycai/Hugo-Theme-Stack-511aec5b9ed845ce9b6e3ae0bf7fb6d4) for more details.
|
Check [documentation](https://docs.stack.jimmycai.com/) for more details.
|
||||||
|
|
||||||
## Copyright
|
## Copyright
|
||||||
|
|
||||||
@ -58,9 +55,9 @@ If you want to port this theme to another blogging platform, please let me know
|
|||||||
|
|
||||||
## Sponsoring
|
## Sponsoring
|
||||||
|
|
||||||
If you like this theme, consider supporting its development:
|
If you like this theme, give it a star, and consider supporting its development:
|
||||||
|
|
||||||
<a href="https://www.buymeacoffee.com/jimmycai" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-green.png" alt="Buy Me A Coffee" height="60px" width="217px"></a>
|
[](https://ko-fi.com/C0C530AXX)
|
||||||
|
|
||||||
Your support is greatly appreciated :)
|
Your support is greatly appreciated :)
|
||||||
|
|
||||||
|
7
assets/icons/toggle-left.svg
Normal file
7
assets/icons/toggle-left.svg
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-toggle-left" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z"/>
|
||||||
|
<circle cx="8" cy="12" r="2" />
|
||||||
|
<rect x="2" y="6" width="20" height="12" rx="6" />
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
|
After Width: | Height: | Size: 369 B |
7
assets/icons/toggle-right.svg
Normal file
7
assets/icons/toggle-right.svg
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-toggle-right" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z"/>
|
||||||
|
<circle cx="16" cy="12" r="2" />
|
||||||
|
<rect x="2" y="6" width="20" height="12" rx="6" />
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
|
After Width: | Height: | Size: 371 B |
10
assets/jsconfig.json
Normal file
10
assets/jsconfig.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"*": [
|
||||||
|
"*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -112,8 +112,6 @@ main.main {
|
|||||||
padding-top: var(--main-top-padding);
|
padding-top: var(--main-top-padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-grid {
|
.main-container {
|
||||||
@media (max-width: $on-phone) {
|
min-height: 100vh;
|
||||||
flex-direction: column;
|
}
|
||||||
}
|
|
||||||
}
|
|
@ -56,24 +56,6 @@
|
|||||||
padding: var(--card-padding);
|
padding: var(--card-padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
.article-category {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
a {
|
|
||||||
display: inline-block;
|
|
||||||
text-decoration: none;
|
|
||||||
padding: 8px 16px;
|
|
||||||
font-size: 1.4rem;
|
|
||||||
background: nth($defaultTagBackgrounds, 1);
|
|
||||||
color: nth($defaultTagColors, 1);
|
|
||||||
border-radius: var(--tag-border-radius);
|
|
||||||
|
|
||||||
@media (max-width: $on-phone) {
|
|
||||||
font-size: 1.25rem;
|
|
||||||
padding: 8px 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.article-title {
|
.article-title {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
@ -128,11 +110,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.article-category,
|
||||||
.article-tags {
|
.article-tags {
|
||||||
a {
|
a {
|
||||||
color: var(--accent-color-text);
|
color: var(--accent-color-text);
|
||||||
background-color: var(--accent-color);
|
background-color: var(--accent-color);
|
||||||
padding: 8px 18px;
|
padding: 8px 16px;
|
||||||
border-radius: var(--tag-border-radius);
|
border-radius: var(--tag-border-radius);
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
@ -193,6 +176,7 @@
|
|||||||
img {
|
img {
|
||||||
width: var(--image-size);
|
width: var(--image-size);
|
||||||
height: var(--image-size);
|
height: var(--image-size);
|
||||||
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,7 +184,7 @@
|
|||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.article-preview{
|
.article-preview {
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
color: var(--card-text-color-tertiary);
|
color: var(--card-text-color-tertiary);
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
@ -3,11 +3,6 @@
|
|||||||
* https://xyproto.github.io/splash/docs/monokai.html
|
* https://xyproto.github.io/splash/docs/monokai.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
:root {
|
|
||||||
--pre-text-color: #f8f8f2;
|
|
||||||
--pre-background-color: #272822;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Background */
|
/* Background */
|
||||||
.chroma {
|
.chroma {
|
||||||
color: #f8f8f2;
|
color: #f8f8f2;
|
@ -2,10 +2,6 @@
|
|||||||
* Style: monokailight
|
* Style: monokailight
|
||||||
* https://xyproto.github.io/splash/docs/monokailight.html
|
* https://xyproto.github.io/splash/docs/monokailight.html
|
||||||
*/
|
*/
|
||||||
:root {
|
|
||||||
--pre-text-color: #272822;
|
|
||||||
--pre-background-color: #fafafa;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Background */
|
/* Background */
|
||||||
.chroma {
|
.chroma {
|
@ -1,31 +1,3 @@
|
|||||||
.archives-group {
|
.archives-group {
|
||||||
margin-bottom: var(--section-separation);
|
margin-bottom: var(--section-separation);
|
||||||
}
|
}
|
||||||
|
|
||||||
.template-archives {
|
|
||||||
.category-list {
|
|
||||||
margin-bottom: var(--section-separation);
|
|
||||||
overflow-x: auto;
|
|
||||||
|
|
||||||
.article-list--tile {
|
|
||||||
display: flex;
|
|
||||||
padding-bottom: 15px;
|
|
||||||
|
|
||||||
article {
|
|
||||||
width: 250px;
|
|
||||||
height: 150px;
|
|
||||||
margin-right: 20px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
|
|
||||||
.article-title {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 1.8rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.article-details {
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -305,4 +305,8 @@
|
|||||||
tr:nth-child(even) {
|
tr:nth-child(even) {
|
||||||
background-color: var(--tr-even-background-color);
|
background-color: var(--tr-even-background-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.twitter-tweet {
|
||||||
|
color: var(--card-text-color-main);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.taxonomy-card {
|
.section-card {
|
||||||
border-radius: var(--card-border-radius);
|
border-radius: var(--card-border-radius);
|
||||||
background-color: var(--card-background);
|
background-color: var(--card-background);
|
||||||
padding: var(--small-card-padding);
|
padding: var(--small-card-padding);
|
||||||
@ -9,37 +9,37 @@
|
|||||||
|
|
||||||
--separation: 15px;
|
--separation: 15px;
|
||||||
|
|
||||||
.taxonomy-term {
|
.section-term {
|
||||||
font-size: 2.2rem;
|
font-size: 2.2rem;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
margin-top: calc(var(--separation) / 2);
|
margin-top: calc(var(--separation) / 2);
|
||||||
color: var(--card-text-color-main);
|
color: var(--card-text-color-main);
|
||||||
|
|
||||||
& + .taxonomy-description {
|
& + .section-description {
|
||||||
margin-top: var(--separation);
|
margin-top: var(--separation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.taxonomy-description {
|
.section-description {
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
color: var(--card-text-color-secondary);
|
color: var(--card-text-color-secondary);
|
||||||
font-size: 1.6rem;
|
font-size: 1.6rem;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.taxonomy-details {
|
.section-details {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.taxonomy-image {
|
.section-image {
|
||||||
img {
|
img {
|
||||||
width: 60px;
|
width: 60px;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.taxonomy-count {
|
.section-count {
|
||||||
color: var(--card-text-color-tertiary);
|
color: var(--card-text-color-tertiary);
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -47,3 +47,29 @@
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.subsection-list {
|
||||||
|
margin-bottom: var(--section-separation);
|
||||||
|
overflow-x: auto;
|
||||||
|
|
||||||
|
.article-list--tile {
|
||||||
|
display: flex;
|
||||||
|
padding-bottom: 15px;
|
||||||
|
|
||||||
|
article {
|
||||||
|
width: 250px;
|
||||||
|
height: 150px;
|
||||||
|
margin-right: 20px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
.article-title {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-details {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -129,6 +129,8 @@
|
|||||||
margin-top: var(--sidebar-element-separation);
|
margin-top: var(--sidebar-element-separation);
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
flex-grow: 1;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
|
||||||
@media (min-width: $on-desktop-large) {
|
@media (min-width: $on-desktop-large) {
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
@ -192,7 +194,6 @@
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: var(--body-text-color);
|
color: var(--body-text-color);
|
||||||
font-size: 1.5rem;
|
|
||||||
|
|
||||||
@media (max-width: $on-desktop-large) {
|
@media (max-width: $on-desktop-large) {
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
|
@ -134,3 +134,30 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[data-scheme="dark"] {
|
||||||
|
#dark-mode-toggle {
|
||||||
|
color: var(--accent-color);
|
||||||
|
font-weight: 700;
|
||||||
|
|
||||||
|
.icon-tabler-toggle-left {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-tabler-toggle-right {
|
||||||
|
display: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#dark-mode-toggle {
|
||||||
|
margin-top: auto;
|
||||||
|
color: var(--body-text-color);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.icon-tabler-toggle-right {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
@import "partials/base.scss";
|
@import "partials/base.scss";
|
||||||
@import "partials/layout/archives.scss";
|
@import "partials/layout/archives.scss";
|
||||||
@import "partials/layout/article.scss";
|
@import "partials/layout/article.scss";
|
||||||
@import "partials/layout/taxonomy.scss";
|
@import "partials/layout/list.scss";
|
||||||
@import "partials/layout/404.scss";
|
@import "partials/layout/404.scss";
|
||||||
@import "partials/layout/search.scss";
|
@import "partials/layout/search.scss";
|
||||||
|
|
||||||
|
@ -1,6 +1,18 @@
|
|||||||
$defaultTagBackgrounds: #8ea885, #df7988, #0177b8, #ffb900, #6b69d6;
|
$defaultTagBackgrounds: #8ea885, #df7988, #0177b8, #ffb900, #6b69d6;
|
||||||
$defaultTagColors: #fff, #fff, #fff, #fff, #fff;
|
$defaultTagColors: #fff, #fff, #fff, #fff, #fff;
|
||||||
|
|
||||||
|
[data-scheme="light"] {
|
||||||
|
--pre-text-color: #272822;
|
||||||
|
--pre-background-color: #fafafa;
|
||||||
|
@import "partials/highlight/light.scss";
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-scheme="dark"] {
|
||||||
|
--pre-text-color: #f8f8f2;
|
||||||
|
--pre-background-color: #272822;
|
||||||
|
@import "partials/highlight/dark.scss";
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Global style
|
* Global style
|
||||||
*/
|
*/
|
||||||
@ -13,7 +25,6 @@ $defaultTagColors: #fff, #fff, #fff, #fff, #fff;
|
|||||||
--main-top-padding: 50px;
|
--main-top-padding: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
--body-background: #f5f5fa;
|
--body-background: #f5f5fa;
|
||||||
|
|
||||||
--accent-color: #34495e;
|
--accent-color: #34495e;
|
||||||
@ -25,7 +36,7 @@ $defaultTagColors: #fff, #fff, #fff, #fff, #fff;
|
|||||||
|
|
||||||
--section-separation: 40px;
|
--section-separation: 40px;
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
[data-scheme="dark"] {
|
||||||
--body-background: #303030;
|
--body-background: #303030;
|
||||||
--accent-color: #ecf0f1;
|
--accent-color: #ecf0f1;
|
||||||
--accent-color-darker: #bdc3c7;
|
--accent-color-darker: #bdc3c7;
|
||||||
@ -72,7 +83,7 @@ $defaultTagColors: #fff, #fff, #fff, #fff, #fff;
|
|||||||
--small-card-padding: 25px 20px;
|
--small-card-padding: 25px 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
[data-scheme="dark"] {
|
||||||
--card-background: #424242;
|
--card-background: #424242;
|
||||||
--card-background-selected: rgba(255, 255, 255, 0.16);
|
--card-background-selected: rgba(255, 255, 255, 0.16);
|
||||||
--card-text-color-main: rgba(255, 255, 255, 0.9);
|
--card-text-color-main: rgba(255, 255, 255, 0.9);
|
||||||
@ -116,7 +127,7 @@ $defaultTagColors: #fff, #fff, #fff, #fff, #fff;
|
|||||||
--table-border-color: #dadada;
|
--table-border-color: #dadada;
|
||||||
--tr-even-background-color: #efefee;
|
--tr-even-background-color: #efefee;
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
[data-scheme="dark"] {
|
||||||
--code-background-color: #272822;
|
--code-background-color: #272822;
|
||||||
--code-text-color: rgba(255, 255, 255, 0.9);
|
--code-text-color: rgba(255, 255, 255, 0.9);
|
||||||
|
|
||||||
|
86
assets/ts/colorScheme.ts
Normal file
86
assets/ts/colorScheme.ts
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
type colorScheme = 'light' | 'dark' | 'auto';
|
||||||
|
|
||||||
|
class StackColorScheme {
|
||||||
|
private localStorageKey = 'StackColorScheme';
|
||||||
|
private currentScheme: colorScheme;
|
||||||
|
private systemPreferScheme: colorScheme;
|
||||||
|
|
||||||
|
constructor(toggleEl: HTMLElement) {
|
||||||
|
this.bindMatchMedia();
|
||||||
|
this.currentScheme = this.getSavedScheme();
|
||||||
|
|
||||||
|
if (toggleEl)
|
||||||
|
this.bindClick(toggleEl);
|
||||||
|
|
||||||
|
if (document.body.style.transition == '')
|
||||||
|
document.body.style.setProperty('transition', 'background-color .3s ease');
|
||||||
|
}
|
||||||
|
|
||||||
|
private saveScheme() {
|
||||||
|
localStorage.setItem(this.localStorageKey, this.currentScheme);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bindClick(toggleEl) {
|
||||||
|
toggleEl.addEventListener('click', (e) => {
|
||||||
|
if (this.isDark()) {
|
||||||
|
/// Disable dark mode
|
||||||
|
this.currentScheme = 'light';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.currentScheme = 'dark';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setBodyClass();
|
||||||
|
|
||||||
|
if (this.currentScheme == this.systemPreferScheme) {
|
||||||
|
/// Set to auto
|
||||||
|
this.currentScheme = 'auto';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.saveScheme();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private isDark() {
|
||||||
|
return (this.currentScheme == 'dark' || this.currentScheme == 'auto' && this.systemPreferScheme == 'dark');
|
||||||
|
}
|
||||||
|
|
||||||
|
private dispatchEvent(colorScheme: colorScheme) {
|
||||||
|
const event = new CustomEvent('onColorSchemeChange', {
|
||||||
|
detail: colorScheme
|
||||||
|
});
|
||||||
|
window.dispatchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
private setBodyClass() {
|
||||||
|
if (this.isDark()) {
|
||||||
|
document.body.dataset.scheme = 'dark';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
document.body.dataset.scheme = 'light';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dispatchEvent(document.body.dataset.scheme as colorScheme);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getSavedScheme(): colorScheme {
|
||||||
|
const savedScheme = localStorage.getItem(this.localStorageKey);
|
||||||
|
|
||||||
|
if (savedScheme == 'light' || savedScheme == 'dark' || savedScheme == 'auto') return savedScheme;
|
||||||
|
else return 'auto';
|
||||||
|
}
|
||||||
|
|
||||||
|
private bindMatchMedia() {
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
|
||||||
|
if (e.matches) {
|
||||||
|
this.systemPreferScheme = 'dark';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.systemPreferScheme = 'light';
|
||||||
|
}
|
||||||
|
this.setBodyClass();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default StackColorScheme;
|
@ -1,287 +1,132 @@
|
|||||||
import { loadScript, loadStyle } from './utils';
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
PhotoSwipe: any;
|
||||||
|
PhotoSwipeUI_Default: any
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
interface PhotoSwipeItem {
|
||||||
* Init PhotoSwipe
|
w: number;
|
||||||
* From: https://photoswipe.com/documentation/getting-started.html
|
h: number;
|
||||||
* @param gallerySelector
|
src: string;
|
||||||
*/
|
msrc: string;
|
||||||
var initPhotoSwipeFromDOM = function (gallerySelector) {
|
title?: string;
|
||||||
|
el: HTMLElement;
|
||||||
|
}
|
||||||
|
|
||||||
// parse slide data (url, title, size ...) from DOM elements
|
class StackGallery {
|
||||||
// (children of gallerySelector)
|
private galleryUID: number;
|
||||||
var parseThumbnailElements = function (el) {
|
private items: PhotoSwipeItem[] = [];
|
||||||
var thumbElements = el.childNodes,
|
|
||||||
numNodes = thumbElements.length,
|
|
||||||
items = [],
|
|
||||||
figureEl,
|
|
||||||
linkEl,
|
|
||||||
size,
|
|
||||||
item;
|
|
||||||
|
|
||||||
for (var i = 0; i < numNodes; i++) {
|
constructor(container: HTMLElement, galleryUID = 1) {
|
||||||
|
if (window.PhotoSwipe == undefined || window.PhotoSwipeUI_Default == undefined) {
|
||||||
figureEl = thumbElements[i]; // <figure> element
|
console.error("PhotoSwipe lib not loaded.");
|
||||||
|
|
||||||
// include only element nodes
|
|
||||||
if (figureEl.nodeType !== 1) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
linkEl = figureEl.children[0]; // <a> element
|
|
||||||
|
|
||||||
size = linkEl.getAttribute('data-size').split('x');
|
|
||||||
|
|
||||||
// create slide object
|
|
||||||
item = {
|
|
||||||
src: linkEl.getAttribute('href'),
|
|
||||||
w: parseInt(size[0], 10),
|
|
||||||
h: parseInt(size[1], 10)
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (figureEl.children.length > 1) {
|
|
||||||
// <figcaption> content
|
|
||||||
item.title = figureEl.children[1].innerHTML;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (linkEl.children.length > 0) {
|
|
||||||
// <img> thumbnail element, retrieving thumbnail url
|
|
||||||
item.msrc = linkEl.children[0].getAttribute('src');
|
|
||||||
}
|
|
||||||
|
|
||||||
item.el = figureEl; // save link to element for getThumbBoundsFn
|
|
||||||
items.push(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return items;
|
|
||||||
};
|
|
||||||
|
|
||||||
// find nearest parent element
|
|
||||||
var closest = function closest(el, fn) {
|
|
||||||
return el && (fn(el) ? el : closest(el.parentNode, fn));
|
|
||||||
};
|
|
||||||
|
|
||||||
// triggers when user clicks on thumbnail
|
|
||||||
var onThumbnailsClick = function (e) {
|
|
||||||
e = e || window.event;
|
|
||||||
e.preventDefault ? e.preventDefault() : e.returnValue = false;
|
|
||||||
|
|
||||||
var eTarget = e.target || e.srcElement;
|
|
||||||
|
|
||||||
// find root element of slide
|
|
||||||
var clickedListItem = closest(eTarget, function (el) {
|
|
||||||
return (el.tagName && el.tagName.toUpperCase() === 'FIGURE');
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!clickedListItem) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find index of clicked item by looping through all child nodes
|
this.galleryUID = galleryUID;
|
||||||
// alternatively, you may define index via data- attribute
|
|
||||||
var clickedGallery = clickedListItem.parentNode,
|
|
||||||
childNodes = clickedListItem.parentNode.childNodes,
|
|
||||||
numChildNodes = childNodes.length,
|
|
||||||
nodeIndex = 0,
|
|
||||||
index;
|
|
||||||
|
|
||||||
for (var i = 0; i < numChildNodes; i++) {
|
StackGallery.createGallery(container);
|
||||||
if (childNodes[i].nodeType !== 1) {
|
this.loadItems(container);
|
||||||
continue;
|
this.bindClick();
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadItems(container: HTMLElement) {
|
||||||
|
this.items = [];
|
||||||
|
|
||||||
|
const figures = container.querySelectorAll('figure');
|
||||||
|
|
||||||
|
for (const el of figures) {
|
||||||
|
const figcaption = el.querySelector('figcaption'),
|
||||||
|
img = el.querySelector('img');
|
||||||
|
|
||||||
|
let aux: PhotoSwipeItem = {
|
||||||
|
w: parseInt(img.getAttribute('width')),
|
||||||
|
h: parseInt(img.getAttribute('height')),
|
||||||
|
src: img.src,
|
||||||
|
msrc: img.getAttribute('data-thumb') || img.src,
|
||||||
|
el: el
|
||||||
}
|
}
|
||||||
|
|
||||||
if (childNodes[i] === clickedListItem) {
|
if (figcaption) {
|
||||||
index = nodeIndex;
|
aux.title = figcaption.innerHTML;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
nodeIndex++;
|
|
||||||
|
this.items.push(aux);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (index >= 0) {
|
public static createGallery(container: HTMLElement) {
|
||||||
// open PhotoSwipe if valid index found
|
const figuresEl = container.querySelectorAll('figure');
|
||||||
openPhotoSwipe(index, clickedGallery);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// parse picture index and gallery index from URL (#&pid=1&gid=2)
|
let currentGallery = [];
|
||||||
var photoswipeParseHash = function () {
|
|
||||||
var hash = window.location.hash.substring(1),
|
|
||||||
params = {};
|
|
||||||
|
|
||||||
if (hash.length < 5) {
|
for (const figure of figuresEl) {
|
||||||
return params;
|
if (!currentGallery.length) {
|
||||||
}
|
/// First iteration
|
||||||
|
currentGallery = [figure];
|
||||||
var vars = hash.split('&');
|
|
||||||
for (var i = 0; i < vars.length; i++) {
|
|
||||||
if (!vars[i]) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
var pair = vars[i].split('=');
|
else if (figure.previousElementSibling === currentGallery[currentGallery.length - 1]) {
|
||||||
if (pair.length < 2) {
|
/// Adjacent figures
|
||||||
continue;
|
currentGallery.push(figure);
|
||||||
|
}
|
||||||
|
else if (currentGallery.length) {
|
||||||
|
/// End gallery
|
||||||
|
StackGallery.wrap(currentGallery);
|
||||||
|
currentGallery = [figure];
|
||||||
}
|
}
|
||||||
params[pair[0]] = pair[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.gid) {
|
if (currentGallery.length > 0) {
|
||||||
params.gid = parseInt(params.gid, 10);
|
StackGallery.wrap(currentGallery);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return params;
|
/**
|
||||||
};
|
* Wrap adjacent figure tags with div.gallery
|
||||||
|
* @param figures
|
||||||
|
*/
|
||||||
|
public static wrap(figures: HTMLElement[]) {
|
||||||
|
const galleryContainer = document.createElement('div');
|
||||||
|
galleryContainer.className = 'gallery';
|
||||||
|
|
||||||
var openPhotoSwipe = function (index, galleryElement, disableAnimation, fromURL) {
|
const parentNode = figures[0].parentNode,
|
||||||
var pswpElement = document.querySelectorAll('.pswp')[0],
|
first = figures[0];
|
||||||
gallery,
|
|
||||||
options,
|
|
||||||
items;
|
|
||||||
|
|
||||||
items = parseThumbnailElements(galleryElement);
|
parentNode.insertBefore(galleryContainer, first)
|
||||||
|
|
||||||
// define options (if needed)
|
for (const figure of figures) {
|
||||||
options = {
|
galleryContainer.appendChild(figure);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// define gallery index (for URL)
|
public open(index: number) {
|
||||||
galleryUID: galleryElement.getAttribute('data-pswp-uid'),
|
const pswp = document.querySelector('.pswp') as HTMLDivElement;
|
||||||
|
const ps = new window.PhotoSwipe(pswp, window.PhotoSwipeUI_Default, this.items, {
|
||||||
getThumbBoundsFn: function (index) {
|
index: index,
|
||||||
// See Options -> getThumbBoundsFn section of documentation for more info
|
galleryUID: this.galleryUID,
|
||||||
var thumbnail = items[index].el.getElementsByTagName('img')[0], // find thumbnail
|
getThumbBoundsFn: (index) => {
|
||||||
|
const thumbnail = this.items[index].el.getElementsByTagName('img')[0],
|
||||||
pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
|
pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
|
||||||
rect = thumbnail.getBoundingClientRect();
|
rect = thumbnail.getBoundingClientRect();
|
||||||
|
|
||||||
return { x: rect.left, y: rect.top + pageYScroll, w: rect.width };
|
return { x: rect.left, y: rect.top + pageYScroll, w: rect.width };
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
};
|
ps.init();
|
||||||
|
|
||||||
// PhotoSwipe opened from URL
|
|
||||||
if (fromURL) {
|
|
||||||
if (options.galleryPIDs) {
|
|
||||||
// parse real index when custom PIDs are used
|
|
||||||
// http://photoswipe.com/documentation/faq.html#custom-pid-in-url
|
|
||||||
for (var j = 0; j < items.length; j++) {
|
|
||||||
if (items[j].pid == index) {
|
|
||||||
options.index = j;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// in URL indexes start from 1
|
|
||||||
options.index = parseInt(index, 10) - 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
options.index = parseInt(index, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
// exit if index not found
|
|
||||||
if (isNaN(options.index)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (disableAnimation) {
|
|
||||||
options.showAnimationDuration = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pass data to PhotoSwipe and initialize it
|
|
||||||
gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, options);
|
|
||||||
gallery.init();
|
|
||||||
};
|
|
||||||
|
|
||||||
// loop through all gallery elements and bind events
|
|
||||||
var galleryElements = document.querySelectorAll(gallerySelector);
|
|
||||||
|
|
||||||
for (var i = 0, l = galleryElements.length; i < l; i++) {
|
|
||||||
galleryElements[i].setAttribute('data-pswp-uid', i + 1);
|
|
||||||
galleryElements[i].onclick = onThumbnailsClick;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse URL and open gallery if it contains #&pid=3&gid=1
|
private bindClick() {
|
||||||
var hashData = photoswipeParseHash();
|
for (const [index, item] of this.items.entries()) {
|
||||||
if (hashData.pid && hashData.gid) {
|
const a = item.el.querySelector('a');
|
||||||
openPhotoSwipe(hashData.pid, galleryElements[hashData.gid - 1], true, true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
a.addEventListener('click', (e) => {
|
||||||
* Wrap adjacent figure tags with div.gallery, and append style
|
e.preventDefault();
|
||||||
* Reference: https://github.com/xieranmaya/blog/issues/6
|
this.open(index);
|
||||||
* @param gallery
|
})
|
||||||
*/
|
}
|
||||||
function wrap(gallery: HTMLElement[]) {
|
|
||||||
let galleryContainer = document.createElement('div');
|
|
||||||
galleryContainer.className = 'gallery';
|
|
||||||
|
|
||||||
let parentNode = gallery[0].parentNode,
|
|
||||||
first = gallery[0];
|
|
||||||
|
|
||||||
parentNode.insertBefore(galleryContainer, first)
|
|
||||||
|
|
||||||
for (let j = 0; j < gallery.length; ++j) {
|
|
||||||
const width = gallery[j].querySelector('img').width,
|
|
||||||
height = gallery[j].querySelector('img').height;
|
|
||||||
|
|
||||||
gallery[j].style.flexGrow = `${width * 100 / height}`;
|
|
||||||
gallery[j].style.flexBasis = `${width * 240 / height}px`;
|
|
||||||
|
|
||||||
galleryContainer.appendChild(gallery[j]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
export default StackGallery;
|
||||||
* Load PhotoSwipe library dynamically
|
|
||||||
*/
|
|
||||||
function loadPhotoSwipe() {
|
|
||||||
const tasks = [
|
|
||||||
loadScript("https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.js"),
|
|
||||||
loadScript("https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe-ui-default.min.js"),
|
|
||||||
loadStyle("https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.css"),
|
|
||||||
loadStyle("https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/default-skin/default-skin.min.css")
|
|
||||||
];
|
|
||||||
|
|
||||||
return Promise.all(tasks);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create gallery
|
|
||||||
* @param selector
|
|
||||||
*/
|
|
||||||
function createGallery(selector: string) {
|
|
||||||
const figures = document.querySelector(selector).querySelectorAll('figure');
|
|
||||||
|
|
||||||
if (figures.length) {
|
|
||||||
let currentGallery = [figures[0]];
|
|
||||||
for (let i = 1; i < figures.length; ++i) {
|
|
||||||
if (figures[i].previousElementSibling === currentGallery[currentGallery.length - 1]) {
|
|
||||||
/* Adjacent */
|
|
||||||
currentGallery.push(figures[i]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* End gallery */
|
|
||||||
wrap(currentGallery);
|
|
||||||
currentGallery = [figures[i]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentGallery.length > 0) {
|
|
||||||
wrap(currentGallery);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load PhotoSwipe library, and then initialize
|
|
||||||
*/
|
|
||||||
loadPhotoSwipe().then(() => {
|
|
||||||
const pswp = document.querySelector('.pswp') as HTMLDivElement;
|
|
||||||
pswp.style.removeProperty('display');
|
|
||||||
|
|
||||||
initPhotoSwipeFromDOM(`${selector} .gallery`);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
|
||||||
createGallery
|
|
||||||
}
|
|
@ -5,11 +5,11 @@
|
|||||||
* @website: https://jimmycai.com
|
* @website: https://jimmycai.com
|
||||||
* @link: https://github.com/CaiJimmy/hugo-theme-stack
|
* @link: https://github.com/CaiJimmy/hugo-theme-stack
|
||||||
*/
|
*/
|
||||||
|
import StackGallery from "ts/gallery";
|
||||||
import { createGallery } from "./gallery"
|
import { getColor } from 'ts/color';
|
||||||
import { getColor } from './color';
|
import menu from 'ts/menu';
|
||||||
import menu from './menu';
|
import createElement from 'ts/createElement';
|
||||||
import createElement from './createElement';
|
import StackColorScheme from 'ts/colorScheme';
|
||||||
|
|
||||||
let Stack = {
|
let Stack = {
|
||||||
init: () => {
|
init: () => {
|
||||||
@ -18,24 +18,11 @@ let Stack = {
|
|||||||
*/
|
*/
|
||||||
menu();
|
menu();
|
||||||
|
|
||||||
if (document.querySelector('.article-content')) {
|
const articleContent = document.querySelector('.article-content') as HTMLElement;
|
||||||
createGallery('.article-content');
|
if (articleContent) {
|
||||||
|
new StackGallery(articleContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add color to tags
|
|
||||||
*/
|
|
||||||
document.querySelectorAll('.color-tag').forEach(async (tag: HTMLLinkElement) => {
|
|
||||||
const imageURL = tag.getAttribute('data-image'),
|
|
||||||
key = tag.getAttribute('data-key'),
|
|
||||||
hash = tag.getAttribute('data-hash');
|
|
||||||
|
|
||||||
const colors = await getColor(key, hash, imageURL);
|
|
||||||
|
|
||||||
tag.style.color = colors.Vibrant.bodyTextColor;
|
|
||||||
tag.style.background = colors.Vibrant.hex;
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add linear gradient background to tile style article
|
* Add linear gradient background to tile style article
|
||||||
*/
|
*/
|
||||||
@ -66,6 +53,8 @@ let Stack = {
|
|||||||
|
|
||||||
observer.observe(articleTile)
|
observer.observe(articleTile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new StackColorScheme(document.getElementById('dark-mode-toggle'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
/**
|
|
||||||
* Load script asynchronous
|
|
||||||
* @return {Promise}
|
|
||||||
* @param url
|
|
||||||
*/
|
|
||||||
const loadScript = function (url) {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
var scriptTag = document.createElement('script');
|
|
||||||
scriptTag.src = url;
|
|
||||||
|
|
||||||
scriptTag.onload = () => {
|
|
||||||
resolve();
|
|
||||||
};
|
|
||||||
|
|
||||||
document.head.appendChild(scriptTag);
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load style asynchronous
|
|
||||||
* @return {Promise}
|
|
||||||
* @param url
|
|
||||||
*/
|
|
||||||
const loadStyle = function (url) {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
var link = document.createElement('link');
|
|
||||||
link.href = url;
|
|
||||||
|
|
||||||
link.type = "text/css";
|
|
||||||
link.rel = "stylesheet";
|
|
||||||
|
|
||||||
link.onload = () => {
|
|
||||||
resolve();
|
|
||||||
};
|
|
||||||
|
|
||||||
document.head.appendChild(link);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export {
|
|
||||||
loadScript,
|
|
||||||
loadStyle
|
|
||||||
}
|
|
@ -1,103 +0,0 @@
|
|||||||
baseurl = "https://example.com"
|
|
||||||
languageCode = "en-us"
|
|
||||||
theme = "hugo-theme-stack"
|
|
||||||
paginate = 5
|
|
||||||
title = "Example Site"
|
|
||||||
disqusShortname = "hugo-theme-stack" # Change it to your Disqus shortname before using
|
|
||||||
DefaultContentLanguage = "en" # Theme i18n support
|
|
||||||
|
|
||||||
[permalinks]
|
|
||||||
post = "/p/:slug/"
|
|
||||||
page = "/:slug/"
|
|
||||||
|
|
||||||
[params]
|
|
||||||
mainSections = ["post"]
|
|
||||||
featuredImageField = "image"
|
|
||||||
rssFullContent = true
|
|
||||||
|
|
||||||
[params.dateFormat]
|
|
||||||
published = "Jan 02, 2006"
|
|
||||||
lastUpdated = "Jan 02, 2006 15:04 MST"
|
|
||||||
|
|
||||||
[params.sidebar]
|
|
||||||
emoji = "🍥"
|
|
||||||
avatar = "img/avatar.png"
|
|
||||||
subtitle = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
|
|
||||||
|
|
||||||
[params.article]
|
|
||||||
math = false
|
|
||||||
[params.article.license]
|
|
||||||
enabled = true
|
|
||||||
default = "Licensed under CC BY-NC-SA 4.0"
|
|
||||||
|
|
||||||
[params.comments]
|
|
||||||
enabled = true
|
|
||||||
provider = "disqus" # Available: disqus, utterances
|
|
||||||
[params.comments.utterances]
|
|
||||||
repo = ""
|
|
||||||
issueTerm = "pathname"
|
|
||||||
label = "" # Optional
|
|
||||||
theme = "preferred-color-scheme"
|
|
||||||
|
|
||||||
[params.widgets]
|
|
||||||
enabled = ['search', 'archives', 'tag-cloud']
|
|
||||||
[params.widgets.archives]
|
|
||||||
limit = 5
|
|
||||||
### Archives page relative URL
|
|
||||||
path = "archives"
|
|
||||||
[params.widgets.tagCloud]
|
|
||||||
limit = 10
|
|
||||||
|
|
||||||
[params.opengraph]
|
|
||||||
[params.opengraph.twitter]
|
|
||||||
site = ""
|
|
||||||
card = "summary_large_image"
|
|
||||||
|
|
||||||
[params.defaultImage]
|
|
||||||
[params.defaultImage.opengraph]
|
|
||||||
enabled = false
|
|
||||||
local = false
|
|
||||||
src = ""
|
|
||||||
|
|
||||||
[menu]
|
|
||||||
[[menu.main]]
|
|
||||||
identifier = "home"
|
|
||||||
name = "Home"
|
|
||||||
url = "/"
|
|
||||||
weight = -100
|
|
||||||
pre = "home"
|
|
||||||
[[menu.main]]
|
|
||||||
identifier = "about-cn"
|
|
||||||
name = "About"
|
|
||||||
url = "about"
|
|
||||||
weight = -90
|
|
||||||
pre = "user"
|
|
||||||
[[menu.main]]
|
|
||||||
identifier = "archives"
|
|
||||||
name = "Archives"
|
|
||||||
url = "archives"
|
|
||||||
weight = -70
|
|
||||||
pre = "archives"
|
|
||||||
[[menu.main]]
|
|
||||||
identifier = "search"
|
|
||||||
name = "Search"
|
|
||||||
url = "search"
|
|
||||||
weight = -60
|
|
||||||
pre = "search"
|
|
||||||
|
|
||||||
[related]
|
|
||||||
includeNewer = true
|
|
||||||
threshold = 60
|
|
||||||
toLower = false
|
|
||||||
|
|
||||||
[[related.indices]]
|
|
||||||
name = "tags"
|
|
||||||
weight = 100
|
|
||||||
|
|
||||||
[[related.indices]]
|
|
||||||
name = "categories"
|
|
||||||
weight = 200
|
|
||||||
|
|
||||||
[markup]
|
|
||||||
[markup.highlight]
|
|
||||||
noClasses = false
|
|
134
exampleSite/config.yaml
Normal file
134
exampleSite/config.yaml
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
baseurl: https://example.com
|
||||||
|
languageCode: en-us
|
||||||
|
theme: hugo-theme-stack
|
||||||
|
paginate: 5
|
||||||
|
title: Example Site
|
||||||
|
|
||||||
|
# Change it to your Disqus shortname before using
|
||||||
|
disqusShortname: hugo-theme-stack
|
||||||
|
|
||||||
|
# Theme i18n support
|
||||||
|
# Available values: en, fr, id, ja, ko, pt-br, zh-cn
|
||||||
|
DefaultContentLanguage: en
|
||||||
|
|
||||||
|
permalinks:
|
||||||
|
post: /p/:slug/
|
||||||
|
page: /:slug/
|
||||||
|
|
||||||
|
params:
|
||||||
|
mainSections:
|
||||||
|
- post
|
||||||
|
featuredImageField: image
|
||||||
|
rssFullContent: true
|
||||||
|
favicon:
|
||||||
|
|
||||||
|
footer:
|
||||||
|
since: 2020
|
||||||
|
customText:
|
||||||
|
|
||||||
|
dateFormat:
|
||||||
|
published: Jan 02, 2006
|
||||||
|
lastUpdated: Jan 02, 2006 15:04 MST
|
||||||
|
|
||||||
|
sidebar:
|
||||||
|
emoji: 🍥
|
||||||
|
subtitle: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||||
|
avatar:
|
||||||
|
local: true
|
||||||
|
src: img/avatar.png
|
||||||
|
|
||||||
|
article:
|
||||||
|
math: false
|
||||||
|
license:
|
||||||
|
enabled: true
|
||||||
|
default: Licensed under CC BY-NC-SA 4.0
|
||||||
|
|
||||||
|
comments:
|
||||||
|
enabled: true
|
||||||
|
provider: disqus
|
||||||
|
utterances:
|
||||||
|
repo:
|
||||||
|
issueTerm: pathname
|
||||||
|
label:
|
||||||
|
theme: preferred-color-scheme
|
||||||
|
|
||||||
|
widgets:
|
||||||
|
enabled:
|
||||||
|
- search
|
||||||
|
- archives
|
||||||
|
- tag-cloud
|
||||||
|
|
||||||
|
archives:
|
||||||
|
limit: 5
|
||||||
|
path: archives
|
||||||
|
|
||||||
|
tagCloud:
|
||||||
|
limit: 10
|
||||||
|
|
||||||
|
opengraph:
|
||||||
|
twitter:
|
||||||
|
# Your Twitter username
|
||||||
|
site:
|
||||||
|
|
||||||
|
# Available values: summary, summary_large_image
|
||||||
|
card: summary_large_image
|
||||||
|
|
||||||
|
defaultImage:
|
||||||
|
opengraph:
|
||||||
|
enabled: false
|
||||||
|
local: false
|
||||||
|
src:
|
||||||
|
|
||||||
|
colorScheme:
|
||||||
|
# Display toggle
|
||||||
|
toggle: true
|
||||||
|
|
||||||
|
# Available values: auto, light, dark
|
||||||
|
default: auto
|
||||||
|
|
||||||
|
imageProcessing:
|
||||||
|
cover:
|
||||||
|
enabled: true
|
||||||
|
content:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
menu:
|
||||||
|
main:
|
||||||
|
- identifier: home
|
||||||
|
name: Home
|
||||||
|
url: /
|
||||||
|
weight: -100
|
||||||
|
pre: home
|
||||||
|
|
||||||
|
- identifier: about
|
||||||
|
name: About
|
||||||
|
url: about
|
||||||
|
weight: -90
|
||||||
|
pre: user
|
||||||
|
|
||||||
|
- identifier: archives
|
||||||
|
name: Archives
|
||||||
|
url: archives
|
||||||
|
weight: -70
|
||||||
|
pre: archives
|
||||||
|
|
||||||
|
- identifier: search
|
||||||
|
name: Search
|
||||||
|
url: search
|
||||||
|
weight: -60
|
||||||
|
pre: search
|
||||||
|
|
||||||
|
related:
|
||||||
|
includeNewer: true
|
||||||
|
threshold: 60
|
||||||
|
toLower: false
|
||||||
|
indices:
|
||||||
|
- name: tags
|
||||||
|
weight: 100
|
||||||
|
|
||||||
|
- name: categories
|
||||||
|
weight: 200
|
||||||
|
|
||||||
|
markup:
|
||||||
|
highlight:
|
||||||
|
noClasses: false
|
@ -3,4 +3,7 @@ title: "Test"
|
|||||||
description: "This is a example category"
|
description: "This is a example category"
|
||||||
slug: "test"
|
slug: "test"
|
||||||
image: "hutomo-abrianto-l2jk-uxb1BY-unsplash.jpg"
|
image: "hutomo-abrianto-l2jk-uxb1BY-unsplash.jpg"
|
||||||
|
style:
|
||||||
|
background: "#2a9d8f"
|
||||||
|
color: "#fff"
|
||||||
---
|
---
|
41
i18n/en.toml
41
i18n/en.toml
@ -1,41 +0,0 @@
|
|||||||
[toggleMenu]
|
|
||||||
other = "Toggle Menu"
|
|
||||||
|
|
||||||
[relatedContents]
|
|
||||||
other = "Related contents"
|
|
||||||
|
|
||||||
[lastUpdatedOn]
|
|
||||||
other ="Last updated on"
|
|
||||||
|
|
||||||
[widgetArchivesTitle]
|
|
||||||
other = "Archives"
|
|
||||||
|
|
||||||
[widgetArchivesMore]
|
|
||||||
other = "More"
|
|
||||||
|
|
||||||
[widgetTagCloudTitle]
|
|
||||||
other = "Tags"
|
|
||||||
|
|
||||||
[categoriesTitle]
|
|
||||||
other = "Categories"
|
|
||||||
|
|
||||||
[notFoundTitle]
|
|
||||||
other = "Not Found"
|
|
||||||
|
|
||||||
[notFoundSubtitle]
|
|
||||||
other = "This page does not exist."
|
|
||||||
|
|
||||||
[searchTitle]
|
|
||||||
other = "Search"
|
|
||||||
|
|
||||||
[searchPlaceholder]
|
|
||||||
other = "Type something..."
|
|
||||||
|
|
||||||
[searchResultTitle]
|
|
||||||
other = "#PAGES_COUNT pages (#TIME_SECONDS seconds)"
|
|
||||||
|
|
||||||
[footerBuiltWith]
|
|
||||||
other = "Built with {{ .Generator }}"
|
|
||||||
|
|
||||||
[footerDesignedBy]
|
|
||||||
other = "Theme {{ .Theme }} designed by {{ .DesignedBy }}"
|
|
57
i18n/en.yaml
Normal file
57
i18n/en.yaml
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
toggleMenu:
|
||||||
|
other: Toggle Menu
|
||||||
|
|
||||||
|
darkMode:
|
||||||
|
other: Dark Mode
|
||||||
|
|
||||||
|
list:
|
||||||
|
page:
|
||||||
|
one: "{{ .Count }} page"
|
||||||
|
other: "{{ .Count }} pages"
|
||||||
|
|
||||||
|
section:
|
||||||
|
other: Section
|
||||||
|
|
||||||
|
subsection:
|
||||||
|
one: Subsection
|
||||||
|
other: Subsections
|
||||||
|
|
||||||
|
archives:
|
||||||
|
categories:
|
||||||
|
other: Categories
|
||||||
|
|
||||||
|
article:
|
||||||
|
relatedContents:
|
||||||
|
other: Related contents
|
||||||
|
lastUpdatedOn:
|
||||||
|
other: Last updated on
|
||||||
|
|
||||||
|
notFound:
|
||||||
|
title:
|
||||||
|
other: Not Found
|
||||||
|
subtitle:
|
||||||
|
other: This page does not exist.
|
||||||
|
|
||||||
|
widget:
|
||||||
|
archives:
|
||||||
|
title:
|
||||||
|
other: Archives
|
||||||
|
more:
|
||||||
|
other: More
|
||||||
|
tagCloud:
|
||||||
|
title:
|
||||||
|
other: Tags
|
||||||
|
|
||||||
|
search:
|
||||||
|
title:
|
||||||
|
other: Search
|
||||||
|
placeholder:
|
||||||
|
other: Type something...
|
||||||
|
resultTitle:
|
||||||
|
other: "#PAGES_COUNT pages (#TIME_SECONDS seconds)"
|
||||||
|
|
||||||
|
footer:
|
||||||
|
builtWith:
|
||||||
|
other: Built with {{ .Generator }}
|
||||||
|
designedBy:
|
||||||
|
other: Theme {{ .Theme }} designed by {{ .DesignedBy }}
|
38
i18n/fr.toml
38
i18n/fr.toml
@ -1,38 +0,0 @@
|
|||||||
[toggleMenu]
|
|
||||||
other = "Afficher le menu"
|
|
||||||
|
|
||||||
[relatedContents]
|
|
||||||
other = "Contenus liés"
|
|
||||||
|
|
||||||
[lastUpdatedOn]
|
|
||||||
other = "Dernière mise à jour le"
|
|
||||||
|
|
||||||
[widgetArchivesTitle]
|
|
||||||
other = "Archives"
|
|
||||||
|
|
||||||
[widgetArchivesMore]
|
|
||||||
other = "Autres"
|
|
||||||
|
|
||||||
[widgetTagCloudTitle]
|
|
||||||
other = "Mots clés"
|
|
||||||
|
|
||||||
[notFoundTitle]
|
|
||||||
other = "Page non trouvée"
|
|
||||||
|
|
||||||
[notFoundSubtitle]
|
|
||||||
other = "Cette page n'existe pas."
|
|
||||||
|
|
||||||
[searchTitle]
|
|
||||||
other = "Rechercher"
|
|
||||||
|
|
||||||
[searchPlaceholder]
|
|
||||||
other = "Cherchez un article, une publication, etc."
|
|
||||||
|
|
||||||
[searchResultTitle]
|
|
||||||
other = "#PAGES_COUNT pages (#TIME_SECONDS secondes)"
|
|
||||||
|
|
||||||
[footerBuiltWith]
|
|
||||||
other = "Généré avec {{ .Generator }}"
|
|
||||||
|
|
||||||
[footerDesignedBy]
|
|
||||||
other = "Thème {{ .Theme }} conçu par {{ .DesignedBy }}"
|
|
38
i18n/fr.yaml
Normal file
38
i18n/fr.yaml
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
toggleMenu:
|
||||||
|
other: Afficher le menu
|
||||||
|
|
||||||
|
article:
|
||||||
|
relatedContents:
|
||||||
|
other: Contenus liés
|
||||||
|
lastUpdatedOn:
|
||||||
|
other: Dernière mise à jour le
|
||||||
|
|
||||||
|
notFound:
|
||||||
|
title:
|
||||||
|
other: Page non trouvée
|
||||||
|
subtitle:
|
||||||
|
other: Cette page n'existe pas.
|
||||||
|
|
||||||
|
widget:
|
||||||
|
archives:
|
||||||
|
title:
|
||||||
|
other: Archives
|
||||||
|
more:
|
||||||
|
other: Autres
|
||||||
|
tagCloud:
|
||||||
|
title:
|
||||||
|
other: Mots clés
|
||||||
|
|
||||||
|
search:
|
||||||
|
title:
|
||||||
|
other: Rechercher
|
||||||
|
placeholder:
|
||||||
|
other: Cherchez un article, une publication, etc.
|
||||||
|
resultTitle:
|
||||||
|
other: "#PAGES_COUNT pages (#TIME_SECONDS secondes)"
|
||||||
|
|
||||||
|
footer:
|
||||||
|
builtWith:
|
||||||
|
other: Généré avec {{ .Generator }}
|
||||||
|
designedBy:
|
||||||
|
other: Thème {{ .Theme }} conçu par {{ .DesignedBy }}
|
38
i18n/id.yaml
Normal file
38
i18n/id.yaml
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
toggleMenu:
|
||||||
|
other: Tampilkan Menu
|
||||||
|
|
||||||
|
article:
|
||||||
|
relatedContents:
|
||||||
|
other: Konten terkait
|
||||||
|
lastUpdatedOn:
|
||||||
|
other: Terakhir diperbarui pada
|
||||||
|
|
||||||
|
notFound:
|
||||||
|
title:
|
||||||
|
other: Not Found
|
||||||
|
subtitle:
|
||||||
|
other: Halaman ini tidak ada.
|
||||||
|
|
||||||
|
widget:
|
||||||
|
archives:
|
||||||
|
title:
|
||||||
|
other: Arsip
|
||||||
|
more:
|
||||||
|
other: Lebih
|
||||||
|
tagCloud:
|
||||||
|
title:
|
||||||
|
other: Tag
|
||||||
|
|
||||||
|
search:
|
||||||
|
title:
|
||||||
|
other: Cari
|
||||||
|
placeholder:
|
||||||
|
other: Ketik sesuatu...
|
||||||
|
resultTitle:
|
||||||
|
other: "#PAGES_COUNT halaman (#TIME_SECONDS detik)"
|
||||||
|
|
||||||
|
footer:
|
||||||
|
builtWith:
|
||||||
|
other: Dibangun dengan {{ .Generator }}
|
||||||
|
designedBy:
|
||||||
|
other: Tema {{ .Theme }} dirancang oleh {{ .DesignedBy }}
|
23
i18n/ja.toml
23
i18n/ja.toml
@ -1,23 +0,0 @@
|
|||||||
[toggleMenu]
|
|
||||||
other = "メニューを開く・閉じる"
|
|
||||||
|
|
||||||
[relatedContents]
|
|
||||||
other = "関連するコンテンツ"
|
|
||||||
|
|
||||||
[lastUpdatedOn]
|
|
||||||
other = "最終更新"
|
|
||||||
|
|
||||||
[widgetArchivesTitle]
|
|
||||||
other = "アーカイブ"
|
|
||||||
|
|
||||||
[widgetArchivesMore]
|
|
||||||
other = "さらに見る"
|
|
||||||
|
|
||||||
[widgetTagCloudTitle]
|
|
||||||
other = "タグ"
|
|
||||||
|
|
||||||
[notFoundTitle]
|
|
||||||
other = "404 Not Found"
|
|
||||||
|
|
||||||
[notFoundSubtitle]
|
|
||||||
other = "指定されたページは存在しません。"
|
|
39
i18n/ja.yaml
Normal file
39
i18n/ja.yaml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
toggleMenu:
|
||||||
|
other: メニューを開く・閉じる
|
||||||
|
|
||||||
|
darkMode:
|
||||||
|
other: ダークモード
|
||||||
|
|
||||||
|
archives:
|
||||||
|
categories:
|
||||||
|
other: 分類
|
||||||
|
|
||||||
|
article:
|
||||||
|
relatedContents:
|
||||||
|
other: 関連するコンテンツ
|
||||||
|
lastUpdatedOn:
|
||||||
|
other: 最終更新
|
||||||
|
|
||||||
|
notFound:
|
||||||
|
title:
|
||||||
|
other: 404 Not Found
|
||||||
|
subtitle:
|
||||||
|
other: 指定されたページは存在しません。
|
||||||
|
|
||||||
|
widget:
|
||||||
|
archives:
|
||||||
|
title:
|
||||||
|
other: アーカイブ
|
||||||
|
more:
|
||||||
|
other: さらに見る
|
||||||
|
tagCloud:
|
||||||
|
title:
|
||||||
|
other: タグ
|
||||||
|
|
||||||
|
search:
|
||||||
|
title:
|
||||||
|
other: サーチ
|
||||||
|
placeholder:
|
||||||
|
other: 入力...
|
||||||
|
resultTitle:
|
||||||
|
other: "#PAGES_COUNT 件 (#TIME_SECONDS 秒)"
|
38
i18n/ko.toml
38
i18n/ko.toml
@ -1,38 +0,0 @@
|
|||||||
[toggleMenu]
|
|
||||||
other = "메뉴 여닫기"
|
|
||||||
|
|
||||||
[relatedContents]
|
|
||||||
other = "관련 글"
|
|
||||||
|
|
||||||
[lastUpdatedOn]
|
|
||||||
other ="마지막 수정: "
|
|
||||||
|
|
||||||
[widgetArchivesTitle]
|
|
||||||
other = "보관함"
|
|
||||||
|
|
||||||
[widgetArchivesMore]
|
|
||||||
other = "더보기"
|
|
||||||
|
|
||||||
[widgetTagCloudTitle]
|
|
||||||
other = "태그"
|
|
||||||
|
|
||||||
[notFoundTitle]
|
|
||||||
other = "찾을 수 없음"
|
|
||||||
|
|
||||||
[notFoundSubtitle]
|
|
||||||
other = "페이지를 찾을 수 없습니다."
|
|
||||||
|
|
||||||
[searchTitle]
|
|
||||||
other = "검색"
|
|
||||||
|
|
||||||
[searchPlaceholder]
|
|
||||||
other = "검색어를 입력하세요..."
|
|
||||||
|
|
||||||
[searchResultTitle]
|
|
||||||
other = "#PAGES_COUNT 페이지 (#TIME_SECONDS 초)"
|
|
||||||
|
|
||||||
[footerBuiltWith]
|
|
||||||
other = "{{ .Generator }}로 만듦"
|
|
||||||
|
|
||||||
[footerDesignedBy]
|
|
||||||
other = "{{ .DesignedBy }}의 {{ .Theme }} 테마 사용 중"
|
|
38
i18n/ko.yaml
Normal file
38
i18n/ko.yaml
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
toggleMenu:
|
||||||
|
other: 메뉴 여닫기
|
||||||
|
|
||||||
|
article:
|
||||||
|
relatedContents:
|
||||||
|
other: 관련 글
|
||||||
|
lastUpdatedOn:
|
||||||
|
other: "마지막 수정: "
|
||||||
|
|
||||||
|
notFound:
|
||||||
|
title:
|
||||||
|
other: 찾을 수 없음
|
||||||
|
subtitle:
|
||||||
|
other: 페이지를 찾을 수 없습니다.
|
||||||
|
|
||||||
|
widget:
|
||||||
|
archives:
|
||||||
|
title:
|
||||||
|
other: 보관함
|
||||||
|
more:
|
||||||
|
other: 더보기
|
||||||
|
tagCloud:
|
||||||
|
title:
|
||||||
|
other: 태그
|
||||||
|
|
||||||
|
search:
|
||||||
|
title:
|
||||||
|
other: 검색
|
||||||
|
placeholder:
|
||||||
|
other: 검색어를 입력하세요...
|
||||||
|
resultTitle:
|
||||||
|
other: "#PAGES_COUNT 페이지 (#TIME_SECONDS 초)"
|
||||||
|
|
||||||
|
footer:
|
||||||
|
builtWith:
|
||||||
|
other: "{{ .Generator }}로 만듦"
|
||||||
|
designedBy:
|
||||||
|
other: "{{ .DesignedBy }}의 {{ .Theme }} 테마 사용 중"
|
@ -1,41 +0,0 @@
|
|||||||
[toggleMenu]
|
|
||||||
other = "Alternar Menu"
|
|
||||||
|
|
||||||
[relatedContents]
|
|
||||||
other = "Conteúdos Relacionados"
|
|
||||||
|
|
||||||
[lastUpdatedOn]
|
|
||||||
other ="Última atualização em"
|
|
||||||
|
|
||||||
[widgetArchivesTitle]
|
|
||||||
other = "Arquivos"
|
|
||||||
|
|
||||||
[widgetArchivesMore]
|
|
||||||
other = "Mais"
|
|
||||||
|
|
||||||
[widgetTagCloudTitle]
|
|
||||||
other = "Tags"
|
|
||||||
|
|
||||||
[categoriesTitle]
|
|
||||||
other = "Categorias"
|
|
||||||
|
|
||||||
[notFoundTitle]
|
|
||||||
other = "Não Encontrado"
|
|
||||||
|
|
||||||
[notFoundSubtitle]
|
|
||||||
other = "Esta página não existe."
|
|
||||||
|
|
||||||
[searchTitle]
|
|
||||||
other = "Busca"
|
|
||||||
|
|
||||||
[searchPlaceholder]
|
|
||||||
other = "Digite algo..."
|
|
||||||
|
|
||||||
[searchResultTitle]
|
|
||||||
other = "#PAGES_COUNT páginas (#TIME_SECONDS segundos)"
|
|
||||||
|
|
||||||
[footerBuiltWith]
|
|
||||||
other = "Criado com {{ .Generator }}"
|
|
||||||
|
|
||||||
[footerDesignedBy]
|
|
||||||
other = "Tema {{ .Theme }} desenvolvido por {{ .DesignedBy }}"
|
|
42
i18n/pt-BR.yaml
Normal file
42
i18n/pt-BR.yaml
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
toggleMenu:
|
||||||
|
other: Alternar Menu
|
||||||
|
|
||||||
|
archives:
|
||||||
|
categories:
|
||||||
|
other: Categorias
|
||||||
|
|
||||||
|
article:
|
||||||
|
relatedContents:
|
||||||
|
other: Conteúdos Relacionados
|
||||||
|
lastUpdatedOn:
|
||||||
|
other: Última atualização em
|
||||||
|
|
||||||
|
notFound:
|
||||||
|
title:
|
||||||
|
other: Não Encontrado
|
||||||
|
subtitle:
|
||||||
|
other: Esta página não existe.
|
||||||
|
|
||||||
|
widget:
|
||||||
|
archives:
|
||||||
|
title:
|
||||||
|
other: Arquivos
|
||||||
|
more:
|
||||||
|
other: Mais
|
||||||
|
tagCloud:
|
||||||
|
title:
|
||||||
|
other: Tags
|
||||||
|
|
||||||
|
search:
|
||||||
|
title:
|
||||||
|
other: Busca
|
||||||
|
placeholder:
|
||||||
|
other: Digite algo...
|
||||||
|
resultTitle:
|
||||||
|
other: "#PAGES_COUNT páginas (#TIME_SECONDS segundos)"
|
||||||
|
|
||||||
|
footer:
|
||||||
|
builtWith:
|
||||||
|
other: Criado com {{ .Generator }}
|
||||||
|
designedBy:
|
||||||
|
other: Tema {{ .Theme }} desenvolvido por {{ .DesignedBy }}
|
61
i18n/ru.yaml
Normal file
61
i18n/ru.yaml
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
toggleMenu:
|
||||||
|
other: Показать/скрыть меню
|
||||||
|
|
||||||
|
darkMode:
|
||||||
|
other: Тёмный режим
|
||||||
|
|
||||||
|
list:
|
||||||
|
page:
|
||||||
|
one: "{{ .Count }} страница"
|
||||||
|
few: "{{ .Count }} страницы"
|
||||||
|
many: "{{ .Count }} страниц"
|
||||||
|
other: "{{ .Count }} страниц"
|
||||||
|
|
||||||
|
section:
|
||||||
|
other: Разделы
|
||||||
|
|
||||||
|
subsection:
|
||||||
|
one: Подраздел
|
||||||
|
few: Подраздела
|
||||||
|
many: Подразделов
|
||||||
|
other: Подразделов
|
||||||
|
|
||||||
|
archives:
|
||||||
|
categories:
|
||||||
|
other: Категории
|
||||||
|
|
||||||
|
article:
|
||||||
|
relatedContents:
|
||||||
|
other: Также рекомендуем
|
||||||
|
lastUpdatedOn:
|
||||||
|
other: Обновлено
|
||||||
|
|
||||||
|
notFound:
|
||||||
|
title:
|
||||||
|
other: Не найшено
|
||||||
|
subtitle:
|
||||||
|
other: Запрашиваемая страница не существует
|
||||||
|
|
||||||
|
widget:
|
||||||
|
archives:
|
||||||
|
title:
|
||||||
|
other: Архивы
|
||||||
|
more:
|
||||||
|
other: Ещё
|
||||||
|
tagCloud:
|
||||||
|
title:
|
||||||
|
other: Теги
|
||||||
|
|
||||||
|
search:
|
||||||
|
title:
|
||||||
|
other: Поиск
|
||||||
|
placeholder:
|
||||||
|
other: Введите что-нибудь...
|
||||||
|
resultTitle:
|
||||||
|
other: "Найдено #PAGES_COUNT страниц (за #TIME_SECONDS с.)"
|
||||||
|
|
||||||
|
footer:
|
||||||
|
builtWith:
|
||||||
|
other: Создано при помощи {{ .Generator }}
|
||||||
|
designedBy:
|
||||||
|
other: Тема {{ .Theme }} дизайн {{ .DesignedBy }}
|
57
i18n/tr.yaml
Normal file
57
i18n/tr.yaml
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
toggleMenu:
|
||||||
|
other: Menüyü Gizle
|
||||||
|
|
||||||
|
darkMode:
|
||||||
|
other: Koyu Mod
|
||||||
|
|
||||||
|
list:
|
||||||
|
page:
|
||||||
|
one: "{{ .Count }} makale"
|
||||||
|
other: "{{ .Count }} makale"
|
||||||
|
|
||||||
|
section:
|
||||||
|
other: Bölüm
|
||||||
|
|
||||||
|
subsection:
|
||||||
|
one: Alt bölüm
|
||||||
|
other: Alt bölümler
|
||||||
|
|
||||||
|
archives:
|
||||||
|
categories:
|
||||||
|
other: Kategoriler
|
||||||
|
|
||||||
|
article:
|
||||||
|
relatedContents:
|
||||||
|
other: Alakalı içerikler
|
||||||
|
lastUpdatedOn:
|
||||||
|
other: Son güncelleme
|
||||||
|
|
||||||
|
notFound:
|
||||||
|
title:
|
||||||
|
other: Bulunamadı
|
||||||
|
subtitle:
|
||||||
|
other: Aradığınız sayfa mevcut değil.
|
||||||
|
|
||||||
|
widget:
|
||||||
|
archives:
|
||||||
|
title:
|
||||||
|
other: Arşiv
|
||||||
|
more:
|
||||||
|
other: Daha fazla
|
||||||
|
tagCloud:
|
||||||
|
title:
|
||||||
|
other: Etiketler
|
||||||
|
|
||||||
|
search:
|
||||||
|
title:
|
||||||
|
other: Arama
|
||||||
|
placeholder:
|
||||||
|
other: Birşeyler yazın...
|
||||||
|
resultTitle:
|
||||||
|
other: "#PAGES_COUNT sayfa (#TIME_SECONDS saniye)"
|
||||||
|
|
||||||
|
footer:
|
||||||
|
builtWith:
|
||||||
|
other: "{{ .Generator }} ile oluşturuldu."
|
||||||
|
designedBy:
|
||||||
|
other: "{{ .Theme }} teması {{ .DesignedBy }} tarafından tasarlandı"
|
@ -1,32 +0,0 @@
|
|||||||
[toggleMenu]
|
|
||||||
other = "切换菜单"
|
|
||||||
|
|
||||||
[relatedContents]
|
|
||||||
other = "相关文章"
|
|
||||||
|
|
||||||
[lastUpdatedOn]
|
|
||||||
other ="最后更新于"
|
|
||||||
|
|
||||||
[widgetArchivesTitle]
|
|
||||||
other = "归档"
|
|
||||||
|
|
||||||
[widgetArchivesMore]
|
|
||||||
other = "更多"
|
|
||||||
|
|
||||||
[widgetTagCloudTitle]
|
|
||||||
other = "标签云"
|
|
||||||
|
|
||||||
[notFoundTitle]
|
|
||||||
other = "404 错误"
|
|
||||||
|
|
||||||
[notFoundSubtitle]
|
|
||||||
other = "页面不存在"
|
|
||||||
|
|
||||||
[searchTitle]
|
|
||||||
other = "搜索"
|
|
||||||
|
|
||||||
[searchPlaceholder]
|
|
||||||
other = "输入关键词..."
|
|
||||||
|
|
||||||
[searchResultTitle]
|
|
||||||
other = "#PAGES_COUNT 个结果 (用时 #TIME_SECONDS 秒)"
|
|
39
i18n/zh-CN.yaml
Normal file
39
i18n/zh-CN.yaml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
toggleMenu:
|
||||||
|
other: 切换菜单
|
||||||
|
|
||||||
|
darkMode:
|
||||||
|
other: 暗色模式
|
||||||
|
|
||||||
|
archives:
|
||||||
|
categories:
|
||||||
|
other: 分类
|
||||||
|
|
||||||
|
article:
|
||||||
|
relatedContents:
|
||||||
|
other: 相关文章
|
||||||
|
lastUpdatedOn:
|
||||||
|
other: 最后更新于
|
||||||
|
|
||||||
|
notFound:
|
||||||
|
title:
|
||||||
|
other: 404 错误
|
||||||
|
subtitle:
|
||||||
|
other: 页面不存在
|
||||||
|
|
||||||
|
widget:
|
||||||
|
archives:
|
||||||
|
title:
|
||||||
|
other: 归档
|
||||||
|
more:
|
||||||
|
other: 更多
|
||||||
|
tagCloud:
|
||||||
|
title:
|
||||||
|
other: 标签云
|
||||||
|
|
||||||
|
search:
|
||||||
|
title:
|
||||||
|
other: 搜索
|
||||||
|
placeholder:
|
||||||
|
other: 输入关键词...
|
||||||
|
resultTitle:
|
||||||
|
other: "#PAGES_COUNT 个结果 (用时 #TIME_SECONDS 秒)"
|
@ -1,7 +1,7 @@
|
|||||||
{{ define "main" }}
|
{{ define "main" }}
|
||||||
<div class="not-found-card">
|
<div class="not-found-card">
|
||||||
<h1 class="article-title">{{ T "notFoundTitle" }}</h1>
|
<h1 class="article-title">{{ T "notFound.title" }}</h1>
|
||||||
<h2 class="article-subtitle">{{ T "notFoundSubtitle" }}</h2>
|
<h2 class="article-subtitle">{{ T "notFound.subtitle" }}</h2>
|
||||||
</div>
|
</div>
|
||||||
{{ partialCached "footer/footer" . }}
|
{{ partialCached "footer/footer" . }}
|
||||||
{{ end }}
|
{{ end }}
|
@ -1,19 +1,27 @@
|
|||||||
{{- $image := .Page.Resources.GetMatch (printf "%s" (.Destination | safeURL)) -}}
|
{{- $image := .Page.Resources.GetMatch (printf "%s" (.Destination | safeURL)) -}}
|
||||||
{{- if $image -}}
|
{{- if $image -}}
|
||||||
{{- $small := $image.Resize "480x" -}}
|
|
||||||
{{- $big := $image.Resize "1024x" -}}
|
|
||||||
{{- $alt := .PlainText | safeHTML -}}
|
{{- $alt := .PlainText | safeHTML -}}
|
||||||
{{- $caption := "" -}}
|
<figure style="flex-grow: {{ div (mul $image.Width 100) $image.Height }}; flex-basis: {{ div (mul $image.Width 240) $image.Height }}px">
|
||||||
{{- with $alt -}}
|
|
||||||
{{- $caption = . | safeHTML -}}
|
|
||||||
{{- end -}}
|
|
||||||
<figure>
|
|
||||||
<a href="{{ $image.RelPermalink }}" data-size="{{ $image.Width }}x{{ $image.Height }}">
|
<a href="{{ $image.RelPermalink }}" data-size="{{ $image.Width }}x{{ $image.Height }}">
|
||||||
<img srcset="{{ $small.RelPermalink }} 480w, {{ $big.RelPermalink }} 1024w"
|
{{- $Permalink := $image.RelPermalink -}}
|
||||||
src="{{ $image.RelPermalink }}" width="{{ $image.Width }}" height="{{ $image.Height }}" loading="lazy"
|
{{- $Width := $image.Width -}}
|
||||||
alt="{{ if $alt }}{{ $alt }}{{ else if $caption }}{{ $caption | markdownify | plainify }}{{ else }} {{ end }}">
|
{{- $Height := $image.Height -}}
|
||||||
|
{{- $Srcset := "" -}}
|
||||||
|
|
||||||
|
{{- if (default true .Page.Site.Params.imageProcessing.content.enabled) -}}
|
||||||
|
{{- $small := $image.Resize "480x" -}}
|
||||||
|
{{- $big := $image.Resize "1024x" -}}
|
||||||
|
{{- $Srcset = printf "%s 480w, %s 1024w" $small.RelPermalink $big.RelPermalink -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
<img src="{{ $Permalink }}"
|
||||||
|
{{ with $Srcset }}srcset="{{ . }}"{{ end }}
|
||||||
|
width="{{ $Width }}"
|
||||||
|
height="{{ $Height }}"
|
||||||
|
loading="lazy"
|
||||||
|
{{ with $alt }}alt="{{ . }}"{{ end }}>
|
||||||
</a>
|
</a>
|
||||||
{{ with $caption }}
|
{{ with $alt }}
|
||||||
<figcaption>{{ . | markdownify }}</figcaption>
|
<figcaption>{{ . | markdownify }}</figcaption>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</figure>
|
</figure>
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
{{ define "main" }}
|
{{ define "main" }}
|
||||||
{{ $categories := ($.Site.GetPage "taxonomyTerm" "categories").Pages }}
|
{{ $categories := ($.Site.GetPage "taxonomyTerm" "categories").Pages }}
|
||||||
{{ if $categories }}
|
{{ if $categories }}
|
||||||
<h2 class="section-title">{{ T "categoriesTitle" }}</h2>
|
<h2 class="section-title">{{ T "archives.categories" }}</h2>
|
||||||
<div class="category-list">
|
<div class="subsection-list">
|
||||||
<div class="article-list--tile">
|
<div class="article-list--tile">
|
||||||
{{ range $categories }}
|
{{ range $categories }}
|
||||||
{{ partial "article-list/tile" (dict "context" . "size" "250x150" "Type" "taxonomy") }}
|
{{ partial "article-list/tile" (dict "context" . "size" "250x150" "Type" "taxonomy") }}
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
{{- block "head" . -}}{{ end }}
|
{{- block "head" . -}}{{ end }}
|
||||||
</head>
|
</head>
|
||||||
<body class="{{ block `body-class` . }}{{ end }}">
|
<body class="{{ block `body-class` . }}{{ end }}">
|
||||||
<div class="container flex on-phone--column align-items--flex-start {{ if .Site.Params.widgets.enabled }}extended{{ else }}compact{{ end }} {{ block `container-class` . }}{{end}}">
|
{{- partial "head/colorScheme" . -}}
|
||||||
|
<div class="container main-container flex on-phone--column {{ if .Site.Params.widgets.enabled }}extended{{ else }}compact{{ end }} {{ block `container-class` . }}{{end}}">
|
||||||
{{ partial "sidebar/left.html" . }}
|
{{ partial "sidebar/left.html" . }}
|
||||||
<main class="main full-width">
|
<main class="main full-width">
|
||||||
{{- block "main" . }}{{- end }}
|
{{- block "main" . }}{{- end }}
|
||||||
|
@ -1,10 +1,63 @@
|
|||||||
{{ define "main" }}
|
{{ define "main" }}
|
||||||
<div class="widget">
|
<h3 class="section-title">
|
||||||
<h3 class="widget-title">{{ .Title }}</h3>
|
{{ if eq .Parent (.GetPage "/") }}
|
||||||
|
{{ T "list.section" }}
|
||||||
|
{{ else }}
|
||||||
|
{{ .Parent.Title }}
|
||||||
|
{{ end }}
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div class="section-card">
|
||||||
|
<div class="section-details">
|
||||||
|
<h3 class="section-count">{{ T "list.page" (len .Pages) }}</h3>
|
||||||
|
<h1 class="section-term">{{ .Title }}</h1>
|
||||||
|
{{ with .Params.description }}
|
||||||
|
<h2 class="section-description">{{ . }}</h2>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{- $image := partialCached "helper/image" (dict "Context" . "Type" "section") .RelPermalink "section" -}}
|
||||||
|
{{ if $image.exists }}
|
||||||
|
<div class="section-image">
|
||||||
|
{{ if $image.resource }}
|
||||||
|
{{- $Permalink := $image.resource.RelPermalink -}}
|
||||||
|
{{- $Width := $image.resource.Width -}}
|
||||||
|
{{- $Height := $image.resource.Height -}}
|
||||||
|
|
||||||
|
{{- if (default true .Page.Site.Params.imageProcessing.cover.enabled) -}}
|
||||||
|
{{- $thumbnail := $image.resource.Fill "120x120" -}}
|
||||||
|
{{- $Permalink = $thumbnail.RelPermalink -}}
|
||||||
|
{{- $Width = $thumbnail.Width -}}
|
||||||
|
{{- $Height = $thumbnail.Height -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
<img src="{{ $Permalink }}"
|
||||||
|
width="{{ $Width }}"
|
||||||
|
height="{{ $Height }}"
|
||||||
|
loading="lazy">
|
||||||
|
{{ else }}
|
||||||
|
<img src="{{ $image.permalink }}" loading="lazy" />
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{ $subsections := .Sections }}
|
||||||
|
{{ with $subsections }}
|
||||||
|
<h2 class="section-title">{{ T "list.subsection" (len $subsections) }}</h2>
|
||||||
|
<div class="subsection-list">
|
||||||
|
<div class="article-list--tile">
|
||||||
|
{{ range . }}
|
||||||
|
{{ partial "article-list/tile" (dict "context" . "size" "250x150" "Type" "section") }}
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{/* List only pages that are not a subsection */}}
|
||||||
|
{{ $paginator := .Paginate (.Pages | complement $subsections) }}
|
||||||
<section class="article-list--compact">
|
<section class="article-list--compact">
|
||||||
{{ range .Paginator.Pages }}
|
{{ range $paginator.Pages }}
|
||||||
{{ partial "article-list/compact" . }}
|
{{ partial "article-list/compact" . }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</section>
|
</section>
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
{{ define "main" }}
|
|
||||||
<h3 class="taxonomy-type section-title">{{ .Type | singularize | humanize }}</h3>
|
|
||||||
<div class="taxonomy-card">
|
|
||||||
<div class="taxonomy-details">
|
|
||||||
<h3 class="taxonomy-count">{{ len .Pages }} post{{ if gt (len .Pages) 1 }}s{{ end }}</h3>
|
|
||||||
<h1 class="taxonomy-term">{{ .Title }}</h1>
|
|
||||||
{{ with .Params.description }}
|
|
||||||
<h2 class="taxonomy-description">{{ . }}</h2>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{- $image := partialCached "helper/image" (dict "Context" . "Type" "taxonomy") .RelPermalink "taxonomy" -}}
|
|
||||||
{{ if $image.exists }}
|
|
||||||
<div class="taxonomy-image">
|
|
||||||
{{ if $image.resource }}
|
|
||||||
{{- $thumbnail := $image.resource.Fill "120x120" -}}
|
|
||||||
<img src="{{ $thumbnail.RelPermalink }}" width="{{ $thumbnail.Width }}"
|
|
||||||
height="{{ $thumbnail.Height }}" loading="lazy">
|
|
||||||
{{ else }}
|
|
||||||
<img src="{{ $image.permalink }}" loading="lazy">
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<section class="article-list--compact">
|
|
||||||
{{ $v2 := where .Pages "Params.hidden" "!=" true }}
|
|
||||||
{{ $pag := .Paginate (.Pages) }}
|
|
||||||
{{ range $pag.Pages }}
|
|
||||||
{{ partial "article-list/compact" . }}
|
|
||||||
{{ end }}
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{{- partial "pagination.html" . -}}
|
|
||||||
|
|
||||||
{{ partialCached "footer/footer" . }}
|
|
||||||
{{ end }}
|
|
@ -11,7 +11,7 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
{{- partial "pagination.html" . -}}
|
{{- partial "pagination.html" . -}}
|
||||||
{{ partialCached "footer/footer" . }}
|
{{- partial "footer/footer" . -}}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{ define "right-sidebar" }}
|
{{ define "right-sidebar" }}
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
{{ define "main" }}
|
{{ define "main" }}
|
||||||
<form action="{{ .Permalink }}" class="search-form"{{ with .OutputFormats.Get "json" -}} data-json="{{ .Permalink }}"{{- end }}>
|
<form action="{{ .Permalink }}" class="search-form"{{ with .OutputFormats.Get "json" -}} data-json="{{ .Permalink }}"{{- end }}>
|
||||||
<p>
|
<p>
|
||||||
<label>{{ T "searchTitle" }}</label>
|
<label>{{ T "search.title" }}</label>
|
||||||
<input name="keyword" placeholder="{{ T `searchPlaceholder` }}" />
|
<input name="keyword" placeholder="{{ T `search.placeholder` }}" />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<button title="Search">
|
<button title="Search">
|
||||||
@ -20,7 +20,7 @@
|
|||||||
<div class="search-result--list article-list--compact"></div>
|
<div class="search-result--list article-list--compact"></div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.searchResultTitleTemplate = "{{ T `searchResultTitle` }}"
|
window.searchResultTitleTemplate = "{{ T `search.resultTitle` }}"
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{{- $opts := dict "minify" hugo.IsProduction "JSXFactory" "createElement" -}}
|
{{- $opts := dict "minify" hugo.IsProduction "JSXFactory" "createElement" -}}
|
||||||
|
@ -8,11 +8,17 @@
|
|||||||
{{- $data := dict "title" .Title "date" .Date "permalink" .Permalink "content" (.Plain) -}}
|
{{- $data := dict "title" .Title "date" .Date "permalink" .Permalink "content" (.Plain) -}}
|
||||||
|
|
||||||
{{- $image := partialCached "helper/image" (dict "Context" . "Type" "articleList") .RelPermalink "articleList" -}}
|
{{- $image := partialCached "helper/image" (dict "Context" . "Type" "articleList") .RelPermalink "articleList" -}}
|
||||||
{{- if and $image.exists $image.resource -}}
|
{{- if $image.exists -}}
|
||||||
{{- $thumbnail := $image.resource.Fill "120x120" -}}
|
{{- $imagePermalink := "" -}}
|
||||||
{{- $image := dict "image" (absURL $thumbnail.Permalink) -}}
|
{{- if and $image.resource (default true .Page.Site.Params.imageProcessing.cover.enabled) -}}
|
||||||
{{- $data = merge $data $image -}}
|
{{- $thumbnail := $image.resource.Fill "120x120" -}}
|
||||||
{{ end }}
|
{{- $imagePermalink = (absURL $thumbnail.Permalink) -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- $imagePermalink = $image.permalink -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- $data = merge $data (dict "image" (absURL $imagePermalink)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
{{- $result = $result | append $data -}}
|
{{- $result = $result | append $data -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
@ -15,9 +15,21 @@
|
|||||||
{{ if $image.exists }}
|
{{ if $image.exists }}
|
||||||
<div class="article-image">
|
<div class="article-image">
|
||||||
{{ if $image.resource }}
|
{{ if $image.resource }}
|
||||||
{{- $thumbnail := $image.resource.Fill "120x120" -}}
|
{{- $Permalink := $image.resource.RelPermalink -}}
|
||||||
<img src="{{ $thumbnail.RelPermalink }}" width="{{ $thumbnail.Width }}"
|
{{- $Width := $image.resource.Width -}}
|
||||||
height="{{ $thumbnail.Height }}" loading="lazy">
|
{{- $Height := $image.resource.Height -}}
|
||||||
|
|
||||||
|
{{- if (default true .Page.Site.Params.imageProcessing.cover.enabled) -}}
|
||||||
|
{{- $thumbnail := $image.resource.Fill "120x120" -}}
|
||||||
|
{{- $Permalink = $thumbnail.RelPermalink -}}
|
||||||
|
{{- $Width = $thumbnail.Width -}}
|
||||||
|
{{- $Height = $thumbnail.Height -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
<img src="{{ $Permalink }}"
|
||||||
|
width="{{ $Width }}"
|
||||||
|
height="{{ $Height }}"
|
||||||
|
loading="lazy">
|
||||||
{{ else }}
|
{{ else }}
|
||||||
<img src="{{ $image.permalink }}" loading="lazy" alt="Featured image of post {{ .Title }}" />
|
<img src="{{ $image.permalink }}" loading="lazy" alt="Featured image of post {{ .Title }}" />
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
@ -1,22 +1,4 @@
|
|||||||
{{ $image := partialCached "helper/image" (dict "Context" . "Type" "articleList") .RelPermalink "articleList" }}
|
{{ $image := partialCached "helper/image" (dict "Context" . "Type" "articleList") .RelPermalink "articleList" }}
|
||||||
<article class="{{ if $image.exists }}has-image{{ end }}">
|
<article class="{{ if $image.exists }}has-image{{ end }}">
|
||||||
{{ if $image.exists }}
|
{{ partial "article/components/header" . }}
|
||||||
<div class="article-image">
|
|
||||||
<a href="{{ .RelPermalink }}">
|
|
||||||
{{ if $image.resource }}
|
|
||||||
{{- $thumbnail := $image.resource.Fill "800x250" -}}
|
|
||||||
{{- $thumbnailRetina := $image.resource.Fill "1600x500" -}}
|
|
||||||
|
|
||||||
<img src="{{ $thumbnail.RelPermalink }}"
|
|
||||||
srcset="{{ $thumbnail.RelPermalink }} 800w, {{ $thumbnailRetina.RelPermalink }} 1600w"
|
|
||||||
width="{{ $thumbnail.Width }}" height="{{ $thumbnail.Height }}" loading="lazy"
|
|
||||||
alt="Featured image of post {{ .Title }}" />
|
|
||||||
{{ else }}
|
|
||||||
<img src="{{ $image.permalink }}" loading="lazy" alt="Featured image of post {{ .Title }}" />
|
|
||||||
{{ end }}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ partialCached "article/components/details" . .RelPermalink }}
|
|
||||||
</article>
|
</article>
|
@ -6,10 +6,23 @@
|
|||||||
<div class="article-image">
|
<div class="article-image">
|
||||||
{{ if $image.resource }}
|
{{ if $image.resource }}
|
||||||
{{- $imageRaw := $image.resource | resources.Fingerprint "md5" -}}
|
{{- $imageRaw := $image.resource | resources.Fingerprint "md5" -}}
|
||||||
{{- $thumbnail := $imageRaw.Fill .size -}}
|
{{- $Permalink := $imageRaw.RelPermalink -}}
|
||||||
|
{{- $Width := $imageRaw.Width -}}
|
||||||
|
{{- $Height := $imageRaw.Height -}}
|
||||||
|
|
||||||
<img src="{{ $thumbnail.RelPermalink }}" width="{{ $thumbnail.Width }}" height="{{ $thumbnail.Height }}"
|
{{- if (default true .Page.Site.Params.imageProcessing.cover.enabled) -}}
|
||||||
loading="lazy" data-key="{{ .context.Slug }}" data-hash="{{ $imageRaw.Data.Integrity }}">
|
{{- $thumbnail := $imageRaw.Fill .size -}}
|
||||||
|
{{- $Permalink = $thumbnail.RelPermalink -}}
|
||||||
|
{{- $Width = $thumbnail.Width -}}
|
||||||
|
{{- $Height = $thumbnail.Height -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
<img src="{{ $Permalink }}"
|
||||||
|
width="{{ $Width }}"
|
||||||
|
height="{{ $Height }}"
|
||||||
|
loading="lazy"
|
||||||
|
data-key="{{ .context.Slug }}"
|
||||||
|
data-hash="{{ $imageRaw.Data.Integrity }}">
|
||||||
{{ else }}
|
{{ else }}
|
||||||
<img src="{{ $image.permalink }}" loading="lazy" data-key="{{ .context.Slug }}" data-hash="{{ $image.permalink }}"/>
|
<img src="{{ $image.permalink }}" loading="lazy" data-key="{{ .context.Slug }}" data-hash="{{ $image.permalink }}"/>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
@ -1,22 +1,10 @@
|
|||||||
{{ $image := partialCached "helper/image" (dict "Context" . "Type" "article") .RelPermalink "article" }}
|
|
||||||
{{- $context := . -}}
|
|
||||||
<div class="article-details">
|
<div class="article-details">
|
||||||
{{ if .Params.categories }}
|
{{ if .Params.categories }}
|
||||||
<header class="article-category">
|
<header class="article-category">
|
||||||
{{ range (.GetTerms "categories") }}
|
{{ range (.GetTerms "categories") }}
|
||||||
{{ if and $image.exists $image.resource }}
|
<a href="{{ .RelPermalink }}" {{ with .Params.style }}style="background-color: {{ .background }}; color: {{ .color }};"{{ end }}>
|
||||||
{{- $imageRaw := $image.resource | resources.Fingerprint "md5" -}}
|
{{ .LinkTitle }}
|
||||||
{{- $20x := $imageRaw.Fill "20x20 smart" -}}
|
</a>
|
||||||
<a href="{{ .RelPermalink }}"
|
|
||||||
class="color-tag"
|
|
||||||
data-image="{{ $20x.RelPermalink }}"
|
|
||||||
data-key="{{ $context.Slug }}"
|
|
||||||
data-hash="{{ $imageRaw.Data.Integrity }}">
|
|
||||||
{{ .LinkTitle }}
|
|
||||||
</a>
|
|
||||||
{{ else }}
|
|
||||||
<a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a>
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</header>
|
</header>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<section class="article-time">
|
<section class="article-time">
|
||||||
{{ partial "helper/icon" "clock" }}
|
{{ partial "helper/icon" "clock" }}
|
||||||
<span class="article-time--modified">
|
<span class="article-time--modified">
|
||||||
{{ T "lastUpdatedOn" }} {{ .Lastmod.Format ( or .Site.Params.dateFormat.lastUpdated "Jan 02, 2006 15:04 MST" ) }}
|
{{ T "article.lastUpdatedOn" }} {{ .Lastmod.Format ( or .Site.Params.dateFormat.lastUpdated "Jan 02, 2006 15:04 MST" ) }}
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
@ -2,16 +2,32 @@
|
|||||||
{{- $image := partialCached "helper/image" (dict "Context" . "Type" "article") .RelPermalink "article" -}}
|
{{- $image := partialCached "helper/image" (dict "Context" . "Type" "article") .RelPermalink "article" -}}
|
||||||
{{ if $image.exists }}
|
{{ if $image.exists }}
|
||||||
<div class="article-image">
|
<div class="article-image">
|
||||||
{{ if $image.resource }}
|
<a href="{{ .RelPermalink }}">
|
||||||
{{- $tablet := $image.resource.Resize "1024x" -}}
|
{{ if $image.resource }}
|
||||||
{{- $desktop := $image.resource.Resize "2000x" -}}
|
{{- $Permalink := $image.resource.RelPermalink -}}
|
||||||
|
{{- $Width := $image.resource.Width -}}
|
||||||
|
{{- $Height := $image.resource.Height -}}
|
||||||
|
{{- $Srcset := "" -}}
|
||||||
|
|
||||||
|
{{- if (default true .Page.Site.Params.imageProcessing.cover.enabled) -}}
|
||||||
|
{{- $thumbnail := $image.resource.Resize "800x" -}}
|
||||||
|
{{- $thumbnailRetina := $image.resource.Resize "1600x" -}}
|
||||||
|
{{- $Srcset = printf "%s 800w, %s 1600w" $thumbnail.RelPermalink $thumbnailRetina.RelPermalink -}}
|
||||||
|
{{- $Permalink = $thumbnail.RelPermalink -}}
|
||||||
|
{{- $Width = $thumbnail.Width -}}
|
||||||
|
{{- $Height = $thumbnail.Height -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
<img srcset="{{ $tablet.RelPermalink }} 1024w, {{ $desktop.RelPermalink }} 2000w"
|
<img src="{{ $Permalink }}"
|
||||||
src="{{ $desktop.RelPermalink }}" width="{{ $image.resource.Width }}" height="{{ $image.resource.Height }}" loading="lazy"
|
{{ with $Srcset }}srcset="{{ . }}"{{ end }}
|
||||||
alt="Featured image of post {{ .Title }}" />
|
width="{{ $Width }}"
|
||||||
{{ else }}
|
height="{{ $Height }}"
|
||||||
<img src="{{ $image.permalink }}" loading="lazy" alt="Featured image of post {{ .Title }}" />
|
loading="lazy"
|
||||||
{{ end }}
|
alt="Featured image of post {{ .Title }}" />
|
||||||
|
{{ else }}
|
||||||
|
<img src="{{ $image.permalink }}" loading="lazy" alt="Featured image of post {{ .Title }}" />
|
||||||
|
{{ end }}
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
@ -5,4 +5,17 @@
|
|||||||
crossorigin="anonymous"></script>
|
crossorigin="anonymous"></script>
|
||||||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js"
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js"
|
||||||
integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"
|
integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"
|
||||||
onload="renderMathInElement(document.querySelector(`.article-content`));"></script>
|
onload="StackLaTeX()"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function StackLaTeX() {
|
||||||
|
renderMathInElement(document.querySelector(`.article-content`), {
|
||||||
|
delimiters: [
|
||||||
|
{ left: "$$", right: "$$", display: true },
|
||||||
|
{ left: "$", right: "$", display: false },
|
||||||
|
{ left: "\\(", right: "\\)", display: false },
|
||||||
|
{ left: "\\[", right: "\\]", display: true }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
@ -1,5 +1,5 @@
|
|||||||
<!-- Root element of PhotoSwipe. Must have class pswp. -->
|
<!-- Root element of PhotoSwipe. Must have class pswp. -->
|
||||||
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true" style="display:none">
|
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
|
||||||
|
|
||||||
<!-- Background of PhotoSwipe.
|
<!-- Background of PhotoSwipe.
|
||||||
It's a separate element as animating opacity is faster than rgba(). -->
|
It's a separate element as animating opacity is faster than rgba(). -->
|
||||||
@ -63,4 +63,10 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe-ui-default.min.js"></script>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/default-skin/default-skin.css">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.css">
|
@ -1,7 +1,7 @@
|
|||||||
<aside class="related-contents--wrapper">
|
<aside class="related-contents--wrapper">
|
||||||
{{ $related := (where (.Site.RegularPages.Related .) "Params.hidden" "!=" true) | first 5 }}
|
{{ $related := (where (.Site.RegularPages.Related .) "Params.hidden" "!=" true) | first 5 }}
|
||||||
{{ with $related }}
|
{{ with $related }}
|
||||||
<h2 class="section-title">{{ T "relatedContents" }}</h2>
|
<h2 class="section-title">{{ T "article.relatedContents" }}</h2>
|
||||||
<div class="related-contents">
|
<div class="related-contents">
|
||||||
<div class="flex article-list--tile">
|
<div class="flex article-list--tile">
|
||||||
{{ range . }}
|
{{ range . }}
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
{{- $light := resources.Get "css/highlight/light.css" | minify -}}
|
|
||||||
{{- $dark := resources.Get "css/highlight/dark.css" | minify -}}
|
|
||||||
<link rel="stylesheet" href="{{ $light.RelPermalink }}" media="(prefers-color-scheme: light)">
|
|
||||||
<link rel="stylesheet" href="{{ $dark.RelPermalink }}" media="(prefers-color-scheme: dark)">
|
|
@ -1,12 +1,23 @@
|
|||||||
{{- $ThemeVersion := "1.1.0" -}}
|
{{- $ThemeVersion := "2.0.1" -}}
|
||||||
<footer class="site-footer">
|
<footer class="site-footer">
|
||||||
<section class="copyright">© {{ now.Format "2006" }} {{ .Site.Title }}</section>
|
<section class="copyright">
|
||||||
|
©
|
||||||
|
{{ if and (.Site.Params.footer.since) (ne .Site.Params.footer.since (int (now.Format "2006"))) }}
|
||||||
|
{{ .Site.Params.footer.since }} -
|
||||||
|
{{ end }}
|
||||||
|
{{ now.Format "2006" }} {{ .Site.Title }}
|
||||||
|
</section>
|
||||||
|
|
||||||
<section class="powerby">
|
<section class="powerby">
|
||||||
|
{{ with .Site.Params.footer.customText }}
|
||||||
|
{{ . | safeHTML }} <br/>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
{{- $Generator := `<a href="https://gohugo.io/" target="_blank" rel="noopener">Hugo</a>` -}}
|
{{- $Generator := `<a href="https://gohugo.io/" target="_blank" rel="noopener">Hugo</a>` -}}
|
||||||
{{- $Theme := printf `<b><a href="https://github.com/CaiJimmy/hugo-theme-stack" target="_blank" rel="noopener" data-version="%s">Stack</a></b>` $ThemeVersion -}}
|
{{- $Theme := printf `<b><a href="https://github.com/CaiJimmy/hugo-theme-stack" target="_blank" rel="noopener" data-version="%s">Stack</a></b>` $ThemeVersion -}}
|
||||||
{{- $DesignedBy := `<a href="https://jimmycai.com" target="_blank" rel="noopener">Jimmy</a>` -}}
|
{{- $DesignedBy := `<a href="https://jimmycai.com" target="_blank" rel="noopener">Jimmy</a>` -}}
|
||||||
|
|
||||||
{{ T "footerBuiltWith" (dict "Generator" $Generator) | safeHTML }} <br />
|
{{ T "footer.builtWith" (dict "Generator" $Generator) | safeHTML }} <br />
|
||||||
{{ T "footerDesignedBy" (dict "Theme" $Theme "DesignedBy" $DesignedBy) | safeHTML }}
|
{{ T "footer.designedBy" (dict "Theme" $Theme "DesignedBy" $DesignedBy) | safeHTML }}
|
||||||
</section>
|
</section>
|
||||||
</footer>
|
</footer>
|
@ -1,4 +1,3 @@
|
|||||||
{{ partialCached "footer/components/script.html" . }}
|
{{ partialCached "footer/components/script.html" . }}
|
||||||
{{ partialCached "footer/components/custom-font.html" . }}
|
{{ partialCached "footer/components/custom-font.html" . }}
|
||||||
{{ partialCached "footer/components/highlight.html" . }}
|
|
||||||
{{ partial "footer/custom.html" . }}
|
{{ partial "footer/custom.html" . }}
|
39
layouts/partials/head/colorScheme.html
Normal file
39
layouts/partials/head/colorScheme.html
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
{{- $defaultColorScheme := default "auto" .Site.Params.colorScheme.default -}}
|
||||||
|
{{- if not (default false .Site.Params.colorScheme.toggle) -}}
|
||||||
|
{{/* If toggle is disabled, force default scheme */}}
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
const colorSchemeKey = 'StackColorScheme';
|
||||||
|
localStorage.setItem(colorSchemeKey, "{{ $defaultColorScheme }}");
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
{{- else -}}
|
||||||
|
{{/* Otherwise set to default scheme only if no preference is set by user */}}
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
const colorSchemeKey = 'StackColorScheme';
|
||||||
|
if(!localStorage.getItem(colorSchemeKey)){
|
||||||
|
localStorage.setItem(colorSchemeKey, "{{ $defaultColorScheme }}");
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
const colorSchemeKey = 'StackColorScheme';
|
||||||
|
const colorSchemeItem = localStorage.getItem(colorSchemeKey);
|
||||||
|
const supportDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches === true;
|
||||||
|
|
||||||
|
if (colorSchemeItem == 'dark' || colorSchemeItem === 'auto' && supportDarkMode) {
|
||||||
|
/**
|
||||||
|
* Enable dark mode if:
|
||||||
|
* 1. If dark mode is set already (in local storage)
|
||||||
|
* 2. Auto mode & prefere color scheme is dark
|
||||||
|
*/
|
||||||
|
document.body.dataset.scheme = 'dark';
|
||||||
|
} else {
|
||||||
|
document.body.dataset.scheme = 'light';
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
@ -17,4 +17,8 @@
|
|||||||
<link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" href="{{ .Permalink | safeURL }}">
|
<link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" href="{{ .Permalink | safeURL }}">
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
|
{{ with .Site.Params.favicon }}
|
||||||
|
<link rel="shortcut icon" href="{{ . }}" />
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
{{- partial "head/custom.html" . -}}
|
{{- partial "head/custom.html" . -}}
|
@ -6,35 +6,35 @@
|
|||||||
<meta property='og:url' content='{{ .Permalink }}'>
|
<meta property='og:url' content='{{ .Permalink }}'>
|
||||||
<meta property='og:site_name' content='{{ .Site.Title }}'>
|
<meta property='og:site_name' content='{{ .Site.Title }}'>
|
||||||
<meta property='og:type' content='
|
<meta property='og:type' content='
|
||||||
{{- if .IsPage -}}
|
{{- if .IsPage -}}
|
||||||
article
|
article
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
website
|
website
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
'>
|
'>
|
||||||
|
|
||||||
{{- with .Params.locale -}}
|
{{- with .Params.locale -}}
|
||||||
<meta property='og:locale' content='{{ . }}'>
|
<meta property='og:locale' content='{{ . }}'>
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
{{- if .IsPage -}}
|
{{- if .IsPage -}}
|
||||||
<meta property='article:section' content='{{ .Section | title }}' />
|
<meta property='article:section' content='{{ .Section | title }}' />
|
||||||
{{- range .Params.tags -}}
|
{{- range .Params.tags -}}
|
||||||
<meta property='article:tag' content='{{ . }}' />
|
<meta property='article:tag' content='{{ . }}' />
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
{{- if .IsPage -}}
|
{{- if .IsPage -}}
|
||||||
{{- if not .Date.IsZero -}}
|
{{- if not .Date.IsZero -}}
|
||||||
<meta property='article:published_time' content='{{ .Date.Format "2006-01-02T15:04:05-07:00" | safeHTML }}'/>
|
<meta property='article:published_time' content='{{ .Date.Format "2006-01-02T15:04:05-07:00" | safeHTML }}'/>
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- if not .Lastmod.IsZero -}}
|
{{- if not .Lastmod.IsZero -}}
|
||||||
<meta property='article:modified_time' content='{{ .Lastmod.Format "2006-01-02T15:04:05-07:00" | safeHTML }}'/>
|
<meta property='article:modified_time' content='{{ .Lastmod.Format "2006-01-02T15:04:05-07:00" | safeHTML }}'/>
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
{{- if not .Site.LastChange.IsZero -}}
|
{{- if not .Site.LastChange.IsZero -}}
|
||||||
<meta property='og:updated_time' content='{{ .Site.LastChange.Format " 2006-01-02T15:04:05-07:00 " | safeHTML }}'/>
|
<meta property='og:updated_time' content='{{ .Site.LastChange.Format " 2006-01-02T15:04:05-07:00 " | safeHTML }}'/>
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
{{ $image := partialCached "helper/image" (dict "Context" . "Type" "opengraph") .RelPermalink "opengraph" }}
|
{{ $image := partialCached "helper/image" (dict "Context" . "Type" "opengraph") .RelPermalink "opengraph" }}
|
||||||
|
@ -10,6 +10,6 @@
|
|||||||
|
|
||||||
{{- $image := partialCached "helper/image" (dict "Context" . "Type" "opengraph") .RelPermalink "opengraph" -}}
|
{{- $image := partialCached "helper/image" (dict "Context" . "Type" "opengraph") .RelPermalink "opengraph" -}}
|
||||||
{{- if $image.exists -}}
|
{{- if $image.exists -}}
|
||||||
<meta name="twitter:card" content="{{ .Site.Params.opengraph.twitter.card }}">
|
<meta name="twitter:card" content="{{ default `summary_large_image` .Site.Params.opengraph.twitter.card }}">
|
||||||
<meta name="twitter:image" content='{{ absURL $image.permalink }}' />
|
<meta name="twitter:image" content='{{ absURL $image.permalink }}' />
|
||||||
{{- end -}}
|
{{- end -}}
|
@ -8,14 +8,18 @@
|
|||||||
<header class="site-info">
|
<header class="site-info">
|
||||||
{{ with .Site.Params.sidebar.avatar }}
|
{{ with .Site.Params.sidebar.avatar }}
|
||||||
<figure class="site-avatar">
|
<figure class="site-avatar">
|
||||||
{{ $avatar := resources.Get (.) }}
|
{{ if not .local }}
|
||||||
|
<img src="{{ .src }}" width="300" height="300" class="site-logo" loading="lazy" alt="Avatar">
|
||||||
{{ if $avatar }}
|
|
||||||
{{ $avatarResized := $avatar.Resize "300x300" }}
|
|
||||||
<img src="{{ $avatarResized.RelPermalink }}" width="{{ $avatarResized.Width }}"
|
|
||||||
height="{{ $avatarResized.Height }}" class="site-logo" loading="lazy" alt="Avatar">
|
|
||||||
{{ else }}
|
{{ else }}
|
||||||
{{ errorf "Failed loading avatar from %q" . }}
|
{{ $avatar := resources.Get (.src) }}
|
||||||
|
|
||||||
|
{{ if $avatar }}
|
||||||
|
{{ $avatarResized := $avatar.Resize "300x" }}
|
||||||
|
<img src="{{ $avatarResized.RelPermalink }}" width="{{ $avatarResized.Width }}"
|
||||||
|
height="{{ $avatarResized.Height }}" class="site-logo" loading="lazy" alt="Avatar">
|
||||||
|
{{ else }}
|
||||||
|
{{ errorf "Failed loading avatar from %q" . }}
|
||||||
|
{{ end }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{ with $.Site.Params.sidebar.emoji }}
|
{{ with $.Site.Params.sidebar.emoji }}
|
||||||
@ -41,5 +45,13 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
{{ if (default false .Site.Params.colorScheme.toggle) }}
|
||||||
|
<li id="dark-mode-toggle">
|
||||||
|
{{ partial "helper/icon" "toggle-left" }}
|
||||||
|
{{ partial "helper/icon" "toggle-right" }}
|
||||||
|
<span>{{ T "darkMode" }}</span>
|
||||||
|
</li>
|
||||||
|
{{ end }}
|
||||||
</ol>
|
</ol>
|
||||||
</aside>
|
</aside>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div class="widget-icon">
|
<div class="widget-icon">
|
||||||
{{ partial "helper/icon" "infinity" }}
|
{{ partial "helper/icon" "infinity" }}
|
||||||
</div>
|
</div>
|
||||||
<h2 class="widget-title section-title">{{ T "widgetArchivesTitle" }}</h2>
|
<h2 class="widget-title section-title">{{ T "widget.archives.title" }}</h2>
|
||||||
|
|
||||||
{{ $pages := where .Site.RegularPages "Type" "in" .Site.Params.mainSections }}
|
{{ $pages := where .Site.RegularPages "Type" "in" .Site.Params.mainSections }}
|
||||||
{{ $notHidden := where .Site.RegularPages "Params.hidden" "!=" true }}
|
{{ $notHidden := where .Site.RegularPages "Params.hidden" "!=" true }}
|
||||||
@ -15,7 +15,7 @@
|
|||||||
<div class="archives-year">
|
<div class="archives-year">
|
||||||
<a href="{{ $.Site.Params.widgets.archives.path | relLangURL }}#{{ $id }}">
|
<a href="{{ $.Site.Params.widgets.archives.path | relLangURL }}#{{ $id }}">
|
||||||
{{ if eq $index $.Site.Params.widgets.archives.limit }}
|
{{ if eq $index $.Site.Params.widgets.archives.limit }}
|
||||||
<span class="year">{{ T "widgetArchivesMore" }}</span>
|
<span class="year">{{ T "widget.archives.more" }}</span>
|
||||||
{{ else }}
|
{{ else }}
|
||||||
<span class="year">{{ .Key }}</span>
|
<span class="year">{{ .Key }}</span>
|
||||||
<span class="count">{{ len $item.Pages }}</span>
|
<span class="count">{{ len $item.Pages }}</span>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<form action="/search" class="search-form widget" {{ with .OutputFormats.Get "json" -}}data-json="{{ .Permalink }}" {{- end }}>
|
<form action="/search" class="search-form widget" {{ with .OutputFormats.Get "json" -}}data-json="{{ .Permalink }}" {{- end }}>
|
||||||
<p>
|
<p>
|
||||||
<label>{{ T "searchTitle" }}</label>
|
<label>{{ T "search.title" }}</label>
|
||||||
<input name="keyword" required placeholder="{{ T `searchPlaceholder` }}" />
|
<input name="keyword" required placeholder="{{ T `search.placeholder` }}" />
|
||||||
|
|
||||||
<button title="Search">
|
<button title="Search">
|
||||||
{{ partial "helper/icon" "search" }}
|
{{ partial "helper/icon" "search" }}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div class="widget-icon">
|
<div class="widget-icon">
|
||||||
{{ partial "helper/icon" "tag" }}
|
{{ partial "helper/icon" "tag" }}
|
||||||
</div>
|
</div>
|
||||||
<h2 class="widget-title section-title">{{ T "widgetTagCloudTitle" }}</h2>
|
<h2 class="widget-title section-title">{{ T "widget.tagCloud.title" }}</h2>
|
||||||
|
|
||||||
<div class="tagCloud-tags">
|
<div class="tagCloud-tags">
|
||||||
{{ range first .Site.Params.widgets.tagCloud.limit .Site.Taxonomies.tags.ByCount }}
|
{{ range first .Site.Params.widgets.tagCloud.limit .Site.Taxonomies.tags.ByCount }}
|
||||||
|
24
layouts/shortcodes/bilibili.html
Normal file
24
layouts/shortcodes/bilibili.html
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{{ $vid := (.Get 0) }}
|
||||||
|
{{ $videopage := default 1 (.Get 1) }}
|
||||||
|
{{ $basicQuery := querify "page" $videopage "high_quality" 1 "as_wide" 1 }}
|
||||||
|
{{ $videoQuery := "" }}
|
||||||
|
|
||||||
|
{{ if strings.HasPrefix (lower $vid) "av" }}
|
||||||
|
{{ $videoQuery = querify "aid" (strings.TrimPrefix "av" (lower $vid)) }}
|
||||||
|
{{ else if strings.HasPrefix (lower $vid) "bv" }}
|
||||||
|
{{ $videoQuery = querify "bvid" $vid }}
|
||||||
|
{{ else }}
|
||||||
|
<p>Bilibili 视频av号或BV号错误!请检查视频av号或BV号是否正确</p>
|
||||||
|
<p>当前视频av或BV号:{{ $vid }},视频分P:{{ $videopage }}</p>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
<div style="position: relative; width: 100%; height: 0; padding-bottom: 56.25%;">
|
||||||
|
<iframe src="//player.bilibili.com/player.html?{{ $basicQuery | safeURL }}&{{ $videoQuery | safeURL }}"
|
||||||
|
scrolling="no"
|
||||||
|
frameborder="no"
|
||||||
|
framespacing="0"
|
||||||
|
allowfullscreen="true"
|
||||||
|
style="position: absolute; width: 100%; height: 100%; left: 0; top: 0;"
|
||||||
|
>
|
||||||
|
</iframe>
|
||||||
|
</div>
|
File diff suppressed because one or more lines are too long
@ -20,7 +20,7 @@ features = [
|
|||||||
"opengraph",
|
"opengraph",
|
||||||
"widgets"
|
"widgets"
|
||||||
]
|
]
|
||||||
min_version = "0.74.0"
|
min_version = "0.78.0"
|
||||||
|
|
||||||
[author]
|
[author]
|
||||||
name = "Jimmy Cai"
|
name = "Jimmy Cai"
|
||||||
|
Loading…
Reference in New Issue
Block a user