mirror of
https://github.com/CaiJimmy/hugo-theme-stack.git
synced 2025-04-29 03:53:30 +08:00
Merge branch 'master' into toggle-dark-mode
This commit is contained in:
parent
7e1c7b94bf
commit
8d018a703f
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
custom: ['https://www.buymeacoffee.com/jimmycai']
|
31
.github/release-drafter.yml
vendored
Normal file
31
.github/release-drafter.yml
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
name-template: 'v$RESOLVED_VERSION 🌈'
|
||||||
|
tag-template: 'v$RESOLVED_VERSION'
|
||||||
|
categories:
|
||||||
|
- title: '🚀 Features'
|
||||||
|
labels:
|
||||||
|
- 'feature'
|
||||||
|
- 'enhancement'
|
||||||
|
- title: '🐛 Bug Fixes'
|
||||||
|
labels:
|
||||||
|
- 'fix'
|
||||||
|
- 'bugfix'
|
||||||
|
- 'bug'
|
||||||
|
- title: '🧰 Maintenance'
|
||||||
|
label: 'chore'
|
||||||
|
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
|
||||||
|
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
|
||||||
|
version-resolver:
|
||||||
|
major:
|
||||||
|
labels:
|
||||||
|
- 'major'
|
||||||
|
minor:
|
||||||
|
labels:
|
||||||
|
- 'minor'
|
||||||
|
patch:
|
||||||
|
labels:
|
||||||
|
- 'patch'
|
||||||
|
default: patch
|
||||||
|
template: |
|
||||||
|
## Changes
|
||||||
|
|
||||||
|
$CHANGES
|
16
.github/workflows/release-drafter.yml
vendored
Normal file
16
.github/workflows/release-drafter.yml
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
name: Release Drafter
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
# branches to consider in the event; optional, defaults to all
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update_release_draft:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
# Drafts your next Release notes as Pull Requests are merged into "master"
|
||||||
|
- uses: release-drafter/release-drafter@v5
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
19
README.md
19
README.md
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
## Documentation & more information
|
## Documentation & more information
|
||||||
|
|
||||||
[Documentation](https://www.notion.so/jimmycai/Hugo-Theme-Stack-511aec5b9ed845ce9b6e3ae0bf7fb6d4) | [中文文档](https://www.notion.so/jimmycai/Hugo-Theme-Stack-511aec5b9ed845ce9b6e3ae0bf7fb6d4)
|
[Documentation](https://docs.stack.jimmycai.com/) | [中文文档](https://docs.stack.jimmycai.com/v/zh-cn/)
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
@ -35,7 +35,12 @@ The only JavaScript library being used is [node-vibrant](https://github.com/Vibr
|
|||||||
|
|
||||||
This theme uses SCSS and TypeScript. For that reason, it's necessary to use **Hugo ≥ 0.74.0**.
|
This theme uses SCSS and TypeScript. For that reason, it's necessary to use **Hugo ≥ 0.74.0**.
|
||||||
|
|
||||||
**Note**: You'll need Hugo Extended version to edit SCSS files
|
Use Hugo Extended version if you want to:
|
||||||
|
|
||||||
|
* Use the latest feature/fix from `master` branch
|
||||||
|
* Edit SCSS files
|
||||||
|
|
||||||
|
**Compiled CSS are updated once per release.**
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@ -51,6 +56,14 @@ Please do not remove the "*Theme Stack designed by Jimmy*" text and link.
|
|||||||
|
|
||||||
If you want to port this theme to another blogging platform, please let me know🙏.
|
If you want to port this theme to another blogging platform, please let me know🙏.
|
||||||
|
|
||||||
|
## Sponsoring
|
||||||
|
|
||||||
|
If you like this theme, 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>
|
||||||
|
|
||||||
|
Your support is greatly appreciated :)
|
||||||
|
|
||||||
## Thanks to
|
## Thanks to
|
||||||
|
|
||||||
- [Vibrant-Colors/node-vibrant](https://github.com/Vibrant-Colors/node-vibrant)
|
- [Vibrant-Colors/node-vibrant](https://github.com/Vibrant-Colors/node-vibrant)
|
||||||
@ -62,4 +75,4 @@ If you want to port this theme to another blogging platform, please let me know
|
|||||||
- [artchen/hexo-theme-element](https://github.com/artchen/hexo-theme-element)
|
- [artchen/hexo-theme-element](https://github.com/artchen/hexo-theme-element)
|
||||||
- [MunifTanjim/minimo](https://github.com/MunifTanjim/minimo)
|
- [MunifTanjim/minimo](https://github.com/MunifTanjim/minimo)
|
||||||
- [lepture/yue.css](https://github.com/lepture/yue.css)
|
- [lepture/yue.css](https://github.com/lepture/yue.css)
|
||||||
- Markdown gallery syntax from [Typlog](https://typlog.com/)
|
- Markdown gallery syntax from [Typlog](https://typlog.com/)
|
||||||
|
7
assets/icons/search.svg
Normal file
7
assets/icons/search.svg
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-search" 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="10" cy="10" r="7" />
|
||||||
|
<line x1="21" y1="21" x2="15" y2="15" />
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
|
After Width: | Height: | Size: 355 B |
1
assets/scss/custom.scss
Normal file
1
assets/scss/custom.scss
Normal file
@ -0,0 +1 @@
|
|||||||
|
/* Place your custom SCSS in HUGO_SITE_FOLDER/assets/scss/custom.scss */
|
119
assets/scss/grid.scss
Normal file
119
assets/scss/grid.scss
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
.container {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
|
||||||
|
&.extended {
|
||||||
|
@media (min-width: $on-phone) {
|
||||||
|
max-width: 800px;
|
||||||
|
|
||||||
|
.left-sidebar {
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: $on-tablet) {
|
||||||
|
max-width: 972px;
|
||||||
|
|
||||||
|
.right-sidebar {
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: $on-desktop) {
|
||||||
|
max-width: 1200px;
|
||||||
|
|
||||||
|
.left-sidebar {
|
||||||
|
width: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-sidebar {
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: $on-desktop-large) {
|
||||||
|
max-width: 1536px;
|
||||||
|
|
||||||
|
.left-sidebar {
|
||||||
|
width: 15%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.compact {
|
||||||
|
@media (min-width: $on-phone) {
|
||||||
|
max-width: 800px;
|
||||||
|
|
||||||
|
.left-sidebar {
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: $on-tablet) {
|
||||||
|
max-width: 972px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: $on-desktop) {
|
||||||
|
max-width: 1050px;
|
||||||
|
|
||||||
|
.left-sidebar {
|
||||||
|
width: 20%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: $on-desktop-large) {
|
||||||
|
max-width: 1300px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
&.column {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.on-phone--column {
|
||||||
|
@media (max-width: $on-phone) {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.align-items--flex-start {
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grow {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.do-not-shrink {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.do-not-overflow {
|
||||||
|
min-width: 0;
|
||||||
|
flex-shrink: 1;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.full-width {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main.main {
|
||||||
|
min-width: 0;
|
||||||
|
padding: 0 15px;
|
||||||
|
max-width: 100%;
|
||||||
|
flex-grow: 1;
|
||||||
|
padding-top: var(--main-top-padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-grid {
|
||||||
|
@media (max-width: $on-phone) {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
@ -11,8 +11,8 @@
|
|||||||
border-radius: var(--card-border-radius);
|
border-radius: var(--card-border-radius);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
transition: box-shadow .3s ease;
|
transition: box-shadow 0.3s ease;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
box-shadow: var(--shadow-l2);
|
box-shadow: var(--shadow-l2);
|
||||||
}
|
}
|
||||||
@ -53,7 +53,7 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
padding: var(--content-padding);
|
padding: var(--card-padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
.article-category {
|
.article-category {
|
||||||
@ -75,10 +75,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.article-title {
|
.article-title {
|
||||||
font-size: 2.4rem;
|
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
color: var(--card-text-color-main);
|
color: var(--card-text-color-main);
|
||||||
|
font-size: 2.2rem;
|
||||||
|
|
||||||
|
@media (min-width: $on-desktop-large) {
|
||||||
|
font-size: 2.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: var(--card-text-color-main);
|
color: var(--card-text-color-main);
|
||||||
@ -88,14 +92,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: $on-desktop-large) {
|
|
||||||
font-size: 2.4rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: $on-desktop) {
|
|
||||||
font-size: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
& + .article-subtitle {
|
& + .article-subtitle {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
@ -103,18 +99,14 @@
|
|||||||
|
|
||||||
.article-subtitle {
|
.article-subtitle {
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-size: 1.8rem;
|
|
||||||
color: var(--card-text-color-secondary);
|
color: var(--card-text-color-secondary);
|
||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
|
||||||
|
font-size: 1.75rem;
|
||||||
@media (min-width: $on-desktop-large) {
|
@media (min-width: $on-desktop-large) {
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: $on-desktop) {
|
|
||||||
font-size: 1.6rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.article-time {
|
.article-time {
|
||||||
@ -125,9 +117,10 @@
|
|||||||
|
|
||||||
svg {
|
svg {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
margin-right: 8px;
|
margin-right: 15px;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
|
stroke-width: 1.33;
|
||||||
}
|
}
|
||||||
|
|
||||||
time {
|
time {
|
||||||
@ -159,24 +152,32 @@
|
|||||||
border-radius: var(--card-border-radius);
|
border-radius: var(--card-border-radius);
|
||||||
box-shadow: var(--shadow-l1);
|
box-shadow: var(--shadow-l1);
|
||||||
background-color: var(--card-background);
|
background-color: var(--card-background);
|
||||||
|
--image-size: 60px;
|
||||||
|
|
||||||
|
@media (max-width: $on-tablet) {
|
||||||
|
--image-size: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
& + .pagination {
|
& + .pagination {
|
||||||
margin-top: var(--section-separation);
|
margin-top: var(--section-separation);
|
||||||
}
|
}
|
||||||
|
|
||||||
article {
|
article {
|
||||||
display: flex;
|
& > a {
|
||||||
align-items: center;
|
display: flex;
|
||||||
padding: var(--small-card-padding);
|
align-items: center;
|
||||||
|
padding: var(--small-card-padding);
|
||||||
|
}
|
||||||
|
|
||||||
&:not(:last-of-type) {
|
&:not(:last-of-type) {
|
||||||
border-bottom: 2px solid var(--card-separator-color);
|
border-bottom: 1.5px solid var(--card-separator-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.article-details {
|
.article-details {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
padding-right: 15px;
|
padding-right: 15px;
|
||||||
|
min-height: var(--image-size);
|
||||||
}
|
}
|
||||||
|
|
||||||
.article-title {
|
.article-title {
|
||||||
@ -190,10 +191,21 @@
|
|||||||
|
|
||||||
.article-image {
|
.article-image {
|
||||||
img {
|
img {
|
||||||
width: 60px;
|
width: var(--image-size);
|
||||||
height: 60px;
|
height: var(--image-size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.article-time {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-preview{
|
||||||
|
font-size: 1.4rem;
|
||||||
|
color: var(--card-text-color-tertiary);
|
||||||
|
margin-top: 10px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,5 +2,5 @@
|
|||||||
background-color: var(--card-background);
|
background-color: var(--card-background);
|
||||||
box-shadow: var(--shadow-l1);
|
box-shadow: var(--shadow-l1);
|
||||||
border-radius: var(--card-border-radius);
|
border-radius: var(--card-border-radius);
|
||||||
padding: var(--content-padding);
|
padding: var(--card-padding);
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,5 @@
|
|||||||
.archives-group {
|
.archives-group {
|
||||||
margin-bottom: var(--section-separation);
|
margin-bottom: var(--section-separation);
|
||||||
.archives-date {
|
|
||||||
text-transform: uppercase;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
font-size: 1.6rem;
|
|
||||||
font-weight: bold;
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: var(--body-text-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.template-archives {
|
.template-archives {
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
article {
|
.main-article {
|
||||||
background: var(--card-background);
|
background: var(--card-background);
|
||||||
border-radius: var(--card-border-radius);
|
border-radius: var(--card-border-radius);
|
||||||
box-shadow: var(--shadow-l1);
|
box-shadow: var(--shadow-l1);
|
||||||
@ -64,13 +64,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.article-details {
|
.article-details {
|
||||||
padding: var(--content-padding);
|
padding: var(--card-padding);
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.article-content {
|
.article-content {
|
||||||
margin: var(--content-padding) 0;
|
margin: var(--card-padding) 0;
|
||||||
color: var(--card-text-color-main);
|
color: var(--card-text-color-main);
|
||||||
|
|
||||||
img {
|
img {
|
||||||
@ -80,11 +80,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.article-footer {
|
.article-footer {
|
||||||
padding: var(--content-padding);
|
margin: var(--card-padding);
|
||||||
padding-top: 0;
|
margin-top: 0;
|
||||||
|
|
||||||
section:not(:first-child) {
|
section:not(:first-child) {
|
||||||
margin-top: var(--content-padding);
|
margin-top: var(--card-padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
section {
|
section {
|
||||||
@ -104,6 +104,7 @@
|
|||||||
|
|
||||||
.article-tags {
|
.article-tags {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
text-transform: unset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,7 +193,7 @@
|
|||||||
|
|
||||||
& > p {
|
& > p {
|
||||||
margin: 1.5em 0;
|
margin: 1.5em 0;
|
||||||
padding: 0 var(--content-padding);
|
padding: 0 var(--card-padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
h1,
|
h1,
|
||||||
@ -201,7 +202,7 @@
|
|||||||
h4,
|
h4,
|
||||||
h5,
|
h5,
|
||||||
h6 {
|
h6 {
|
||||||
padding: 0 calc(var(--content-padding) - var(--heading-border-size));
|
padding: 0 calc(var(--card-padding) - var(--heading-border-size));
|
||||||
border-left: var(--heading-border-size) solid var(--accent-color);
|
border-left: var(--heading-border-size) solid var(--accent-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,13 +220,13 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
border-left: var(--blockquote-border-size) solid var(--card-separator-color);
|
border-left: var(--blockquote-border-size) solid var(--card-separator-color);
|
||||||
padding: 15px calc(var(--content-padding) - var(--blockquote-border-size));
|
padding: 15px calc(var(--card-padding) - var(--blockquote-border-size));
|
||||||
background-color: var(--blockquote-background-color);
|
background-color: var(--blockquote-background-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
& > ul,
|
& > ul,
|
||||||
& > ol {
|
& > ol {
|
||||||
margin: 1em var(--content-padding);
|
margin: 1em var(--card-padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
@ -270,7 +271,7 @@
|
|||||||
font-family: var(--code-font-family);
|
font-family: var(--code-font-family);
|
||||||
line-height: 1.428571429;
|
line-height: 1.428571429;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
padding: var(--content-padding);
|
padding: var(--card-padding);
|
||||||
|
|
||||||
code {
|
code {
|
||||||
color: unset;
|
color: unset;
|
||||||
@ -281,9 +282,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
margin: 0 var(--content-padding);
|
margin: 0 var(--card-padding);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: calc(100% - var(--content-padding) * 2);
|
max-width: calc(100% - var(--card-padding) * 2);
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
border-spacing: 0;
|
border-spacing: 0;
|
||||||
margin-bottom: 1.5em;
|
margin-bottom: 1.5em;
|
||||||
|
82
assets/scss/partials/layout/search.scss
Normal file
82
assets/scss/partials/layout/search.scss
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
.search-form {
|
||||||
|
margin-bottom: var(--section-separation);
|
||||||
|
position: relative;
|
||||||
|
--button-size: 80px;
|
||||||
|
|
||||||
|
&.widget {
|
||||||
|
--button-size: 60px;
|
||||||
|
|
||||||
|
label {
|
||||||
|
font-size: 1.3rem;
|
||||||
|
top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
padding: 30px 20px 15px 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
position: relative;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
position: absolute;
|
||||||
|
top: 15px;
|
||||||
|
left: 20px;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
color: var(--card-text-color-tertiary);
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
padding: 40px 20px 20px;
|
||||||
|
border-radius: var(--card-border-radius);
|
||||||
|
background-color: var(--card-background);
|
||||||
|
box-shadow: var(--shadow-l1);
|
||||||
|
color: var(--card-text-color-main);
|
||||||
|
width: 100%;
|
||||||
|
border: 0;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
|
||||||
|
transition: box-shadow 0.3s ease;
|
||||||
|
|
||||||
|
font-size: 1.8rem;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: 0;
|
||||||
|
box-shadow: var(--shadow-l2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: var(--button-size);
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: transparent;
|
||||||
|
border: 0;
|
||||||
|
|
||||||
|
padding: 0 10px;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: 0;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
stroke-width: 2;
|
||||||
|
color: var(--accent-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
color: var(--card-text-color-secondary);
|
||||||
|
stroke-width: 1.33;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,3 @@
|
|||||||
.taxonomy-type {
|
|
||||||
text-transform: uppercase;
|
|
||||||
color: var(--body-text-color);
|
|
||||||
font-weight: bold;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
font-size: 1.6rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.taxonomy-card {
|
.taxonomy-card {
|
||||||
border-radius: var(--card-border-radius);
|
border-radius: var(--card-border-radius);
|
||||||
background-color: var(--card-background);
|
background-color: var(--card-background);
|
||||||
|
@ -126,9 +126,11 @@
|
|||||||
list-style: none;
|
list-style: none;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
margin-top: 25px;
|
margin-top: var(--sidebar-element-separation);
|
||||||
|
margin-bottom: 0;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
flex-grow: 1;
|
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;
|
||||||
@ -180,6 +182,11 @@
|
|||||||
height: 25px;
|
height: 25px;
|
||||||
stroke-width: 1.33;
|
stroke-width: 1.33;
|
||||||
margin-right: 40px;
|
margin-right: 40px;
|
||||||
|
|
||||||
|
@media (max-width: $on-desktop-large) {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
@ -187,9 +194,8 @@
|
|||||||
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) {
|
@media (max-width: $on-desktop-large) {
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,14 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
--sidebar-avatar-size: 150px;
|
||||||
|
--sidebar-element-separation: 25px;
|
||||||
|
|
||||||
|
@media (max-width: $on-desktop-large) {
|
||||||
|
--sidebar-avatar-size: 120px;
|
||||||
|
--sidebar-element-separation: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: $on-phone) {
|
@media (max-width: $on-phone) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 30px 0;
|
padding: 30px 0;
|
||||||
@ -23,19 +31,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: $on-phone + 1) {
|
@media (min-width: $on-phone + 1) {
|
||||||
width: 25%;
|
|
||||||
margin-right: 1%;
|
margin-right: 1%;
|
||||||
padding: var(--main-top-padding) 15px;
|
padding: var(--main-top-padding) 15px;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: $on-desktop) {
|
|
||||||
width: 20%;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: $on-desktop-large) {
|
|
||||||
width: 15%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.right-sidebar {
|
.right-sidebar {
|
||||||
@ -50,19 +49,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: $on-tablet) {
|
@media (min-width: $on-tablet) {
|
||||||
width: 25%;
|
|
||||||
margin-left: 1%;
|
margin-left: 1%;
|
||||||
padding-top: 50px;
|
padding-top: var(--main-top-padding);
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: $on-desktop + 1) {
|
|
||||||
width: 25%;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-info {
|
.site-info {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
transition: box-shadow 0.5s ease;
|
transition: box-shadow 0.5s ease;
|
||||||
|
|
||||||
@media (max-width: $on-phone) {
|
@media (max-width: $on-phone) {
|
||||||
padding: 15px 30px;
|
padding: 15px 30px;
|
||||||
}
|
}
|
||||||
@ -70,14 +65,10 @@
|
|||||||
.site-avatar {
|
.site-avatar {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
margin-bottom: 25px;
|
width: var(--sidebar-avatar-size);
|
||||||
width: 150px;
|
height: var(--sidebar-avatar-size);
|
||||||
height: 150px;
|
|
||||||
|
|
||||||
@media (max-width: $on-desktop-large) {
|
margin-bottom: var(--sidebar-element-separation);
|
||||||
height: 120px;
|
|
||||||
width: 120px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.site-logo {
|
.site-logo {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -131,16 +122,15 @@
|
|||||||
|
|
||||||
.sidebar {
|
.sidebar {
|
||||||
.widget {
|
.widget {
|
||||||
&:not(:last-of-type) {
|
margin-bottom: var(--section-separation);
|
||||||
margin-bottom: var(--section-separation);
|
|
||||||
&:after {
|
&:not(:last-of-type):after {
|
||||||
content: "";
|
content: "";
|
||||||
width: 100px;
|
width: 100px;
|
||||||
height: 2px;
|
height: 2px;
|
||||||
background-color: var(--body-text-color);
|
background-color: var(--body-text-color);
|
||||||
display: block;
|
display: block;
|
||||||
margin-top: var(--section-separation);
|
margin-top: var(--section-separation);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,4 @@
|
|||||||
.widget {
|
.widget {
|
||||||
.widget-title {
|
|
||||||
text-transform: uppercase;
|
|
||||||
color: var(--body-text-color);
|
|
||||||
font-weight: bold;
|
|
||||||
margin: 0;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
font-size: 1.6rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.widget-icon {
|
.widget-icon {
|
||||||
svg {
|
svg {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
@ -45,28 +36,26 @@
|
|||||||
|
|
||||||
/* Archives widget */
|
/* Archives widget */
|
||||||
.widget.archives {
|
.widget.archives {
|
||||||
|
.widget-archive--list {
|
||||||
|
border-radius: var(--card-border-radius);
|
||||||
|
box-shadow: var(--shadow-l1);
|
||||||
|
background-color: var(--card-background);
|
||||||
|
}
|
||||||
|
|
||||||
.archives-year {
|
.archives-year {
|
||||||
margin-bottom: 10px;
|
&:not(:last-of-type) {
|
||||||
|
border-bottom: 1.5px solid var(--card-separator-color);
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
background-color: var(--card-background);
|
font-size: 1.4rem;
|
||||||
padding: 15px 25px;
|
padding: 18px 25px;
|
||||||
border-radius: var(--card-border-radius);
|
|
||||||
box-shadow: var(--shadow-l1);
|
|
||||||
display: flex;
|
display: flex;
|
||||||
transition: box-shadow 0.3s ease;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: var(--shadow-l2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: $on-desktop-large) {
|
|
||||||
padding: 12px 20px;
|
|
||||||
font-size: 1.4rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.year {
|
span.year {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
color: var(--card-text-color-main);
|
color: var(--card-text-color-main);
|
||||||
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.count {
|
span.count {
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
@import "breakpoints.scss";
|
@import "breakpoints.scss";
|
||||||
@import "variables.scss";
|
@import "variables.scss";
|
||||||
|
@import "grid.scss";
|
||||||
|
|
||||||
@import "external/normalize.scss";
|
@import "external/normalize.scss";
|
||||||
|
|
||||||
@ -22,6 +23,9 @@
|
|||||||
@import "partials/layout/article.scss";
|
@import "partials/layout/article.scss";
|
||||||
@import "partials/layout/taxonomy.scss";
|
@import "partials/layout/taxonomy.scss";
|
||||||
@import "partials/layout/404.scss";
|
@import "partials/layout/404.scss";
|
||||||
|
@import "partials/layout/search.scss";
|
||||||
|
|
||||||
|
@import "custom.scss";
|
||||||
|
|
||||||
a {
|
a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
@ -41,96 +45,16 @@ a {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.section-title {
|
||||||
margin-left: auto;
|
text-transform: uppercase;
|
||||||
margin-right: auto;
|
margin-top: 0;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
display: block;
|
||||||
|
font-size: 1.6rem;
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--body-text-color);
|
||||||
|
|
||||||
&.extended {
|
a {
|
||||||
@media (min-width: $on-phone) {
|
color: var(--body-text-color);
|
||||||
max-width: 800px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: $on-tablet) {
|
|
||||||
max-width: 972px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: $on-desktop) {
|
|
||||||
max-width: 1200px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: $on-desktop-large) {
|
|
||||||
max-width: 1536px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
main.main {
|
|
||||||
min-width: 0;
|
|
||||||
padding: 0 15px;
|
|
||||||
max-width: 100%;
|
|
||||||
flex-grow: 1;
|
|
||||||
padding-top: var(--main-top-padding);
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-grid {
|
|
||||||
@media (max-width: $on-phone) {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
|
|
||||||
&.column {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.on-phone--column {
|
|
||||||
@media (max-width: $on-phone) {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.align-items--flex-start {
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grow {
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.do-not-shrink {
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.do-not-overflow {
|
|
||||||
min-width: 0;
|
|
||||||
flex-shrink: 1;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.full-width {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.alert {
|
|
||||||
position: fixed;
|
|
||||||
right: 20px;
|
|
||||||
bottom: 20px;
|
|
||||||
z-index: 5;
|
|
||||||
background: var(--card-background);
|
|
||||||
max-width: 400px;
|
|
||||||
padding: 15px 20px;
|
|
||||||
border-radius: var(--card-border-radius);
|
|
||||||
line-height: 1.75;
|
|
||||||
color: var(--card-text-color-secondary);
|
|
||||||
box-shadow: var(--shadow-l2);
|
|
||||||
|
|
||||||
@media (max-width: $on-phone) {
|
|
||||||
max-width: 100vw;
|
|
||||||
width: calc(100% - 30px);
|
|
||||||
left: 15px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,14 @@ $defaultTagColors: #fff, #fff, #fff, #fff, #fff;
|
|||||||
*/
|
*/
|
||||||
:root {
|
:root {
|
||||||
@media (min-width: $on-phone + 1) {
|
@media (min-width: $on-phone + 1) {
|
||||||
|
--main-top-padding: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: $on-desktop-large) {
|
||||||
--main-top-padding: 50px;
|
--main-top-padding: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
--body-background: #f5f5fa;
|
--body-background: #f5f5fa;
|
||||||
|
|
||||||
--accent-color: #34495e;
|
--accent-color: #34495e;
|
||||||
@ -54,15 +59,18 @@ $defaultTagColors: #fff, #fff, #fff, #fff, #fff;
|
|||||||
|
|
||||||
--card-border-radius: 10px;
|
--card-border-radius: 10px;
|
||||||
|
|
||||||
--content-padding: 30px;
|
--card-padding: 30px;
|
||||||
@media (max-width: $on-desktop-large) {
|
@media (max-width: $on-desktop-large) {
|
||||||
--content-padding: 25px;
|
--card-padding: 25px;
|
||||||
}
|
}
|
||||||
@media (max-width: $on-tablet) {
|
@media (max-width: $on-tablet) {
|
||||||
--content-padding: 20px;
|
--card-padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
--small-card-padding: 25px;
|
--small-card-padding: 25px;
|
||||||
|
@media (max-width: $on-tablet) {
|
||||||
|
--small-card-padding: 25px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
.theme-dark {
|
.theme-dark {
|
||||||
--card-background: #424242;
|
--card-background: #424242;
|
||||||
|
34
assets/ts/createElement.ts
Normal file
34
assets/ts/createElement.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* createElement
|
||||||
|
* Edited from:
|
||||||
|
* @link https://stackoverflow.com/a/42405694
|
||||||
|
*/
|
||||||
|
function createElement(tag, attrs, children) {
|
||||||
|
var element = document.createElement(tag);
|
||||||
|
|
||||||
|
for (let name in attrs) {
|
||||||
|
if (name && attrs.hasOwnProperty(name)) {
|
||||||
|
let value = attrs[name];
|
||||||
|
|
||||||
|
if (name == "dangerouslySetInnerHTML") {
|
||||||
|
element.innerHTML = value.__html;
|
||||||
|
}
|
||||||
|
else if (value === true) {
|
||||||
|
element.setAttribute(name, name);
|
||||||
|
} else if (value !== false && value != null) {
|
||||||
|
element.setAttribute(name, value.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i = 2; i < arguments.length; i++) {
|
||||||
|
let child = arguments[i];
|
||||||
|
if (child) {
|
||||||
|
element.appendChild(
|
||||||
|
child.nodeType == null ?
|
||||||
|
document.createTextNode(child.toString()) : child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default createElement;
|
@ -236,10 +236,10 @@ function wrap(gallery: HTMLElement[]) {
|
|||||||
*/
|
*/
|
||||||
function loadPhotoSwipe() {
|
function loadPhotoSwipe() {
|
||||||
const tasks = [
|
const tasks = [
|
||||||
loadScript("https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.3/photoswipe.min.js"),
|
loadScript("https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.js"),
|
||||||
loadScript("https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.3/photoswipe-ui-default.min.js"),
|
loadScript("https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe-ui-default.min.js"),
|
||||||
loadStyle("https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.3/photoswipe.min.css"),
|
loadStyle("https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.css"),
|
||||||
loadStyle("https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.3/default-skin/default-skin.min.css")
|
loadStyle("https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/default-skin/default-skin.min.css")
|
||||||
];
|
];
|
||||||
|
|
||||||
return Promise.all(tasks);
|
return Promise.all(tasks);
|
||||||
|
@ -10,6 +10,7 @@ import { createGallery } from "./gallery"
|
|||||||
import { getColor } from './color';
|
import { getColor } from './color';
|
||||||
import menu from './menu';
|
import menu from './menu';
|
||||||
import darkmode from "./darkmode";
|
import darkmode from "./darkmode";
|
||||||
|
import createElement from './createElement';
|
||||||
|
|
||||||
let Stack = {
|
let Stack = {
|
||||||
init: () => {
|
init: () => {
|
||||||
@ -68,29 +69,6 @@ let Stack = {
|
|||||||
|
|
||||||
observer.observe(articleTile)
|
observer.observe(articleTile)
|
||||||
}
|
}
|
||||||
},
|
|
||||||
alert: (content, time = 5000, animationSpeed = 500) => {
|
|
||||||
const alert = document.createElement('div');
|
|
||||||
alert.innerHTML = content;
|
|
||||||
alert.className = 'alert';
|
|
||||||
alert.style.visibility = 'hidden';
|
|
||||||
document.body.appendChild(alert);
|
|
||||||
|
|
||||||
alert.style.transform = `translateY(${alert.clientHeight + 50}px)`;
|
|
||||||
alert.style.transition = `transform ${animationSpeed / 1000}s ease`;
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
alert.style.removeProperty('visibility');
|
|
||||||
alert.style.transform = `translateY(0)`;
|
|
||||||
}, animationSpeed);
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
alert.style.transform = `translateY(${alert.clientHeight + 50}px)`;
|
|
||||||
}, animationSpeed + time);
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
alert.remove();
|
|
||||||
}, 2 * animationSpeed + time);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,4 +78,12 @@ window.addEventListener('load', () => {
|
|||||||
}, 0);
|
}, 0);
|
||||||
})
|
})
|
||||||
|
|
||||||
window.Stack = Stack;
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
createElement: any;
|
||||||
|
Stack: any
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.Stack = Stack;
|
||||||
|
window.createElement = createElement;
|
263
assets/ts/search.tsx
Normal file
263
assets/ts/search.tsx
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
interface pageData {
|
||||||
|
title: string,
|
||||||
|
date: string,
|
||||||
|
permalink: string,
|
||||||
|
content: string,
|
||||||
|
image?: string,
|
||||||
|
preview: string,
|
||||||
|
matchCount: number
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escape HTML tags as HTML entities
|
||||||
|
* Edited from:
|
||||||
|
* @link https://stackoverflow.com/a/5499821
|
||||||
|
*/
|
||||||
|
const tagsToReplace = {
|
||||||
|
'&': '&',
|
||||||
|
'<': '<',
|
||||||
|
'>': '>',
|
||||||
|
'"': '"',
|
||||||
|
'…': '…'
|
||||||
|
};
|
||||||
|
|
||||||
|
function replaceTag(tag) {
|
||||||
|
return tagsToReplace[tag] || tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
function replaceHTMLEnt(str) {
|
||||||
|
return str.replace(/[&<>"]/g, replaceTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
function escapeRegExp(string) {
|
||||||
|
return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&');
|
||||||
|
}
|
||||||
|
|
||||||
|
class Search {
|
||||||
|
private data: pageData[];
|
||||||
|
private form: HTMLFormElement;
|
||||||
|
private input: HTMLInputElement;
|
||||||
|
private list: HTMLDivElement;
|
||||||
|
private resultTitle: HTMLHeadElement;
|
||||||
|
private resultTitleTemplate: string;
|
||||||
|
|
||||||
|
constructor({ form, input, list, resultTitle, resultTitleTemplate }) {
|
||||||
|
this.form = form;
|
||||||
|
this.input = input;
|
||||||
|
this.list = list;
|
||||||
|
this.resultTitle = resultTitle;
|
||||||
|
this.resultTitleTemplate = resultTitleTemplate;
|
||||||
|
|
||||||
|
this.handleQueryString();
|
||||||
|
this.bindQueryStringChange();
|
||||||
|
this.bindSearchForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async searchKeywords(keywords: string[]) {
|
||||||
|
const rawData = await this.getData();
|
||||||
|
let results: pageData[] = [];
|
||||||
|
|
||||||
|
/// Sort keywords by their length
|
||||||
|
keywords.sort((a, b) => {
|
||||||
|
return b.length - a.length
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const item of rawData) {
|
||||||
|
let result = {
|
||||||
|
...item,
|
||||||
|
preview: '',
|
||||||
|
matchCount: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
let matched = false;
|
||||||
|
|
||||||
|
for (const keyword of keywords) {
|
||||||
|
if (keyword === '') continue;
|
||||||
|
|
||||||
|
const regex = new RegExp(escapeRegExp(replaceHTMLEnt(keyword)), 'gi');
|
||||||
|
|
||||||
|
const contentMatch = regex.exec(result.content);
|
||||||
|
regex.lastIndex = 0; /// Reset regex
|
||||||
|
|
||||||
|
const titleMatch = regex.exec(result.title);
|
||||||
|
regex.lastIndex = 0; /// Reset regex
|
||||||
|
|
||||||
|
if (titleMatch) {
|
||||||
|
result.title = result.title.replace(regex, Search.marker);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (titleMatch || contentMatch) {
|
||||||
|
matched = true;
|
||||||
|
++result.matchCount;
|
||||||
|
|
||||||
|
let start = 0,
|
||||||
|
end = 100;
|
||||||
|
|
||||||
|
if (contentMatch) {
|
||||||
|
start = contentMatch.index - 20;
|
||||||
|
end = contentMatch.index + 80
|
||||||
|
|
||||||
|
if (start < 0) start = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.preview.indexOf(keyword) !== -1) {
|
||||||
|
result.preview = result.preview.replace(regex, Search.marker);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (start !== 0) result.preview += `[...] `;
|
||||||
|
result.preview += `${result.content.slice(start, end).replace(regex, Search.marker)} `;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matched) {
|
||||||
|
result.preview += '[...]';
|
||||||
|
results.push(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Result with more matches appears first */
|
||||||
|
return results.sort((a, b) => {
|
||||||
|
return b.matchCount - a.matchCount;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static marker(match) {
|
||||||
|
return '<mark>' + match + '</mark>';
|
||||||
|
}
|
||||||
|
|
||||||
|
private async doSearch(keywords: string[]) {
|
||||||
|
const startTime = performance.now();
|
||||||
|
|
||||||
|
const results = await this.searchKeywords(keywords);
|
||||||
|
this.clear();
|
||||||
|
|
||||||
|
for (const item of results) {
|
||||||
|
this.list.append(Search.render(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
const endTime = performance.now();
|
||||||
|
|
||||||
|
this.resultTitle.innerText = this.generateResultTitle(results.length, ((endTime - startTime) / 1000).toPrecision(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
private generateResultTitle(resultLen, time) {
|
||||||
|
return this.resultTitleTemplate.replace("#PAGES_COUNT", resultLen).replace("#TIME_SECONDS", time);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getData() {
|
||||||
|
if (!this.data) {
|
||||||
|
/// Not fetched yet
|
||||||
|
const jsonURL = this.form.dataset.json;
|
||||||
|
this.data = await fetch(jsonURL).then(res => res.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bindSearchForm() {
|
||||||
|
let lastSearch = '';
|
||||||
|
|
||||||
|
const eventHandler = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const keywords = this.input.value;
|
||||||
|
|
||||||
|
Search.updateQueryString(keywords, true);
|
||||||
|
|
||||||
|
if (keywords === '') {
|
||||||
|
return this.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastSearch === keywords) return;
|
||||||
|
lastSearch = keywords;
|
||||||
|
|
||||||
|
this.doSearch(keywords.split(' '));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.input.addEventListener('input', eventHandler);
|
||||||
|
this.input.addEventListener('compositionend', eventHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
private clear() {
|
||||||
|
this.list.innerHTML = '';
|
||||||
|
this.resultTitle.innerText = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
private bindQueryStringChange() {
|
||||||
|
window.addEventListener('popstate', (e) => {
|
||||||
|
this.handleQueryString()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleQueryString() {
|
||||||
|
const pageURL = new URL(window.location.toString());
|
||||||
|
const keywords = pageURL.searchParams.get('keyword');
|
||||||
|
this.input.value = keywords;
|
||||||
|
|
||||||
|
if (keywords) {
|
||||||
|
this.doSearch(keywords.split(' '));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static updateQueryString(keywords: string, replaceState = false) {
|
||||||
|
const pageURL = new URL(window.location.toString());
|
||||||
|
|
||||||
|
if (keywords === '') {
|
||||||
|
pageURL.searchParams.delete('keyword')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pageURL.searchParams.set('keyword', keywords);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (replaceState) {
|
||||||
|
window.history.replaceState('', '', pageURL.toString());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
window.history.pushState('', '', pageURL.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static render(item: pageData) {
|
||||||
|
return <article>
|
||||||
|
<a href={item.permalink}>
|
||||||
|
<div class="article-details">
|
||||||
|
<h2 class="article-title" dangerouslySetInnerHTML={{ __html: item.title }}></h2>
|
||||||
|
<secion class="article-preview" dangerouslySetInnerHTML={{ __html: item.preview }}></secion>
|
||||||
|
</div>
|
||||||
|
{item.image &&
|
||||||
|
<div class="article-image">
|
||||||
|
<img src={item.image} loading="lazy" />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</a>
|
||||||
|
</article>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
searchResultTitleTemplate: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
setTimeout(function () {
|
||||||
|
const searchForm = document.querySelector('.search-form') as HTMLFormElement,
|
||||||
|
searchInput = searchForm.querySelector('input') as HTMLInputElement,
|
||||||
|
searchResultList = document.querySelector('.search-result--list') as HTMLDivElement,
|
||||||
|
searchResultTitle = document.querySelector('.search-result--title') as HTMLHeadingElement;
|
||||||
|
|
||||||
|
new Search({
|
||||||
|
form: searchForm,
|
||||||
|
input: searchInput,
|
||||||
|
list: searchResultList,
|
||||||
|
resultTitle: searchResultTitle,
|
||||||
|
resultTitleTemplate: window.searchResultTitleTemplate
|
||||||
|
});
|
||||||
|
}, 0);
|
||||||
|
})
|
||||||
|
|
||||||
|
export default Search;
|
@ -1,92 +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"
|
|
||||||
[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]
|
|
||||||
[params.article.license]
|
|
||||||
enabled = true
|
|
||||||
default = "Licenced under CC BY-NC-SA 4.0"
|
|
||||||
[params.comments]
|
|
||||||
enabled = true
|
|
||||||
# Only Disqus is available so far
|
|
||||||
provider = "disqus"
|
|
||||||
[params.widgets]
|
|
||||||
enabled = ['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.article]
|
|
||||||
enabled = false
|
|
||||||
local = false
|
|
||||||
src = ""
|
|
||||||
[params.defaultImage.articleList]
|
|
||||||
enabled = false
|
|
||||||
local = true
|
|
||||||
src = ""
|
|
||||||
[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"
|
|
||||||
|
|
||||||
[related]
|
|
||||||
includeNewer = true
|
|
||||||
threshold = 60
|
|
||||||
toLower = false
|
|
||||||
|
|
||||||
[[related.indices]]
|
|
||||||
name = "tags"
|
|
||||||
weight = 100
|
|
||||||
|
|
||||||
[[related.indices]]
|
|
||||||
name = "categories"
|
|
||||||
weight = 200
|
|
||||||
|
|
||||||
[markup]
|
|
||||||
[markup.highlight]
|
|
||||||
noClasses = false
|
|
113
exampleSite/config.yaml
Normal file
113
exampleSite/config.yaml
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
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:
|
||||||
|
site:
|
||||||
|
card: summary_large_image
|
||||||
|
|
||||||
|
defaultImage:
|
||||||
|
opengraph:
|
||||||
|
enabled: false
|
||||||
|
local: false
|
||||||
|
src:
|
||||||
|
|
||||||
|
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
|
@ -5,6 +5,7 @@ date = "2019-02-28"
|
|||||||
aliases = ["about-us", "about-hugo", "contact"]
|
aliases = ["about-us", "about-hugo", "contact"]
|
||||||
author = "Hugo Authors"
|
author = "Hugo Authors"
|
||||||
license = "CC BY-NC-ND"
|
license = "CC BY-NC-ND"
|
||||||
|
lastmod = "2020-10-09"
|
||||||
+++
|
+++
|
||||||
|
|
||||||
Written in Go, Hugo is an open source static site generator available under the [Apache Licence 2.0.](https://github.com/gohugoio/hugo/blob/master/LICENSE) Hugo supports TOML, YAML and JSON data file types, Markdown and HTML content files and uses shortcodes to add rich content. Other notable features are taxonomies, multilingual mode, image processing, custom output formats, HTML/CSS/JS minification and support for Sass SCSS workflows.
|
Written in Go, Hugo is an open source static site generator available under the [Apache Licence 2.0.](https://github.com/gohugoio/hugo/blob/master/LICENSE) Hugo supports TOML, YAML and JSON data file types, Markdown and HTML content files and uses shortcodes to add rich content. Other notable features are taxonomies, multilingual mode, image processing, custom output formats, HTML/CSS/JS minification and support for Sass SCSS workflows.
|
||||||
|
8
exampleSite/content/page/search.md
Normal file
8
exampleSite/content/page/search.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: "Search"
|
||||||
|
slug: "search"
|
||||||
|
layout: "search"
|
||||||
|
outputs:
|
||||||
|
- html
|
||||||
|
- json
|
||||||
|
---
|
@ -1,11 +1,12 @@
|
|||||||
---
|
---
|
||||||
title: 中文文章内容测试
|
title: Chinese Test
|
||||||
description: 这是一个副标题
|
description: 这是一个副标题
|
||||||
date: 2020-09-09
|
date: 2020-09-09
|
||||||
slug: test-chinese
|
slug: test-chinese
|
||||||
image: helena-hertz-wWZzXlDpMog-unsplash.jpg
|
image: helena-hertz-wWZzXlDpMog-unsplash.jpg
|
||||||
categories:
|
categories:
|
||||||
- Test
|
- Test
|
||||||
|
- 测试
|
||||||
---
|
---
|
||||||
|
|
||||||
## 正文测试
|
## 正文测试
|
||||||
|
@ -4,11 +4,13 @@ title = "Placeholder Text"
|
|||||||
date = "2019-03-09"
|
date = "2019-03-09"
|
||||||
description = "Lorem Ipsum Dolor Si Amet"
|
description = "Lorem Ipsum Dolor Si Amet"
|
||||||
categories = [
|
categories = [
|
||||||
"Test"
|
"Test",
|
||||||
|
"Test with whitespaces"
|
||||||
]
|
]
|
||||||
tags = [
|
tags = [
|
||||||
"markdown",
|
"markdown",
|
||||||
"text",
|
"text",
|
||||||
|
"tag with whitespaces"
|
||||||
]
|
]
|
||||||
image = "matt-le-SJSpo9hQf7s-unsplash.jpg"
|
image = "matt-le-SJSpo9hQf7s-unsplash.jpg"
|
||||||
+++
|
+++
|
||||||
|
@ -13,14 +13,6 @@ Hugo ships with several [Built-in Shortcodes](https://gohugo.io/content-manageme
|
|||||||
<!--more-->
|
<!--more-->
|
||||||
---
|
---
|
||||||
|
|
||||||
## Instagram Simple Shortcode
|
|
||||||
|
|
||||||
{{< instagram_simple BGvuInzyFAe hidecaption >}}
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## YouTube Privacy Enhanced Shortcode
|
## YouTube Privacy Enhanced Shortcode
|
||||||
|
|
||||||
{{< youtube ZJthWmvUzzc >}}
|
{{< youtube ZJthWmvUzzc >}}
|
||||||
|
26
i18n/en.toml
26
i18n/en.toml
@ -1,26 +0,0 @@
|
|||||||
[toggleMenu]
|
|
||||||
other = "Toggle Menu"
|
|
||||||
|
|
||||||
[relatedContents]
|
|
||||||
other = "Related contents"
|
|
||||||
|
|
||||||
[lastUpdatedOn]
|
|
||||||
other ="Last updated on {{ .Count }}"
|
|
||||||
|
|
||||||
[widgetArchivesTitle]
|
|
||||||
other = "Archives"
|
|
||||||
|
|
||||||
[widgetArchivesMore]
|
|
||||||
other = "More"
|
|
||||||
|
|
||||||
[widgetTagCloudTitle]
|
|
||||||
other = "Tags"
|
|
||||||
|
|
||||||
[notFoundTitle]
|
|
||||||
other = "Not Found"
|
|
||||||
|
|
||||||
[notFoundSubtitle]
|
|
||||||
other = "This page does not exist."
|
|
||||||
|
|
||||||
[darkModeToggle]
|
|
||||||
other = "Dark Mode"
|
|
46
i18n/en.yaml
Normal file
46
i18n/en.yaml
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
toggleMenu:
|
||||||
|
other: Toggle Menu
|
||||||
|
|
||||||
|
darkMode:
|
||||||
|
toggle:
|
||||||
|
other: Dark Mode
|
||||||
|
|
||||||
|
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.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 }}
|
24
i18n/ja.yaml
Normal file
24
i18n/ja.yaml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
toggleMenu:
|
||||||
|
other: メニューを開く・閉じる
|
||||||
|
|
||||||
|
article:
|
||||||
|
relatedContents:
|
||||||
|
other: 関連するコンテンツ
|
||||||
|
lastUpdatedOn:
|
||||||
|
other: 最終更新
|
||||||
|
|
||||||
|
notFound:
|
||||||
|
title:
|
||||||
|
other: 404 Not Found
|
||||||
|
subtitle:
|
||||||
|
other: 指定されたページは存在しません。
|
||||||
|
|
||||||
|
widget:
|
||||||
|
archives:
|
||||||
|
title:
|
||||||
|
other: アーカイブ
|
||||||
|
more:
|
||||||
|
other: さらに見る
|
||||||
|
tagCloud:
|
||||||
|
title:
|
||||||
|
other: タグ
|
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 }} 테마 사용 중"
|
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 }}
|
@ -1,26 +0,0 @@
|
|||||||
[toggleMenu]
|
|
||||||
other = "切换菜单"
|
|
||||||
|
|
||||||
[relatedContents]
|
|
||||||
other = "相关文章"
|
|
||||||
|
|
||||||
[lastUpdatedOn]
|
|
||||||
other ="最后更新于 {{ .Count }}"
|
|
||||||
|
|
||||||
[widgetArchivesTitle]
|
|
||||||
other = "归档"
|
|
||||||
|
|
||||||
[widgetArchivesMore]
|
|
||||||
other = "更多"
|
|
||||||
|
|
||||||
[widgetTagCloudTitle]
|
|
||||||
other = "标签云"
|
|
||||||
|
|
||||||
[notFoundTitle]
|
|
||||||
other = "404 错误"
|
|
||||||
|
|
||||||
[notFoundSubtitle]
|
|
||||||
other = "页面不存在"
|
|
||||||
|
|
||||||
[darkModeToggle]
|
|
||||||
other = "暗色模式"
|
|
40
i18n/zh-CN.yaml
Normal file
40
i18n/zh-CN.yaml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
toggleMenu:
|
||||||
|
other: 切换菜单
|
||||||
|
|
||||||
|
darkMode:
|
||||||
|
toggle:
|
||||||
|
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 }}
|
@ -2,14 +2,12 @@
|
|||||||
{{ define "main" }}
|
{{ define "main" }}
|
||||||
{{ $categories := ($.Site.GetPage "taxonomyTerm" "categories").Pages }}
|
{{ $categories := ($.Site.GetPage "taxonomyTerm" "categories").Pages }}
|
||||||
{{ if $categories }}
|
{{ if $categories }}
|
||||||
<div class="widget">
|
<h2 class="section-title">{{ T "archives.categories" }}</h2>
|
||||||
<h1 class="widget-title">Categories</h1>
|
<div class="category-list">
|
||||||
<div class="category-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") }}
|
{{ end }}
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
@ -21,7 +19,7 @@
|
|||||||
{{ range $filtered.GroupByDate "2006" }}
|
{{ range $filtered.GroupByDate "2006" }}
|
||||||
{{ $id := lower (replace .Key " " "-") }}
|
{{ $id := lower (replace .Key " " "-") }}
|
||||||
<div class="archives-group" id="{{ $id }}">
|
<div class="archives-group" id="{{ $id }}">
|
||||||
<h3 class="archives-date"><a href="{{ $.Permalink }}#{{ $id }}">{{ .Key }}</a></h3>
|
<h2 class="archives-date section-title"><a href="{{ $.RelPermalink }}#{{ $id }}">{{ .Key }}</a></h2>
|
||||||
<div class="article-list--compact">
|
<div class="article-list--compact">
|
||||||
{{ range .Pages }}
|
{{ range .Pages }}
|
||||||
{{ partial "article-list/compact" . }}
|
{{ partial "article-list/compact" . }}
|
||||||
@ -31,4 +29,4 @@
|
|||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{ partialCached "footer/footer" . }}
|
{{ partialCached "footer/footer" . }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="{{ .Site.LanguageCode }}">
|
<html lang="{{ .Site.LanguageCode }}">
|
||||||
{{- partial "head/head.html" . -}}
|
<head>
|
||||||
|
{{- partial "head/head.html" . -}}
|
||||||
|
{{- block "head" . -}}{{ end }}
|
||||||
|
</head>
|
||||||
<body class="{{ block `body-class` . }}{{ end }}">
|
<body class="{{ block `body-class` . }}{{ end }}">
|
||||||
<script>
|
<script>
|
||||||
(function() {
|
(function() {
|
||||||
@ -15,7 +18,7 @@
|
|||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="container extended flex on-phone--column align-items--flex-start {{ block `container-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 "sidebar/left.html" . }}
|
{{ partial "sidebar/left.html" . }}
|
||||||
<main class="main full-width">
|
<main class="main full-width">
|
||||||
{{- block "main" . }}{{- end }}
|
{{- block "main" . }}{{- end }}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{{ define "main" }}
|
{{ define "main" }}
|
||||||
<h3 class="taxonomy-type">{{ .Type | singularize | humanize }}</h3>
|
<h3 class="taxonomy-type section-title">{{ .Type | singularize | humanize }}</h3>
|
||||||
<div class="taxonomy-card">
|
<div class="taxonomy-card">
|
||||||
<div class="taxonomy-details">
|
<div class="taxonomy-details">
|
||||||
<h3 class="taxonomy-count">{{ len .Pages }} post{{ if gt (len .Pages) 1 }}s{{ end }}</h3>
|
<h3 class="taxonomy-count">{{ len .Pages }} post{{ if gt (len .Pages) 1 }}s{{ end }}</h3>
|
||||||
|
@ -15,5 +15,5 @@
|
|||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{ define "right-sidebar" }}
|
{{ define "right-sidebar" }}
|
||||||
{{ partialCached "sidebar/right.html" . }}
|
{{ partial "sidebar/right.html" . }}
|
||||||
{{ end }}
|
{{ end }}
|
31
layouts/page/search.html
Normal file
31
layouts/page/search.html
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{{ define "body-class" }}template-search{{ end }}
|
||||||
|
{{ define "head" }}
|
||||||
|
{{- with .OutputFormats.Get "json" -}}
|
||||||
|
<link rel="preload" href="{{ .Permalink }}" as="fetch" crossorigin="anonymous">
|
||||||
|
{{- end -}}
|
||||||
|
{{ end }}
|
||||||
|
{{ define "main" }}
|
||||||
|
<form action="{{ .Permalink }}" class="search-form"{{ with .OutputFormats.Get "json" -}} data-json="{{ .Permalink }}"{{- end }}>
|
||||||
|
<p>
|
||||||
|
<label>{{ T "search.title" }}</label>
|
||||||
|
<input name="keyword" placeholder="{{ T `search.placeholder` }}" />
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<button title="Search">
|
||||||
|
{{ partial "helper/icon" "search" }}
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<h3 class="search-result--title section-title"></h3>
|
||||||
|
<div class="search-result--list article-list--compact"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.searchResultTitleTemplate = "{{ T `search.resultTitle` }}"
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{{- $opts := dict "minify" hugo.IsProduction "JSXFactory" "createElement" -}}
|
||||||
|
{{- $searchScript := resources.Get "ts/search.tsx" | js.Build $opts -}}
|
||||||
|
<script type="text/javascript" src="{{ $searchScript.RelPermalink }}" defer></script>
|
||||||
|
|
||||||
|
{{ partialCached "footer/footer" . }}
|
||||||
|
{{ end }}
|
20
layouts/page/search.json
Normal file
20
layouts/page/search.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{{- $pages := where .Site.RegularPages "Type" "in" .Site.Params.mainSections -}}
|
||||||
|
{{- $notHidden := where .Site.RegularPages "Params.hidden" "!=" true -}}
|
||||||
|
{{- $filtered := ($pages | intersect $notHidden) -}}
|
||||||
|
|
||||||
|
{{- $result := slice -}}
|
||||||
|
|
||||||
|
{{- range $filtered -}}
|
||||||
|
{{- $data := dict "title" .Title "date" .Date "permalink" .Permalink "content" (.Plain) -}}
|
||||||
|
|
||||||
|
{{- $image := partialCached "helper/image" (dict "Context" . "Type" "articleList") .RelPermalink "articleList" -}}
|
||||||
|
{{- if and $image.exists $image.resource -}}
|
||||||
|
{{- $thumbnail := $image.resource.Fill "120x120" -}}
|
||||||
|
{{- $image := dict "image" (absURL $thumbnail.Permalink) -}}
|
||||||
|
{{- $data = merge $data $image -}}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{- $result = $result | append $data -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{ jsonify $result }}
|
@ -1,27 +1,27 @@
|
|||||||
<article>
|
<article>
|
||||||
<div class="article-details">
|
<a href="{{ .RelPermalink }}">
|
||||||
<h2 class="article-title">
|
<div class="article-details">
|
||||||
<a href="{{ .Permalink }}">
|
<h2 class="article-title">
|
||||||
{{- .Title -}}
|
{{- .Title -}}
|
||||||
</a>
|
</h2>
|
||||||
</h2>
|
<footer class="article-time">
|
||||||
<footer class="article-time">
|
<time datetime='{{ .Date.Format "2006-01-02T15:04:05Z07:00" }}'>
|
||||||
<time datetime='{{ .Date.Format "2006-01-02T15:04:05Z07:00" }}'>
|
{{- .Date.Format (or .Site.Params.dateFormat.published "Jan 02, 2006") -}}
|
||||||
{{- .Date.Format (or .Site.Params.dateFormat.published "Jan 02, 2006") -}}
|
</time>
|
||||||
</time>
|
</footer>
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{- $image := partialCached "helper/image" (dict "Context" . "Type" "articleList") .RelPermalink "articleList" -}}
|
|
||||||
{{ if $image.exists }}
|
|
||||||
<div class="article-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" alt="Featured image of post {{ .Title }}" />
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
|
||||||
|
{{- $image := partialCached "helper/image" (dict "Context" . "Type" "articleList") .RelPermalink "articleList" -}}
|
||||||
|
{{ if $image.exists }}
|
||||||
|
<div class="article-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" alt="Featured image of post {{ .Title }}" />
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</a>
|
||||||
</article>
|
</article>
|
@ -2,7 +2,7 @@
|
|||||||
<article class="{{ if $image.exists }}has-image{{ end }}">
|
<article class="{{ if $image.exists }}has-image{{ end }}">
|
||||||
{{ if $image.exists }}
|
{{ if $image.exists }}
|
||||||
<div class="article-image">
|
<div class="article-image">
|
||||||
<a href="{{ .Permalink }}">
|
<a href="{{ .RelPermalink }}">
|
||||||
{{ if $image.resource }}
|
{{ if $image.resource }}
|
||||||
{{- $thumbnail := $image.resource.Fill "800x250" -}}
|
{{- $thumbnail := $image.resource.Fill "800x250" -}}
|
||||||
{{- $thumbnailRetina := $image.resource.Fill "1600x500" -}}
|
{{- $thumbnailRetina := $image.resource.Fill "1600x500" -}}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{{ $image := partialCached "helper/image" (dict "Context" .context "Type" .Type) .context.RelPermalink .Type }}
|
{{ $image := partialCached "helper/image" (dict "Context" .context "Type" .Type) .context.RelPermalink .Type }}
|
||||||
<article class="{{ if $image.exists }}has-image{{ end }}">
|
<article class="{{ if $image.exists }}has-image{{ end }}">
|
||||||
<a href="{{ .context.Permalink }}">
|
<a href="{{ .context.RelPermalink }}">
|
||||||
|
|
||||||
{{ if $image.exists }}
|
{{ if $image.exists }}
|
||||||
<div class="article-image">
|
<div class="article-image">
|
||||||
|
@ -4,4 +4,8 @@
|
|||||||
{{ partial "article/components/content" . }}
|
{{ partial "article/components/content" . }}
|
||||||
|
|
||||||
{{ partial "article/components/footer" . }}
|
{{ partial "article/components/footer" . }}
|
||||||
|
|
||||||
|
{{ if or .Params.math .Site.Params.article.math }}
|
||||||
|
{{ partialCached "article/components/math.html" . }}
|
||||||
|
{{ end }}
|
||||||
</article>
|
</article>
|
@ -1,25 +1,28 @@
|
|||||||
{{ $image := partialCached "helper/image" (dict "Context" . "Type" "article") .RelPermalink "article" }}
|
{{ $image := partialCached "helper/image" (dict "Context" . "Type" "article") .RelPermalink "article" }}
|
||||||
{{- $context := . -}}
|
{{- $context := . -}}
|
||||||
{{- $categories := .Params.categories -}}
|
|
||||||
<div class="article-details">
|
<div class="article-details">
|
||||||
{{ if $categories }}
|
{{ if .Params.categories }}
|
||||||
<header class="article-category">
|
<header class="article-category">
|
||||||
{{ range $category := $categories }}
|
{{ range (.GetTerms "categories") }}
|
||||||
{{ $term := $.Site.GetPage (printf "/categories/%s" $category) }}
|
|
||||||
{{ if and $image.exists $image.resource }}
|
{{ if and $image.exists $image.resource }}
|
||||||
{{- $imageRaw := $image.resource | resources.Fingerprint "md5" -}}
|
{{- $imageRaw := $image.resource | resources.Fingerprint "md5" -}}
|
||||||
{{- $20x := $imageRaw.Fill "20x20 smart" -}}
|
{{- $20x := $imageRaw.Fill "20x20 smart" -}}
|
||||||
<a href="{{ $term.Permalink }}" class="color-tag"
|
<a href="{{ .RelPermalink }}"
|
||||||
data-image="{{ $20x.RelPermalink }}" data-key="{{ $context.Slug }}" data-hash="{{ $imageRaw.Data.Integrity }}">{{ $term.Title | humanize }}</a>
|
class="color-tag"
|
||||||
|
data-image="{{ $20x.RelPermalink }}"
|
||||||
|
data-key="{{ $context.Slug }}"
|
||||||
|
data-hash="{{ $imageRaw.Data.Integrity }}">
|
||||||
|
{{ .LinkTitle }}
|
||||||
|
</a>
|
||||||
{{ else }}
|
{{ else }}
|
||||||
<a href="{{ $term.Permalink }}">{{ $term.Title | humanize }}</a>
|
<a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</header>
|
</header>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
<h2 class="article-title">
|
<h2 class="article-title">
|
||||||
<a href="{{ .Permalink }}">
|
<a href="{{ .RelPermalink }}">
|
||||||
{{- .Title -}}
|
{{- .Title -}}
|
||||||
</a>
|
</a>
|
||||||
</h2>
|
</h2>
|
||||||
@ -32,7 +35,7 @@
|
|||||||
|
|
||||||
{{- if not .Date.IsZero -}}
|
{{- if not .Date.IsZero -}}
|
||||||
<footer class="article-time">
|
<footer class="article-time">
|
||||||
{{ (resources.Get "icons/clock.svg").Content | safeHTML }}
|
{{ partial "helper/icon" "clock" }}
|
||||||
<time class="article-time--published">
|
<time class="article-time--published">
|
||||||
{{- .Date.Format (or .Site.Params.dateFormat.published "Jan 02, 2006") -}}
|
{{- .Date.Format (or .Site.Params.dateFormat.published "Jan 02, 2006") -}}
|
||||||
</time>
|
</time>
|
||||||
|
@ -3,16 +3,16 @@
|
|||||||
|
|
||||||
{{ if and (.Site.Params.article.license.enabled) (not (eq .Params.license false)) }}
|
{{ if and (.Site.Params.article.license.enabled) (not (eq .Params.license false)) }}
|
||||||
<section class="article-copyright">
|
<section class="article-copyright">
|
||||||
{{ (resources.Get "icons/copyright.svg").Content | safeHTML }}
|
{{ partial "helper/icon" "copyright" }}
|
||||||
<span>{{ default .Site.Params.article.license.default .Params.license }}</span>
|
<span>{{ default .Site.Params.article.license.default .Params.license }}</span>
|
||||||
</section>
|
</section>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{- if ne .Lastmod .Date -}}
|
{{- if ne .Lastmod .Date -}}
|
||||||
<section class="article-time">
|
<section class="article-time">
|
||||||
{{ (resources.Get "icons/clock.svg").Content | safeHTML }}
|
{{ 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 -}}
|
||||||
|
8
layouts/partials/article/components/math.html
Normal file
8
layouts/partials/article/components/math.html
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css"
|
||||||
|
integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous">
|
||||||
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js"
|
||||||
|
integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js"
|
||||||
|
integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"
|
||||||
|
onload="renderMathInElement(document.querySelector(`.article-content`));"></script>
|
@ -1,7 +1,7 @@
|
|||||||
<aside class="widget related-contents--wrapper">
|
<aside class="related-contents--wrapper">
|
||||||
{{ $related := .Site.RegularPages.Related . | first 5 }}
|
{{ $related := (where (.Site.RegularPages.Related .) "Params.hidden" "!=" true) | first 5 }}
|
||||||
{{ with $related }}
|
{{ with $related }}
|
||||||
<h1 class="widget-title">{{ T "relatedContents" }}</h1>
|
<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 . }}
|
||||||
@ -10,4 +10,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</aside>
|
</aside>
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
{{- $tags := .Params.Tags -}}
|
{{ if .Params.Tags }}
|
||||||
{{ if $tags }}
|
|
||||||
<section class="article-tags">
|
<section class="article-tags">
|
||||||
{{ range $tag := $tags }}
|
{{ range (.GetTerms "tags") }}
|
||||||
{{ with $.Site.GetPage (printf "/tags/%s" $tag) }}
|
<a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a>
|
||||||
<a href="{{ .Permalink }}">{{ .Title | humanize }}</a>
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</section>
|
</section>
|
||||||
{{ end }}
|
{{ end }}
|
@ -7,6 +7,6 @@
|
|||||||
background-color: var(--card-background);
|
background-color: var(--card-background);
|
||||||
border-radius: var(--card-border-radius);
|
border-radius: var(--card-border-radius);
|
||||||
box-shadow: var(--shadow-l1);
|
box-shadow: var(--shadow-l1);
|
||||||
padding: var(--content-padding);
|
padding: var(--card-padding);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
16
layouts/partials/comments/provider/utterances.html
Normal file
16
layouts/partials/comments/provider/utterances.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<script src="https://utteranc.es/client.js"
|
||||||
|
repo="{{ .Site.Params.comments.utterances.repo }}"
|
||||||
|
issue-term="{{ .Site.Params.comments.utterances.issueTerm }}"
|
||||||
|
theme="{{ .Site.Params.comments.utterances.theme }}"
|
||||||
|
{{ with .Site.Params.comments.utterances.label }}
|
||||||
|
label="{{ . }}"
|
||||||
|
{{ end }}
|
||||||
|
crossorigin="anonymous"
|
||||||
|
async>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.utterances {
|
||||||
|
max-width: unset;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,4 +1,4 @@
|
|||||||
{{- $light := resources.Get "css/highlight/light.css" | minify -}}
|
{{- $light := resources.Get "css/highlight/light.css" | minify -}}
|
||||||
{{- $dark := resources.Get "css/highlight/dark.css" | minify -}}
|
{{- $dark := resources.Get "css/highlight/dark.css" | minify -}}
|
||||||
<link rel="stylesheet" href="{{ $light.Permalink }}" media="(prefers-color-scheme: light)">
|
<link rel="stylesheet" href="{{ $light.RelPermalink }}" media="(prefers-color-scheme: light)">
|
||||||
<link rel="stylesheet" href="{{ $dark.Permalink }}" media="(prefers-color-scheme: dark)">
|
<link rel="stylesheet" href="{{ $dark.RelPermalink }}" media="(prefers-color-scheme: dark)">
|
@ -1,8 +1,12 @@
|
|||||||
|
{{- $ThemeVersion := "1.1.0" -}}
|
||||||
<footer class="site-footer">
|
<footer class="site-footer">
|
||||||
<section class="copyright">© {{ now.Format "2006" }} {{ .Site.Title }}</section>
|
<section class="copyright">© {{ now.Format "2006" }} {{ .Site.Title }}</section>
|
||||||
<section class="powerby">
|
<section class="powerby">
|
||||||
Built with <a href="https://gohugo.io/" target="_blank" rel="noopener">Hugo</a> <br />
|
{{- $Generator := `<a href="https://gohugo.io/" target="_blank" rel="noopener">Hugo</a>` -}}
|
||||||
Theme <b><a href="https://github.com/CaiJimmy/hugo-theme-stack" target="_blank" rel="noopener">Stack</a></b> designed by
|
{{- $Theme := printf `<b><a href="https://github.com/CaiJimmy/hugo-theme-stack" target="_blank" rel="noopener" data-version="%s">Stack</a></b>` $ThemeVersion -}}
|
||||||
<a href="https://jimmycai.com" target="_blank" rel="noopener">Jimmy</a>
|
{{- $DesignedBy := `<a href="https://jimmycai.com" target="_blank" rel="noopener">Jimmy</a>` -}}
|
||||||
|
|
||||||
|
{{ T "footer.builtWith" (dict "Generator" $Generator) | safeHTML }} <br />
|
||||||
|
{{ T "footer.designedBy" (dict "Theme" $Theme "DesignedBy" $DesignedBy) | safeHTML }}
|
||||||
</section>
|
</section>
|
||||||
</footer>
|
</footer>
|
@ -1,22 +1,20 @@
|
|||||||
<head>
|
<meta charset='utf-8'>
|
||||||
<meta charset='utf-8'>
|
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||||
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
|
||||||
|
|
||||||
{{- $description := partialCached "data/description" . .RelPermalink -}}
|
|
||||||
<meta name='description' content='{{ $description }}'>
|
|
||||||
|
|
||||||
{{- $title := partialCached "data/title" . .RelPermalink -}}
|
{{- $description := partialCached "data/description" . .RelPermalink -}}
|
||||||
<title>{{ $title }}</title>
|
<meta name='description' content='{{ $description }}'>
|
||||||
|
|
||||||
<link rel='canonical' href='{{ .Permalink }}'>
|
|
||||||
|
|
||||||
{{- partial "head/style.html" . -}}
|
|
||||||
{{- partial "head/script.html" . -}}
|
|
||||||
{{- partial "head/opengraph/include.html" . -}}
|
|
||||||
|
|
||||||
{{- range .AlternativeOutputFormats -}}
|
{{- $title := partialCached "data/title" . .RelPermalink -}}
|
||||||
<link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" href="{{ .Permalink | safeURL }}">
|
<title>{{ $title }}</title>
|
||||||
{{- end -}}
|
|
||||||
|
<link rel='canonical' href='{{ .Permalink }}'>
|
||||||
{{- partial "head/custom.html" . -}}
|
|
||||||
</head>
|
{{- partial "head/style.html" . -}}
|
||||||
|
{{- partial "head/script.html" . -}}
|
||||||
|
{{- partial "head/opengraph/include.html" . -}}
|
||||||
|
|
||||||
|
{{- range .AlternativeOutputFormats -}}
|
||||||
|
<link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" href="{{ .Permalink | safeURL }}">
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- partial "head/custom.html" . -}}
|
@ -1,3 +1,3 @@
|
|||||||
{{ $sass := resources.Get "scss/style.scss" }}
|
{{ $sass := resources.Get "scss/style.scss" }}
|
||||||
{{ $style := $sass | resources.ToCSS | minify }}
|
{{ $style := $sass | resources.ToCSS | minify }}
|
||||||
<link rel="stylesheet" href="{{ $style.Permalink }}">
|
<link rel="stylesheet" href="{{ $style.RelPermalink }}">
|
6
layouts/partials/helper/icon.html
Normal file
6
layouts/partials/helper/icon.html
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{{- $iconFile := resources.GetMatch (printf "icons/%s.svg" .) -}}
|
||||||
|
{{- if $iconFile -}}
|
||||||
|
{{- $iconFile.Content | safeHTML -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- errorf "Error: icon '%s.svg' is not found under 'assets/icons' folder" . -}}
|
||||||
|
{{- end -}}
|
@ -8,17 +8,23 @@
|
|||||||
<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 }}
|
||||||
|
|
||||||
<span class="emoji">{{ $.Site.Params.sidebar.emoji }}</span>
|
{{ with $.Site.Params.sidebar.emoji }}
|
||||||
|
<span class="emoji">{{ . }}</span>
|
||||||
|
{{ end }}
|
||||||
</figure>
|
</figure>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
<h1 class="site-name"><a href="{{ .Site.BaseURL }}">{{ .Site.Title }}</a></h1>
|
<h1 class="site-name"><a href="{{ .Site.BaseURL }}">{{ .Site.Title }}</a></h1>
|
||||||
@ -31,9 +37,9 @@
|
|||||||
{{ $active := or (eq $currentPage.Title .Name) (or ($currentPage.HasMenuCurrent "main" .) ($currentPage.IsMenuCurrent "main" .)) }}
|
{{ $active := or (eq $currentPage.Title .Name) (or ($currentPage.HasMenuCurrent "main" .) ($currentPage.IsMenuCurrent "main" .)) }}
|
||||||
|
|
||||||
<li {{ if $active }} class='current' {{ end }}>
|
<li {{ if $active }} class='current' {{ end }}>
|
||||||
<a href='{{ .URL | absLangURL }}'>
|
<a href='{{ .URL | relURL }}'>
|
||||||
{{ if .Pre }}
|
{{ if .Pre }}
|
||||||
{{ (resources.Get (delimit (slice "icons/" .Pre ".svg") "")).Content | safeHTML }}
|
{{ partial "helper/icon" .Pre }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
<span>{{- .Name -}}</span>
|
<span>{{- .Name -}}</span>
|
||||||
</a>
|
</a>
|
||||||
@ -43,7 +49,7 @@
|
|||||||
<li id="dark-mode-toggle">
|
<li id="dark-mode-toggle">
|
||||||
{{ (resources.Get "icons/toggle-left.svg").Content | safeHTML }}
|
{{ (resources.Get "icons/toggle-left.svg").Content | safeHTML }}
|
||||||
{{ (resources.Get "icons/toggle-right.svg").Content | safeHTML }}
|
{{ (resources.Get "icons/toggle-right.svg").Content | safeHTML }}
|
||||||
<span>{{ T "darkModeToggle" }}</span>
|
<span>{{ T "darkMode.toggle" }}</span>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
</aside>
|
</aside>
|
||||||
|
@ -1,29 +1,27 @@
|
|||||||
<section class="widget archives">
|
<section class="widget archives">
|
||||||
<div class="widget-icon">
|
<div class="widget-icon">
|
||||||
{{ (resources.Get "icons/infinity.svg").Content | safeHTML }}
|
{{ partial "helper/icon" "infinity" }}
|
||||||
</div>
|
</div>
|
||||||
<h1 class="widget-title">{{ T "widgetArchivesTitle" }}</h1>
|
<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 }}
|
||||||
{{ $filtered := ($pages | intersect $notHidden) }}
|
{{ $filtered := ($pages | intersect $notHidden) }}
|
||||||
{{ $archives := $filtered.GroupByDate "2006" }}
|
{{ $archives := $filtered.GroupByDate "2006" }}
|
||||||
|
|
||||||
{{ range first .Site.Params.widgets.archives.limit ($archives) }}
|
<div class="widget-archive--list">
|
||||||
{{ $id := lower (replace .Key " " "-") }}
|
{{ range $index, $item := first (add .Site.Params.widgets.archives.limit 1) ($archives) }}
|
||||||
<div class="archives-year">
|
{{- $id := lower (replace $item.Key " " "-") -}}
|
||||||
<a href="{{ $.Site.Params.widgets.archives.path | relLangURL }}#{{ $id }}">
|
<div class="archives-year">
|
||||||
<span class="year">{{ .Key }}</span>
|
<a href="{{ $.Site.Params.widgets.archives.path | relLangURL }}#{{ $id }}">
|
||||||
<span class="count">{{ len .Pages }}</span>
|
{{ if eq $index $.Site.Params.widgets.archives.limit }}
|
||||||
</a>
|
<span class="year">{{ T "widget.archives.more" }}</span>
|
||||||
</div>
|
{{ else }}
|
||||||
{{ end }}
|
<span class="year">{{ .Key }}</span>
|
||||||
|
<span class="count">{{ len $item.Pages }}</span>
|
||||||
{{ if gt (len $archives) .Site.Params.widgets.archives.limit }}
|
{{ end }}
|
||||||
<div class="archives-year">
|
</a>
|
||||||
<a href="{{ $.Site.Params.widgets.archives.path | relLangURL }}">
|
</div>
|
||||||
<span class="year">{{ T "widgetArchivesMore" }}</span>
|
{{ end }}
|
||||||
</a>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
{{ end }}
|
|
||||||
</section>
|
|
10
layouts/partials/widget/search.html
Normal file
10
layouts/partials/widget/search.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<form action="/search" class="search-form widget" {{ with .OutputFormats.Get "json" -}}data-json="{{ .Permalink }}" {{- end }}>
|
||||||
|
<p>
|
||||||
|
<label>{{ T "search.title" }}</label>
|
||||||
|
<input name="keyword" required placeholder="{{ T `search.placeholder` }}" />
|
||||||
|
|
||||||
|
<button title="Search">
|
||||||
|
{{ partial "helper/icon" "search" }}
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
|
</form>
|
@ -1,16 +1,13 @@
|
|||||||
{{ $tags := .Site.Taxonomies.tags.ByCount }}
|
|
||||||
|
|
||||||
<section class="widget tagCloud">
|
<section class="widget tagCloud">
|
||||||
<div class="widget-icon">
|
<div class="widget-icon">
|
||||||
{{ (resources.Get "icons/tag.svg").Content | safeHTML }}
|
{{ partial "helper/icon" "tag" }}
|
||||||
</div>
|
</div>
|
||||||
<h1 class="widget-title">{{ T "widgetTagCloudTitle" }}</h1>
|
<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 $tags }}
|
{{ range first .Site.Params.widgets.tagCloud.limit .Site.Taxonomies.tags.ByCount }}
|
||||||
{{ $term := $.Site.GetPage (printf "/tags/%s" .Term) }}
|
<a href="{{ .Page.RelPermalink }}" class="font_size_{{ .Count }}">
|
||||||
<a href="{{ $term.Permalink }}" class="font_size_{{ .Count }}">
|
{{ .Page.Title }}
|
||||||
{{ $term.Title | humanize }}
|
|
||||||
</a>
|
</a>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
|
42
layouts/rss.xml
Normal file
42
layouts/rss.xml
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
{{- $pages := where .Site.RegularPages "Type" "in" .Site.Params.mainSections -}}
|
||||||
|
{{- $notHidden := where .Site.RegularPages "Params.hidden" "!=" true -}}
|
||||||
|
{{- $filtered := ($pages | intersect $notHidden) -}}
|
||||||
|
{{- $limit := .Site.Config.Services.RSS.Limit -}}
|
||||||
|
{{- if ge $limit 1 -}}
|
||||||
|
{{- $filtered = $filtered | first $limit -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
|
||||||
|
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||||
|
<channel>
|
||||||
|
<title>{{ if eq .Title .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}{{ end }}</title>
|
||||||
|
<link>{{ .Permalink }}</link>
|
||||||
|
<description>Recent content {{ if ne .Title .Site.Title }}{{ with .Title }}in {{.}} {{ end }}{{ end }}on {{ .Site.Title }}</description>
|
||||||
|
<generator>Hugo -- gohugo.io</generator>{{ with .Site.LanguageCode }}
|
||||||
|
<language>{{.}}</language>{{end}}{{ with .Site.Author.email }}
|
||||||
|
<managingEditor>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</managingEditor>{{end}}{{ with .Site.Author.email }}
|
||||||
|
<webMaster>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</webMaster>{{end}}{{ with .Site.Copyright }}
|
||||||
|
<copyright>{{.}}</copyright>{{end}}{{ if not .Date.IsZero }}
|
||||||
|
<lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>{{ end }}
|
||||||
|
{{- with .OutputFormats.Get "RSS" -}}
|
||||||
|
{{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
|
||||||
|
{{- end -}}
|
||||||
|
{{ range $filtered }}
|
||||||
|
{{- $content := safeHTML (.Summary | html) -}}
|
||||||
|
{{- if .Site.Params.rssFullContent -}}
|
||||||
|
{{- $content = safeHTML (.Content | html) -}}
|
||||||
|
{{- end -}}
|
||||||
|
<item>
|
||||||
|
<title>{{ .Title }}</title>
|
||||||
|
<link>{{ .Permalink }}</link>
|
||||||
|
<pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
|
||||||
|
{{ with .Site.Author.email }}<author>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</author>{{end}}
|
||||||
|
<guid>{{ .Permalink }}</guid>
|
||||||
|
<description>
|
||||||
|
{{- $image := partial "helper/image" (dict "Context" . "Type" "rss") -}}
|
||||||
|
{{- if $image.exists -}}
|
||||||
|
{{ "<" | html }}img src="{{ $image.permalink | absURL }}" alt="Featured image of post {{ .Title }}" {{ "/>" | html}}
|
||||||
|
{{- end -}}{{ $content }}</description>
|
||||||
|
</item>
|
||||||
|
{{ end }}
|
||||||
|
</channel>
|
||||||
|
</rss>
|
@ -2,7 +2,7 @@
|
|||||||
publish = "exampleSite/public"
|
publish = "exampleSite/public"
|
||||||
|
|
||||||
[build.environment]
|
[build.environment]
|
||||||
HUGO_VERSION = "0.74.3"
|
HUGO_VERSION = "0.79.0"
|
||||||
HUGO_THEME = "repo"
|
HUGO_THEME = "repo"
|
||||||
|
|
||||||
[context.production]
|
[context.production]
|
||||||
|
File diff suppressed because one or more lines are too long
@ -5,7 +5,7 @@ name = "Stack"
|
|||||||
license = "GPL-3.0-only"
|
license = "GPL-3.0-only"
|
||||||
licenselink = "https://github.com/CaiJimmy/hugo-theme-stack/blob/master/LICENSE"
|
licenselink = "https://github.com/CaiJimmy/hugo-theme-stack/blob/master/LICENSE"
|
||||||
description = "Card-style Hugo theme designed for bloggers"
|
description = "Card-style Hugo theme designed for bloggers"
|
||||||
homepage = "https://blog.jimmycai.com/p/hugo-theme-stack"
|
homepage = "https://theme-stack.jimmycai.com"
|
||||||
tags = [
|
tags = [
|
||||||
"blog",
|
"blog",
|
||||||
"responsive",
|
"responsive",
|
||||||
@ -24,4 +24,4 @@ min_version = "0.74.0"
|
|||||||
|
|
||||||
[author]
|
[author]
|
||||||
name = "Jimmy Cai"
|
name = "Jimmy Cai"
|
||||||
homepage = "https://jimmycai.com"
|
homepage = "https://jimmycai.com"
|
||||||
|
Loading…
Reference in New Issue
Block a user