diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index a222d4e..95f0c18 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1,2 @@ -ko_fi: jimmycai \ No newline at end of file +ko_fi: jimmycai +github: CaiJimmy diff --git a/README.md b/README.md index 0e6caa2..4289b30 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,10 @@ > Card-style Hugo theme designed for bloggers. +## Quickstart + +Use this template: [CaiJimmy/hugo-theme-stack-starter](https://github.com/CaiJimmy/hugo-theme-stack-starter) + ## Demo [Example Site](https://demo.stack.jimmycai.com/) @@ -28,6 +32,7 @@ Stack is a simple card-style Hugo theme designed for bloggers, some of its featu - Properly cropped thumbnails - Subsection support - Table of contents +- Multilingual mode and RTL support ## Requirements @@ -35,7 +40,7 @@ It's necessary to use **Hugo Extended ≥ 0.87.0**. ## Installation -* Route 1: Clone / Download this repository to `theme` folder +* Route 1: Clone / Download this repository to `themes` folder * Route 2: Turn your site into a hugo module and add this theme as a module dependency Edit your site config following `exampleSite/config.yaml`. diff --git a/assets/icons/categories.svg b/assets/icons/categories.svg new file mode 100644 index 0000000..e00ab1d --- /dev/null +++ b/assets/icons/categories.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/icons/language.svg b/assets/icons/language.svg new file mode 100644 index 0000000..66ede1c --- /dev/null +++ b/assets/icons/language.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/scss/general.scss b/assets/scss/general.scss new file mode 100644 index 0000000..e12bb0e --- /dev/null +++ b/assets/scss/general.scss @@ -0,0 +1,31 @@ +a { + text-decoration: none; + color: var(--accent-color); + + &:hover { + color: var(--accent-color-darker); + } + + &.link { + box-shadow: 0px -2px 0px rgba(var(--link-background-color), var(--link-background-opacity)) inset; + transition: all 0.3s ease; + + &:hover { + box-shadow: 0px calc(-1rem * var(--article-line-height)) 0px rgba(var(--link-background-color), var(--link-background-opacity-hover)) inset; + } + } +} + +.section-title { + text-transform: uppercase; + margin-top: 0; + margin-bottom: 10px; + display: block; + font-size: 1.6rem; + font-weight: bold; + color: var(--body-text-color); + + a { + color: var(--body-text-color); + } +} diff --git a/assets/scss/grid.scss b/assets/scss/grid.scss index a0eddca..84967ef 100644 --- a/assets/scss/grid.scss +++ b/assets/scss/grid.scss @@ -11,7 +11,7 @@ /// Display right sidebar when min-width: lg @include respond(lg) { - display: block; + display: flex; } } @@ -67,24 +67,6 @@ } } - &.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%; } @@ -94,15 +76,22 @@ main.main { min-width: 0; max-width: 100%; flex-grow: 1; - padding-top: var(--main-top-padding); + display: flex; + flex-direction: column; + gap: var(--section-separation); + + @include respond(md) { + padding-top: var(--main-top-padding); + } } .main-container { min-height: 100vh; align-items: flex-start; padding: 0 15px; - column-gap: var(--section-separation); - + gap: var(--section-separation); + padding-top: var(--main-top-padding); + @include respond(md) { padding: 0 20px; } diff --git a/assets/scss/partials/article.scss b/assets/scss/partials/article.scss index 459c22f..f085ff0 100644 --- a/assets/scss/partials/article.scss +++ b/assets/scss/partials/article.scss @@ -2,6 +2,7 @@ .article-list { display: flex; flex-direction: column; + gap: var(--section-separation); article { display: flex; @@ -17,10 +18,6 @@ box-shadow: var(--shadow-l2); } - &:not(:last-of-type) { - margin-bottom: var(--section-separation); - } - .article-image { img { width: 100%; @@ -52,13 +49,13 @@ display: flex; flex-direction: column; justify-content: center; - padding: var(--card-padding); + gap: 15px; } .article-title { font-weight: 600; - margin: 10px 0; + margin: 0; color: var(--card-text-color-main); font-size: 2.2rem; @@ -73,52 +70,58 @@ color: var(--card-text-color-main); } } - - & + .article-subtitle { - margin-top: 0; - } } .article-subtitle { font-weight: normal; color: var(--card-text-color-secondary); - margin: 5px 0; line-height: 1.5; - + margin: 0; font-size: 1.75rem; @include respond(xl) { font-size: 2rem; } } -.article-time { +.article-title-wrapper { + display: flex; + flex-direction: column; + gap: 8px; +} + +.article-time, +.article-translations { display: flex; align-items: center; color: var(--card-text-color-tertiary); gap: 15px; - margin-top: 10px; flex-wrap: wrap; svg { vertical-align: middle; - margin-right: 15px; width: 20px; height: 20px; stroke-width: 1.33; } - time { + time, + a { font-size: 1.4rem; + color: var(--card-text-color-tertiary); } & > div { display: inline-flex; align-items: center; + gap: 15px; } } .article-category, .article-tags { + display: flex; + gap: 10px; + a { color: var(--accent-color-text); background-color: var(--accent-color); @@ -126,8 +129,6 @@ border-radius: var(--tag-border-radius); display: inline-block; font-size: 1.4rem; - margin-right: 10px; - margin-bottom: 10px; transition: background-color 0.5s ease; &:hover { @@ -148,15 +149,12 @@ --image-size: 60px; } - & + .pagination { - margin-top: var(--section-separation); - } - article { & > a { display: flex; align-items: center; padding: var(--small-card-padding); + gap: 15px; } &:not(:last-of-type) { @@ -166,8 +164,8 @@ .article-details { flex-grow: 1; padding: 0; - padding-right: 15px; min-height: var(--image-size); + gap: 10px; } .article-title { diff --git a/assets/scss/partials/base.scss b/assets/scss/partials/base.scss index 408629e..efb4b8f 100644 --- a/assets/scss/partials/base.scss +++ b/assets/scss/partials/base.scss @@ -22,3 +22,17 @@ body { scrollbar-color: var(--scrollbar-thumb) transparent; } /**/ + +/* scrollbar styles for Chromium */ +::-webkit-scrollbar { + height: auto; +} + +::-webkit-scrollbar-thumb { + background-color: var(--scrollbar-thumb); +} + +::-webkit-scrollbar-track { + background-color: transparent; +} +/**/ \ No newline at end of file diff --git a/assets/scss/partials/footer.scss b/assets/scss/partials/footer.scss index 1c60dc7..ccb7394 100644 --- a/assets/scss/partials/footer.scss +++ b/assets/scss/partials/footer.scss @@ -2,7 +2,6 @@ footer.site-footer { padding: 20px 0 var(--section-separation) 0; font-size: 1.4rem; line-height: 1.75; - margin-top: var(--section-separation); &:before { content: ""; diff --git a/assets/scss/partials/layout/archives.scss b/assets/scss/partials/layout/archives.scss deleted file mode 100644 index 34e5f62..0000000 --- a/assets/scss/partials/layout/archives.scss +++ /dev/null @@ -1,3 +0,0 @@ -.archives-group { - margin-bottom: var(--section-separation); -} \ No newline at end of file diff --git a/assets/scss/partials/layout/article.scss b/assets/scss/partials/layout/article.scss index 78ed81c..d789e10 100644 --- a/assets/scss/partials/layout/article.scss +++ b/assets/scss/partials/layout/article.scss @@ -13,10 +13,6 @@ box-shadow: var(--shadow-l1); overflow: hidden; - &.main-article { - margin-bottom: var(--section-separation); - } - .article-header { .article-image { img { @@ -57,11 +53,11 @@ display: flex; align-items: center; font-size: 1.4rem; + gap: 15px; svg { width: 20px; height: 20px; - margin-right: 15px; stroke-width: 1.33; } } @@ -81,109 +77,6 @@ } } -#article-toolbar { - display: flex; - align-items: center; - margin: 20px 0; - - @include respond(md) { - display: none; - } - - .back-home { - background: var(--card-background); - border-radius: var(--tag-border-radius); - color: var(--card-text-color-tertiary); - margin-right: 30px; - display: inline-flex; - align-items: center; - font-size: 1.4rem; - text-transform: uppercase; - padding: 10px 20px 10px 15px; - - transition: box-shadow 0.3s ease; - - box-shadow: var(--shadow-l1); - - &:hover { - box-shadow: var(--shadow-l2); - } - - svg { - margin-right: 5px; - width: 20px; - height: 20px; - } - - span { - font-weight: 500; - white-space: nowrap; - } - } -} - -.article-page.has-toc { - - .left-sidebar { - display: none; - } - - .right-sidebar { - width: 100%; - padding: 0; - display: none; - - @include respond(xl) { - display: block; - top: var(--main-top-padding); - } - } - - #article-toolbar { - display: block; - - @include respond(md) { - padding: 0; - } - - @include respond(xl) { - margin-top: 0; - position: sticky; - top: var(--main-top-padding); - flex-shrink: 1; - - a { - background: transparent; - box-shadow: none; - border: 1px solid var(--body-text-color); - width: 100%; - margin-right: 0; - - svg { - flex-shrink: 0; - } - } - } - } - - .main-container { - align-items: start; - flex-direction: column; - - @include respond(xl) { - flex-direction: row; - } - } - - .main { - padding-top: 0; - - @include respond(xl) { - padding-top: var(--main-top-padding); - } - } -} - .widget--toc { background-color: var(--card-background); border-radius: var(--card-border-radius); @@ -273,11 +166,7 @@ } } -.related-contents--wrapper { - margin-bottom: var(--section-separation); -} - -.related-contents { +.related-content { overflow-x: auto; padding-bottom: 15px; @@ -322,9 +211,9 @@ h4, h5, h6 { - margin-left: calc((var(--card-padding)) * -1); - padding-left: calc(var(--card-padding) - var(--heading-border-size)); - border-left: var(--heading-border-size) solid var(--accent-color); + margin-inline-start: calc((var(--card-padding)) * -1); + padding-inline-start: calc(var(--card-padding) - var(--heading-border-size)); + border-inline-start: var(--heading-border-size) solid var(--accent-color); } figure { @@ -339,7 +228,7 @@ blockquote { position: relative; margin: 1.5em 0; - border-left: var(--blockquote-border-size) solid var(--card-separator-color); + border-inline-start: var(--blockquote-border-size) solid var(--card-separator-color); padding: 15px calc(var(--card-padding) - var(--blockquote-border-size)); background-color: var(--blockquote-background-color); } @@ -367,13 +256,10 @@ flex-direction: row; justify-content: center; margin: 1.5em 0; + gap: 10px; figure { margin: 0; - - & + figure { - margin-left: 10px; - } } } @@ -386,7 +272,10 @@ line-height: 1.428571429; word-break: break-all; padding: var(--card-padding); - + // keep Codeblocks LTR + [dir="rtl"] & { + direction: ltr; + } code { color: unset; border: none; @@ -395,6 +284,44 @@ } } + .highlight { + background-color: var(--pre-background-color); + padding: var(--card-padding); + position: relative; + + &:hover { + .copyCodeButton { + opacity: 1; + } + } + // keep Codeblocks LTR + [dir="rtl"] & { + direction: ltr; + } + pre { + margin: initial; + padding: 0; + margin: 0; + width: auto; + } + } + + .copyCodeButton { + position: absolute; + top: calc(var(--card-padding)); + right: calc(var(--card-padding)); + background: var(--card-background); + border: none; + box-shadow: var(--shadow-l2); + border-radius: var(--tag-border-radius); + padding: 8px 16px; + color: var(--card-text-color-main); + cursor: pointer; + font-size: 14px; + opacity: 0; + transition: opacity 0.3s ease; + } + .table-wrapper { padding: 0 var(--card-padding); overflow-x: auto; @@ -449,6 +376,7 @@ /// Negative margins blockquote, figure, + .highlight, pre, .gallery, .video-wrapper, @@ -458,30 +386,4 @@ margin-right: calc((var(--card-padding)) * -1); width: calc(100% + var(--card-padding) * 2); } - - .highlight { - position: relative; - - &:hover { - .copyCodeButton { - opacity: 1; - } - } - } - - .copyCodeButton { - position: absolute; - top: calc(var(--card-padding)); - right: 0; - background: var(--card-background); - border: none; - box-shadow: var(--shadow-l2); - border-radius: var(--tag-border-radius); - padding: 8px 16px; - color: var(--card-text-color-main); - cursor: pointer; - font-size: 14px; - opacity: 0; - transition: opacity 0.3s ease; - } } diff --git a/assets/scss/partials/layout/list.scss b/assets/scss/partials/layout/list.scss index 1a0e346..d7815ca 100644 --- a/assets/scss/partials/layout/list.scss +++ b/assets/scss/partials/layout/list.scss @@ -3,21 +3,16 @@ background-color: var(--card-background); padding: var(--small-card-padding); box-shadow: var(--shadow-l1); - margin-bottom: var(--section-separation); display: flex; align-items: center; + gap: 20px; --separation: 15px; .section-term { font-size: 2.2rem; margin: 0; - margin-top: calc(var(--separation) / 2); color: var(--card-text-color-main); - - & + .section-description { - margin-top: var(--separation); - } } .section-description { @@ -29,7 +24,9 @@ .section-details { flex-grow: 1; - margin-right: 20px; + display: flex; + flex-direction: column; + gap: 8px; } .section-image { @@ -49,7 +46,6 @@ } .subsection-list { - margin-bottom: var(--section-separation); overflow-x: auto; .article-list--tile { diff --git a/assets/scss/partials/layout/search.scss b/assets/scss/partials/layout/search.scss index b390a7b..89cdcef 100644 --- a/assets/scss/partials/layout/search.scss +++ b/assets/scss/partials/layout/search.scss @@ -1,5 +1,4 @@ .search-form { - margin-bottom: var(--section-separation); position: relative; --button-size: 80px; @@ -25,7 +24,7 @@ label { position: absolute; top: 15px; - left: 20px; + inset-inline-start: 20px; font-size: 1.4rem; color: var(--card-text-color-tertiary); } @@ -52,7 +51,7 @@ button { position: absolute; - right: 0; + inset-inline-end: 0; top: 0; height: 100%; width: var(--button-size); @@ -79,4 +78,5 @@ height: 20px; } } + } \ No newline at end of file diff --git a/assets/scss/partials/menu.scss b/assets/scss/partials/menu.scss index 1d612d1..4f29c9f 100644 --- a/assets/scss/partials/menu.scss +++ b/assets/scss/partials/menu.scss @@ -101,11 +101,16 @@ background: none; border: none; position: absolute; - right: 30px; - top: 30px; + right: 0; + top: 0; z-index: 2; cursor: pointer; + [dir="rtl"] & { + left: 0; + right: auto; + } + @include respond(md) { display: none; } @@ -125,21 +130,31 @@ .menu { padding-left: 0; list-style: none; - display: flex; flex-direction: column; overflow-y: auto; flex-grow: 1; font-size: 1.4rem; - background-color: var(--card-background); - padding: 15px 0; + box-shadow: var(--shadow-l1); display: none; + margin: 0 calc(var(--container-padding) * -1); - margin: 0 -15px; + padding: 30px 30px; + @include respond(xl) { + padding: 15px 0; + } + + &, + .menu-bottom-section { + gap: 30px; + @include respond(xl) { + gap: 25px; + } + } &.show { - display: block; + display: flex; } @include respond(md) { @@ -149,34 +164,19 @@ padding: 0; box-shadow: none; margin: 0; - margin-top: var(--sidebar-element-separation); - } - - @include respond(xl) { - margin-top: 30px; } li { position: relative; vertical-align: middle; - padding: 10px 30px; - - &:not(:last-of-type) { - margin-bottom: 15px; - - @include respond(xl) { - margin-bottom: 20px; - } - } + padding: 0; @include respond(md) { width: 100%; - padding: 10px 0; } svg { stroke-width: 1.33; - margin-right: 40px; width: 20px; height: 20px; @@ -187,6 +187,7 @@ display: inline-flex; align-items: center; color: var(--body-text-color); + gap: var(--menu-icon-separation); } span { @@ -200,11 +201,19 @@ } } } + + .menu-bottom-section { + margin-top: auto; + display: flex; + flex-direction: column; + width: 100%; + } } .social-menu { list-style: none; - padding: 0%; + padding: 0; + margin: 0; display: flex; flex-direction: row; gap: 10px; diff --git a/assets/scss/partials/pagination.scss b/assets/scss/partials/pagination.scss index a6c6882..ca46780 100644 --- a/assets/scss/partials/pagination.scss +++ b/assets/scss/partials/pagination.scss @@ -5,7 +5,6 @@ border-radius: var(--card-border-radius); overflow: hidden; flex-wrap: wrap; - margin: var(--section-separation) 0; .page-link { padding: 16px 32px; diff --git a/assets/scss/partials/sidebar.scss b/assets/scss/partials/sidebar.scss index 462729d..95310ca 100644 --- a/assets/scss/partials/sidebar.scss +++ b/assets/scss/partials/sidebar.scss @@ -11,13 +11,15 @@ flex-direction: column; flex-shrink: 0; align-self: stretch; - - width: 100%; - padding: 30px 0 15px 0; + gap: var(--sidebar-element-separation); max-width: none; + width: 100%; + position: relative; - --sidebar-avatar-size: 120px; + --sidebar-avatar-size: 100px; --sidebar-element-separation: 20px; + --emoji-size: 40px; + --emoji-font-size: 20px; @include respond(md) { width: auto; @@ -27,18 +29,49 @@ } @include respond(2xl) { - --sidebar-avatar-size: 140px; + --sidebar-avatar-size: 120px; --sidebar-element-separation: 25px; + --emoji-size: 40px; } &.sticky { top: 0; } + + &.compact { + --sidebar-avatar-size: 80px; + --emoji-size: 30px; + --emoji-font-size: 15px; + + header { + @include respond(lg) { + flex-direction: row; + } + + .site-meta { + gap: 5px; + } + + .site-name { + font-size: 1.4rem; + + @include respond(2xl) { + font-size: 1.75rem; + } + } + + .site-description { + font-size: 1.4rem; + } + } + } } .right-sidebar { - flex-shrink: 0; + width: 100%; display: none; + flex-direction: column; + gap: var(--widget-separation); &.sticky { top: 0; @@ -49,11 +82,12 @@ } } -.site-info { +.sidebar header { z-index: 1; transition: box-shadow 0.5s ease; - - padding: 15px; + display: flex; + flex-direction: column; + gap: var(--sidebar-element-separation); @include respond(md) { padding: 0; @@ -64,8 +98,7 @@ margin: 0; width: var(--sidebar-avatar-size); height: var(--sidebar-avatar-size); - - margin-bottom: var(--sidebar-element-separation); + flex-shrink: 0; .site-logo { width: 100%; @@ -76,58 +109,44 @@ .emoji { position: absolute; - width: 40px; - height: 40px; - line-height: 40px; + width: var(--emoji-size); + height: var(--emoji-size); + line-height: var(--emoji-size); border-radius: 100%; bottom: 0; right: 0; text-align: center; - font-size: 20px; + font-size: var(--emoji-font-size); background-color: var(--card-background); box-shadow: var(--shadow-l2); - - @include respond(2xl) { - width: 50px; - height: 50px; - line-height: 50px; - } } } + .site-meta { + display: flex; + flex-direction: column; + gap: 10px; + justify-content: center; + } + .site-name { color: var(--accent-color); margin: 0; - font-size: 1.8rem; - - @include respond(2xl) { - font-size: 2rem; - } - } - - .site-description { - color: var(--body-text-color); - font-weight: normal; - margin: 10px 0; font-size: 1.6rem; @include respond(2xl) { font-size: 1.8rem; } } -} -.sidebar { - .widget { - margin-bottom: var(--section-separation); + .site-description { + color: var(--body-text-color); + font-weight: normal; + margin: 0; + font-size: 1.4rem; - &:not(:last-of-type):after { - content: ""; - width: 100px; - height: 2px; - background-color: var(--body-text-color); - display: block; - margin-top: var(--section-separation); + @include respond(2xl) { + font-size: 1.6rem; } } } @@ -153,8 +172,27 @@ display: flex; align-items: center; cursor: pointer; + gap: var(--menu-icon-separation); .icon-tabler-toggle-right { display: none; } } + +#i18n-switch { + color: var(--body-text-color); + display: inline-flex; + align-content: center; + gap: var(--menu-icon-separation); + + select { + border: 0; + background-color: transparent; + color: var(--body-text-color); + + option { + color: var(--card-text-color-main); + background-color: var(--card-background); + } + } +} diff --git a/assets/scss/partials/widgets.scss b/assets/scss/partials/widgets.scss index 33a02dd..42cfcc2 100644 --- a/assets/scss/partials/widgets.scss +++ b/assets/scss/partials/widgets.scss @@ -1,4 +1,7 @@ .widget { + display: flex; + flex-direction: column; + .widget-icon { svg { width: 32px; @@ -14,16 +17,14 @@ .tagCloud-tags { display: flex; flex-wrap: wrap; + gap: 10px; a { background: var(--card-background); box-shadow: var(--shadow-l1); border-radius: var(--tag-border-radius); padding: 8px 20px; - color: var(--card-text-color-main); - margin-bottom: 10px; - margin-right: 5px; font-size: 1.4rem; transition: box-shadow 0.3s ease; diff --git a/assets/scss/style.scss b/assets/scss/style.scss index 2f5aac9..e50d400 100644 --- a/assets/scss/style.scss +++ b/assets/scss/style.scss @@ -19,42 +19,10 @@ @import "partials/pagination.scss"; @import "partials/sidebar.scss"; @import "partials/base.scss"; -@import "partials/layout/archives.scss"; @import "partials/layout/article.scss"; @import "partials/layout/list.scss"; @import "partials/layout/404.scss"; @import "partials/layout/search.scss"; +@import "general.scss"; @import "custom.scss"; - -a { - text-decoration: none; - color: var(--accent-color); - - &:hover { - color: var(--accent-color-darker); - } - - &.link { - box-shadow: 0px -2px 0px rgba(var(--link-background-color), var(--link-background-opacity)) inset; - transition: all 0.3s ease; - - &:hover { - box-shadow: 0px -10px 0px rgba(var(--link-background-color), var(--link-background-opacity-hover)) inset; - } - } -} - -.section-title { - text-transform: uppercase; - margin-top: 0; - margin-bottom: 10px; - display: block; - font-size: 1.6rem; - font-weight: bold; - color: var(--body-text-color); - - a { - color: var(--body-text-color); - } -} diff --git a/assets/scss/variables.scss b/assets/scss/variables.scss index 8e371d6..afddb80 100644 --- a/assets/scss/variables.scss +++ b/assets/scss/variables.scss @@ -1,26 +1,11 @@ $defaultTagBackgrounds: #8ea885, #df7988, #0177b8, #ffb900, #6b69d6; $defaultTagColors: #fff, #fff, #fff, #fff, #fff; -[data-scheme="light"] { - --pre-text-color: #272822; - --pre-background-color: #fafafa; - @import "partials/highlight/light.scss"; -} - -[data-scheme="dark"] { - color-scheme: dark; - --pre-text-color: #f8f8f2; - --pre-background-color: #272822; - @import "partials/highlight/dark.scss"; -} - /* * Global style */ :root { - @include respond(md) { - --main-top-padding: 35px; - } + --main-top-padding: 35px; @include respond(xl) { --main-top-padding: 50px; @@ -46,7 +31,7 @@ $defaultTagColors: #fff, #fff, #fff, #fff, #fff; --accent-color-darker: #bdc3c7; --accent-color-text: #000; --body-text-color: rgba(255, 255, 255, 0.7); - --scrollbar-thumb: #424242; + --scrollbar-thumb: hsl(0, 0%, 40%); --scrollbar-track: var(--body-background); } } @@ -160,3 +145,21 @@ $defaultTagColors: #fff, #fff, #fff, #fff, #fff; --shadow-l4: 0px 24px 32px rgba(0, 0, 0, 0.04), 0px 16px 24px rgba(0, 0, 0, 0.04), 0px 4px 8px rgba(0, 0, 0, 0.04), 0px 0px 1px rgba(0, 0, 0, 0.04); } + +[data-scheme="light"] { + --pre-text-color: #272822; + --pre-background-color: #fafafa; + @import "partials/highlight/light.scss"; +} + +[data-scheme="dark"] { + --pre-text-color: #f8f8f2; + --pre-background-color: #272822; + @import "partials/highlight/dark.scss"; +} + +:root { + --menu-icon-separation: 40px; + --container-padding: 15px; + --widget-separation: var(--section-separation); +} diff --git a/assets/ts/gallery.ts b/assets/ts/gallery.ts index 5de13a2..9840f1e 100644 --- a/assets/ts/gallery.ts +++ b/assets/ts/gallery.ts @@ -57,6 +57,60 @@ class StackGallery { } public static createGallery(container: HTMLElement) { + /// The process of wrapping image with figure tag is done using JavaScript instead of only Hugo markdown render hook + /// because it can not detect whether image is being wrapped by a link or not + /// and it lead to a invalid HTML construction (
) + + const images = container.querySelectorAll('img.gallery-image'); + for (const img of Array.from(images)) { + /// Images are wrapped with figure tag if the paragraph has only images without texts + /// This is done to allow inline images within paragraphs + const paragraph = img.closest('p'); + + if (!paragraph || !container.contains(paragraph)) continue; + + if (paragraph.textContent.trim() == '') { + /// Once we insert figcaption, this check no longer works + /// So we add a class to paragraph to mark it + paragraph.classList.add('no-text'); + } + + let isNewLineImage = paragraph.classList.contains('no-text'); + if (!isNewLineImage) continue; + + const hasLink = img.parentElement.tagName == 'A'; + + let el: HTMLElement = img; + /// Wrap image with figure tag, with flex-grow and flex-basis values extracted from img's data attributes + const figure = document.createElement('figure'); + figure.style.setProperty('flex-grow', img.getAttribute('data-flex-grow') || '1'); + figure.style.setProperty('flex-basis', img.getAttribute('data-flex-basis') || '0'); + if (hasLink) { + /// Wrap if it exists + el = img.parentElement; + } + el.parentElement.insertBefore(figure, el); + figure.appendChild(el); + + /// Add figcaption if it exists + if (img.hasAttribute('alt')) { + const figcaption = document.createElement('figcaption'); + figcaption.innerText = img.getAttribute('alt'); + figure.appendChild(figcaption); + } + + /// Wrap img tag with tag if image was not wrapped by tag + if (!hasLink) { + figure.className = 'gallery-image'; + + const a = document.createElement('a'); + a.href = img.src; + a.setAttribute('target', '_blank'); + img.parentNode.insertBefore(a, img); + a.appendChild(img); + } + } + const figuresEl = container.querySelectorAll('figure.gallery-image'); let currentGallery = []; diff --git a/assets/ts/main.ts b/assets/ts/main.ts index 20de18c..f3160ae 100644 --- a/assets/ts/main.ts +++ b/assets/ts/main.ts @@ -62,20 +62,21 @@ let Stack = { /** * Add copy button to code block */ - const codeBlocks = document.querySelectorAll('.article-content > div.highlight'); + const highlights = document.querySelectorAll('.article-content div.highlight'); const copyText = `Copy`, copiedText = `Copied!`; - codeBlocks.forEach(codeBlock => { + + highlights.forEach(highlight => { const copyButton = document.createElement('button'); copyButton.innerHTML = copyText; copyButton.classList.add('copyCodeButton'); - codeBlock.appendChild(copyButton); + highlight.appendChild(copyButton); - const pre = codeBlock.getElementsByTagName('pre'); - const code = pre[0].textContent; + const codeBlock = highlight.querySelector('code[data-lang]'); + if (!codeBlock) return; copyButton.addEventListener('click', () => { - navigator.clipboard.writeText(code) + navigator.clipboard.writeText(codeBlock.textContent) .then(() => { copyButton.textContent = copiedText; diff --git a/config.yaml b/config.yaml index 0e5283c..93367bb 100644 --- a/config.yaml +++ b/config.yaml @@ -19,6 +19,7 @@ params: lastUpdated: Jan 02, 2006 15:04 MST sidebar: + compact: false emoji: subtitle: avatar: @@ -95,6 +96,7 @@ params: darkTheme: reactionsEnabled: 1 emitMetadata: 0 + lang: gitalk: owner: @@ -108,16 +110,8 @@ params: id: widgets: - enabled: - - search - - archives - - tag-cloud - - archives: - limit: 5 - - tagCloud: - limit: 10 + homepage: [] + page: [] opengraph: twitter: diff --git a/exampleSite/config.yaml b/exampleSite/config.yaml index a67b4aa..b5049ed 100644 --- a/exampleSite/config.yaml +++ b/exampleSite/config.yaml @@ -4,6 +4,21 @@ theme: hugo-theme-stack paginate: 5 title: Example Site +languages: + en: + languageName: English + title: Example Site + weight: 1 + zh-cn: + languageName: 中文 + title: 演示站点 + weight: 2 + ar: + languageName: عربي + languagedirection: rtl + title: موقع تجريبي + weight: 3 + # Change it to your Disqus shortname before using disqusShortname: hugo-theme-stack @@ -11,7 +26,7 @@ disqusShortname: hugo-theme-stack googleAnalytics: # Theme i18n support -# Available values: en, fr, id, ja, ko, pt-br, zh-cn, zh-tw, es, de, nl, it, th, el, uk +# Available values: ar, ca, de, el, en, es, fr, hu, id, it, ja, ko, nl, pt-br, th, uk, zh-cn, zh-hk, zh-tw DefaultContentLanguage: en # Set hasCJKLanguage to true if DefaultContentLanguage is in [zh-cn ja ko] @@ -109,7 +124,7 @@ params: defaultHomeserverUrl: "https://matrix.cactus.chat:8448" serverName: "cactus.chat" siteName: "" # You must insert a unique identifier here matching the one you registered (See https://cactus.chat/docs/getting-started/quick-start/#register-your-site) - + giscus: repo: repoID: @@ -122,26 +137,29 @@ params: emitMetadata: 0 gitalk: - owner: - admin: - repo: - clientID: - clientSecret: - + owner: + admin: + repo: + clientID: + clientSecret: + cusdis: - host: - id: + host: + id: widgets: - enabled: - - search - - archives - - tag-cloud - - archives: - limit: 5 - - tagCloud: - limit: 10 + homepage: + - type: search + - type: archives + params: + limit: 5 + - type: categories + params: + limit: 10 + - type: tag-cloud + params: + limit: 10 + page: + - type: toc opengraph: twitter: @@ -174,28 +192,20 @@ params: ### See https://docs.stack.jimmycai.com/configuration/custom-menu.html ### To remove about, archive and search page menu item, remove `menu` field from their FrontMatter menu: - main: - - identifier: home - name: Home - url: / - weight: -100 - params: - ### For demonstration purpose, the home link will be open in a new tab - newTab: true - icon: home - + main: [] + social: - identifier: github name: GitHub url: https://github.com/CaiJimmy/hugo-theme-stack params: - icon: brand-github - + icon: brand-github + - identifier: twitter name: Twitter url: https://twitter.com params: - icon: brand-twitter + icon: brand-twitter related: includeNewer: true @@ -219,3 +229,9 @@ markup: startLevel: 2 highlight: noClasses: false + codeFences: true + guessSyntax: true + lineNoStart: 1 + lineNos: true + lineNumbersInTable: true + tabWidth: 4 diff --git a/exampleSite/content/_index.md b/exampleSite/content/_index.md new file mode 100644 index 0000000..530dfe8 --- /dev/null +++ b/exampleSite/content/_index.md @@ -0,0 +1,8 @@ +--- +menu: + main: + name: Home + weight: -100 + params: + icon: home +--- \ No newline at end of file diff --git a/exampleSite/content/_index.zh-cn.md b/exampleSite/content/_index.zh-cn.md new file mode 100644 index 0000000..e4b59a8 --- /dev/null +++ b/exampleSite/content/_index.zh-cn.md @@ -0,0 +1,8 @@ +--- +menu: + main: + name: 主页 + weight: -100 + params: + icon: home +--- \ No newline at end of file diff --git a/exampleSite/content/page/about/index.zh-cn.md b/exampleSite/content/page/about/index.zh-cn.md new file mode 100644 index 0000000..0284003 --- /dev/null +++ b/exampleSite/content/page/about/index.zh-cn.md @@ -0,0 +1,10 @@ +--- +title: 关于 +menu: + main: + weight: -90 + params: + icon: user +--- + +This is a test page for i18n support. \ No newline at end of file diff --git a/exampleSite/content/post/chinese-test/index.md b/exampleSite/content/post/chinese-test/index.zh-cn.md similarity index 100% rename from exampleSite/content/post/chinese-test/index.md rename to exampleSite/content/post/chinese-test/index.zh-cn.md diff --git a/exampleSite/content/post/markdown-syntax/index.md b/exampleSite/content/post/markdown-syntax/index.md index be381a0..0254cca 100644 --- a/exampleSite/content/post/markdown-syntax/index.md +++ b/exampleSite/content/post/markdown-syntax/index.md @@ -162,3 +162,7 @@ Xn + Yn = Zn Press CTRL+ALT+Delete to end the session. Most salamanders are nocturnal, and hunt for insects, worms, and other small creatures. + +## Hyperlinked image + +[![Google](https://www.google.com/images/branding/googlelogo/1x/googlelogo_light_color_272x92dp.png)](https://google.com) \ No newline at end of file diff --git a/exampleSite/content/post/placeholder-text/index.ar.md b/exampleSite/content/post/placeholder-text/index.ar.md new file mode 100644 index 0000000..b0328f4 --- /dev/null +++ b/exampleSite/content/post/placeholder-text/index.ar.md @@ -0,0 +1,32 @@ ++++ +author = "Hugo Authors" +title = "مثال نص" +date = "2019-03-09" +description = "هذا النص هو مثال لنص يمكن أن يستبدل في نفس المساحة" +categories = [ + "تجربة", + "تجربة مع فراغات" +] +tags = [ + "ماركداون", + "نص", + "وسم مع فراغات" +] +image = "matt-le-SJSpo9hQf7s-unsplash.jpg" ++++ +## فقرة 1 + +هذا النص هو مثال لنص يمكن أن يستبدل في نفس المساحة، لقد تم توليد هذا النص من [مولد النص العربى](https://colorslab.com/textgator/)، حيث يمكنك أن تولد مثل هذا النص أو العديد من النصوص الأخرى إضافة إلى زيادة عدد الحروف التى يولدها التطبيق. +إذا كنت تحتاج إلى عدد أكبر من الفقرات يتيح لك مولد النص العربى زيادة عدد الفقرات كما تريد، النص لن يبدو مقسما ولا يحوي أخطاء لغوية، مولد النص العربى مفيد لمصممي المواقع على وجه الخصوص، حيث يحتاج العميل فى كثير من الأحيان أن يطلع على صورة حقيقية لتصميم الموقع. +ومن هنا وجب على المصمم أن يضع نصوصا مؤقتة على التصميم ليظهر للعميل الشكل كاملاً،دور مولد النص العربى أن يوفر على المصمم عناء البحث عن نص بديل لا علاقة له بالموضوع الذى يتحدث عنه التصميم فيظهر بشكل لا يليق. +هذا النص يمكن أن يتم تركيبه على أي تصميم دون مشكلة فلن يبدو وكأنه نص منسوخ، غير منظم، غير منسق، أو حتى غير مفهوم. لأنه مازال نصاً بديلاً ومؤقتاً. + +## فقرة 2 + +هذا النص هو مثال لنص يمكن أن يستبدل في نفس المساحة، لقد تم توليد هذا النص من [مولد النص العربى](https://colorslab.com/textgator/)، حيث يمكنك أن تولد مثل هذا النص أو العديد من النصوص الأخرى إضافة إلى زيادة عدد الحروف التى يولدها التطبيق. +إذا كنت تحتاج إلى عدد أكبر من الفقرات يتيح لك مولد النص العربى زيادة عدد الفقرات كما تريد، النص لن يبدو مقسما ولا يحوي أخطاء لغوية، مولد النص العربى مفيد لمصممي المواقع على وجه الخصوص، حيث يحتاج العميل فى كثير من الأحيان أن يطلع على صورة حقيقية لتصميم الموقع. +ومن هنا وجب على المصمم أن يضع نصوصا مؤقتة على التصميم ليظهر للعميل الشكل كاملاً،دور مولد النص العربى أن يوفر على المصمم عناء البحث عن نص بديل لا علاقة له بالموضوع الذى يتحدث عنه التصميم فيظهر بشكل لا يليق. +هذا النص يمكن أن يتم تركيبه على أي تصميم دون مشكلة فلن يبدو وكأنه نص منسوخ، غير منظم، غير منسق، أو حتى غير مفهوم. لأنه مازال نصاً بديلاً ومؤقتاً. + +## تجربة RTL +كلمة 1 Text كلمة 2 diff --git a/exampleSite/content/post/rich-content/index.md b/exampleSite/content/post/rich-content/index.md index af8a390..f2b45db 100644 --- a/exampleSite/content/post/rich-content/index.md +++ b/exampleSite/content/post/rich-content/index.md @@ -36,3 +36,7 @@ Hugo ships with several [Built-in Shortcodes](https://gohugo.io/content-manageme ## bilibilibi Shortcode {{< bilibili av498363026 >}} + +## Gist Shortcode + +{{< gist spf13 7896402 >}} \ No newline at end of file diff --git a/go.mod b/go.mod index 1cf4674..63df635 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ -module github.com/CaiJimmy/hugo-theme-stack +module github.com/CaiJimmy/hugo-theme-stack/v3 -go 1.12 +go 1.17 diff --git a/i18n/ar.yaml b/i18n/ar.yaml new file mode 100644 index 0000000..b2970b1 --- /dev/null +++ b/i18n/ar.yaml @@ -0,0 +1,70 @@ +toggleMenu: + other: اخفي القائمة + +darkMode: + other: الوضع الداكن + +list: + page: + one: "{{ .Count }} صفحه" + other: "{{ .Count }} صفحات" + + section: + other: قسم + + subsection: + one: قسم فرعي + other: اقسام فرعية + +article: + back: + other: خلف + + tableOfContents: + other: جدول المحتويات + + relatedContent: + other: محتوى مشابهه + + lastUpdatedOn: + other: التعديل الاخير + + readingTime: + one: "تُقرأ خلال دقيقة" + other: "تُقرأ خلال {{ .Count }} دقائق" + +notFound: + title: + other: غير موجود + + subtitle: + other: تعذر العثور على الصفحة المطلوبة. + +widget: + archives: + title: + other: الارشيفات + + more: + other: اكثر + + tagCloud: + title: + other: وسوم + +search: + title: + other: بحث + + placeholder: + other: اكتب... + + resultTitle: + other: "#PAGES_COUNT نتيجة (#TIME_SECONDS ثواني)" + +footer: + builtWith: + other: "مبني بستخدام {{ .Generator }}" + + designedBy: + other: "قالب {{ .Theme }} مصمم من {{ .DesignedBy }}" diff --git a/i18n/ca.yaml b/i18n/ca.yaml new file mode 100644 index 0000000..af4167e --- /dev/null +++ b/i18n/ca.yaml @@ -0,0 +1,73 @@ +toggleMenu: + other: Toggle Menu + +darkMode: + other: Mode fosc + +list: + page: + one: "{{ .Count }} pàgina" + other: "{{ .Count }} pàgines" + + section: + other: Secció + + subsection: + one: Subsecció + other: Subseccions + +article: + back: + other: Tornar + + tableOfContents: + other: Taula de contingut + + relatedContent: + other: Continguts relacionats + + lastUpdatedOn: + other: Última vegada actualitzat + + readingTime: + one: "{{ .Count }} minut a llegir" + other: "{{ .Count }} minuts a llegir" + +notFound: + title: + other: No Trobat + + subtitle: + other: Aquesta pàgina no existeix + +widget: + archives: + title: + other: Arxiu + + more: + other: Més + + tagCloud: + title: + other: Etiquetes + categoriesCloud: + title: + other: Categories + +search: + title: + other: Cerca + + placeholder: + other: Tecleja alguna cosa... + + resultTitle: + other: "#PAGES_COUNT pàgines en (#TIME_SECONDS segons)" + +footer: + builtWith: + other: Creat amb {{ .Generator }} + + designedBy: + other: Tema {{ .Theme }} dissenyat per {{ .DesignedBy }} diff --git a/i18n/de.yaml b/i18n/de.yaml index 00a8e11..7ab5b56 100644 --- a/i18n/de.yaml +++ b/i18n/de.yaml @@ -23,7 +23,7 @@ article: tableOfContents: other: Inhaltsverzeichnis - relatedContents: + relatedContent: other: Verwandte Inhalte lastUpdatedOn: @@ -52,6 +52,10 @@ widget: title: other: Schlagwörter + categoriesCloud: + title: + other: Kategorien + search: title: other: Suche diff --git a/i18n/el.yaml b/i18n/el.yaml index 38d867f..27a147d 100644 --- a/i18n/el.yaml +++ b/i18n/el.yaml @@ -23,7 +23,7 @@ article: tableOfContents: other: Πινακας περιεχομενων - relatedContents: + relatedContent: other: Σχετικο περιεχομενο lastUpdatedOn: diff --git a/i18n/en.yaml b/i18n/en.yaml index 0197d89..fb07328 100644 --- a/i18n/en.yaml +++ b/i18n/en.yaml @@ -23,8 +23,8 @@ article: tableOfContents: other: Table of contents - relatedContents: - other: Related contents + relatedContent: + other: Related content lastUpdatedOn: other: Last updated on @@ -51,6 +51,9 @@ widget: tagCloud: title: other: Tags + categoriesCloud: + title: + other: Categories search: title: diff --git a/i18n/es.yaml b/i18n/es.yaml index 9e1d6e1..76995da 100644 --- a/i18n/es.yaml +++ b/i18n/es.yaml @@ -23,7 +23,7 @@ article: tableOfContents: other: Tabla de contenido - relatedContents: + relatedContent: other: Contenidos relacionados lastUpdatedOn: @@ -51,6 +51,9 @@ widget: tagCloud: title: other: Etiquetas + categoriesCloud: + title: + other: Categorías search: title: diff --git a/i18n/fr.yaml b/i18n/fr.yaml index ac2e51a..c3feb1d 100644 --- a/i18n/fr.yaml +++ b/i18n/fr.yaml @@ -23,7 +23,7 @@ article: tableOfContents: other: Table des matières - relatedContents: + relatedContent: other: Contenus liés lastUpdatedOn: diff --git a/i18n/hu.yaml b/i18n/hu.yaml new file mode 100644 index 0000000..5e5af92 --- /dev/null +++ b/i18n/hu.yaml @@ -0,0 +1,73 @@ +toggleMenu: + other: Menü Kapcsolása + +darkMode: + other: Sötét Mód + +list: + page: + one: "{{ .Count }} oldal" + other: "{{ .Count }} oldalak" + + section: + other: Szekció + + subsection: + one: Alszekció + other: Alszekciók + +article: + back: + other: Vissza + + tableOfContents: + other: Tartalomjegyzék + + relatedContent: + other: Kapcsolódó tartalom + + lastUpdatedOn: + other: Utolsó frissítés időpontja + + readingTime: + one: "{{ .Count }} percnyi olvasmány" + other: "{{ .Count }} percnyi olvasmány" + +notFound: + title: + other: Nem található + + subtitle: + other: Ez az oldal nem létezik + +widget: + archives: + title: + other: Archívum + + more: + other: Több + + tagCloud: + title: + other: Cimkék + categoriesCloud: + title: + other: Kategóriák + +search: + title: + other: Keresés + + placeholder: + other: Írj valamit... + + resultTitle: + other: "#PAGES_COUNT oldal (#TIME_SECONDS másodperc alatt)" + +footer: + builtWith: + other: "{{ .Generator }} használatával készült" + + designedBy: + other: A {{ .Theme }} dizájnt {{ .DesignedBy }} tervezte diff --git a/i18n/id.yaml b/i18n/id.yaml index 2af893a..8104351 100644 --- a/i18n/id.yaml +++ b/i18n/id.yaml @@ -23,7 +23,7 @@ article: tableOfContents: other: Daftar Isi - relatedContents: + relatedContent: other: Konten terkait lastUpdatedOn: @@ -51,6 +51,10 @@ widget: title: other: Tag + categoriesCloud: + title: + other: Kategori + search: title: other: Cari diff --git a/i18n/it.yaml b/i18n/it.yaml index 6c4114c..a7fa521 100644 --- a/i18n/it.yaml +++ b/i18n/it.yaml @@ -23,7 +23,7 @@ article: tableOfContents: other: Indice - relatedContents: + relatedContent: other: Contenuti correlati lastUpdatedOn: diff --git a/i18n/ja.yaml b/i18n/ja.yaml index 3f9978d..40380fd 100644 --- a/i18n/ja.yaml +++ b/i18n/ja.yaml @@ -11,7 +11,7 @@ article: tableOfContents: other: 目次 - relatedContents: + relatedContent: other: 関連するコンテンツ lastUpdatedOn: @@ -38,6 +38,10 @@ widget: title: other: タグ + categoriesCloud: + title: + other: カテゴリ + search: title: other: 検索 @@ -47,3 +51,10 @@ search: resultTitle: other: "#PAGES_COUNT 件 (#TIME_SECONDS 秒)" + +footer: + builtWith: + other: Built with {{ .Generator }} + + designedBy: + other: テーマ {{ .Theme }} は {{ .DesignedBy }} によって設計されています。 diff --git a/i18n/ko.yaml b/i18n/ko.yaml index b2202e6..5ded2b0 100644 --- a/i18n/ko.yaml +++ b/i18n/ko.yaml @@ -23,7 +23,7 @@ article: tableOfContents: other: 목차 - relatedContents: + relatedContent: other: 관련 글 lastUpdatedOn: diff --git a/i18n/nl.yaml b/i18n/nl.yaml index b9ecad3..80f1f0c 100644 --- a/i18n/nl.yaml +++ b/i18n/nl.yaml @@ -17,7 +17,7 @@ list: other: Subsecties article: - relatedContents: + relatedContent: other: Gerelateerde inhoud lastUpdatedOn: other: Laatst bijgewerkt op diff --git a/i18n/pl.yaml b/i18n/pl.yaml index f261f86..e44a140 100644 --- a/i18n/pl.yaml +++ b/i18n/pl.yaml @@ -23,7 +23,7 @@ article: tableOfContents: other: Spis treści - relatedContents: + relatedContent: other: Powiązane artykuły lastUpdatedOn: @@ -50,6 +50,10 @@ widget: tagCloud: title: other: Tagi + + categoriesCloud: + title: + other: Kategorie search: title: diff --git a/i18n/pt-BR.yaml b/i18n/pt-br.yaml similarity index 98% rename from i18n/pt-BR.yaml rename to i18n/pt-br.yaml index ffdbe41..e3cf582 100644 --- a/i18n/pt-BR.yaml +++ b/i18n/pt-br.yaml @@ -23,7 +23,7 @@ article: tableOfContents: other: Índice - relatedContents: + relatedContent: other: Conteúdo relacionado lastUpdatedOn: diff --git a/i18n/ru.yaml b/i18n/ru.yaml index 65e3be6..b1f1e51 100644 --- a/i18n/ru.yaml +++ b/i18n/ru.yaml @@ -23,7 +23,7 @@ list: article: back: other: Назад - relatedContents: + relatedContent: other: Также рекомендуем lastUpdatedOn: other: Обновлено diff --git a/i18n/th.yaml b/i18n/th.yaml index b2ae1cd..9982c06 100644 --- a/i18n/th.yaml +++ b/i18n/th.yaml @@ -23,7 +23,7 @@ article: tableOfContents: other: สารบัญ - relatedContents: + relatedContent: other: เนื้อหาคล้ายคลึงกัน lastUpdatedOn: diff --git a/i18n/tr.yaml b/i18n/tr.yaml index fe9269b..2dbb9d5 100644 --- a/i18n/tr.yaml +++ b/i18n/tr.yaml @@ -17,7 +17,7 @@ list: other: Alt bölümler article: - relatedContents: + relatedContent: other: Alakalı içerikler lastUpdatedOn: other: Son güncelleme diff --git a/i18n/uk.yaml b/i18n/uk.yaml index 966e141..3bd4f71 100644 --- a/i18n/uk.yaml +++ b/i18n/uk.yaml @@ -24,7 +24,7 @@ article: tableOfContents: other: Зміст - relatedContents: + relatedContent: other: Схожі матеріали lastUpdatedOn: diff --git a/i18n/zh-CN.yaml b/i18n/zh-cn.yaml similarity index 76% rename from i18n/zh-CN.yaml rename to i18n/zh-cn.yaml index 0f08310..9350c2b 100644 --- a/i18n/zh-CN.yaml +++ b/i18n/zh-cn.yaml @@ -11,7 +11,7 @@ article: tableOfContents: other: 目录 - relatedContents: + relatedContent: other: 相关文章 lastUpdatedOn: @@ -38,6 +38,10 @@ widget: title: other: 标签云 + categoriesCloud: + title: + other: 分类 + search: title: other: 搜索 @@ -47,3 +51,10 @@ search: resultTitle: other: "#PAGES_COUNT 个结果 (用时 #TIME_SECONDS 秒)" + +footer: + builtWith: + other: Built with {{ .Generator }} + + designedBy: + other: 主题 {{ .Theme }} 由 {{ .DesignedBy }} 设计 diff --git a/i18n/zh-hk.yaml b/i18n/zh-hk.yaml new file mode 100644 index 0000000..9e3c246 --- /dev/null +++ b/i18n/zh-hk.yaml @@ -0,0 +1,73 @@ +toggleMenu: + other: 切換選單 + +darkMode: + other: 深色模式 + +list: + page: + one: "第 {{ .Count }} 頁" + other: "第 {{ .Count }} 頁" + + section: + other: Section + + subsection: + one: Subsection + other: Subsections + +article: + back: + other: 返回 + + tableOfContents: + other: 目錄 + + relatedContent: + other: 相關內容 + + lastUpdatedOn: + other: 上次改過於 + + readingTime: + one: "需要 {{ .Count }} 分鐘閱讀" + other: "需要 {{ .Count }} 分鐘閱讀" + +notFound: + title: + other: Not Found + + subtitle: + other: 頁面不存在 + +widget: + archives: + title: + other: Archives + + more: + other: 更多 + + tagCloud: + title: + other: Tags + categoriesCloud: + title: + other: Categories + +search: + title: + other: 搜尋 + + placeholder: + other: Type 關鍵字... + + resultTitle: + other: "#PAGES_COUNT pages (#TIME_SECONDS seconds)" + +footer: + builtWith: + other: Built with {{ .Generator }} + + designedBy: + other: 主題 {{ .Theme }} 由 {{ .DesignedBy }} 設計 diff --git a/i18n/zh-TW.yaml b/i18n/zh-tw.yaml similarity index 97% rename from i18n/zh-TW.yaml rename to i18n/zh-tw.yaml index 871d937..d9e124e 100644 --- a/i18n/zh-TW.yaml +++ b/i18n/zh-tw.yaml @@ -11,7 +11,7 @@ article: tableOfContents: other: 目錄 - relatedContents: + relatedContent: other: 相關文章 lastUpdatedOn: diff --git a/layouts/_default/_markup/render-image.html b/layouts/_default/_markup/render-image.html index 0325458..0ed5584 100644 --- a/layouts/_default/_markup/render-image.html +++ b/layouts/_default/_markup/render-image.html @@ -25,22 +25,17 @@ {{- end -}} {{- end -}} - \ No newline at end of file +> \ No newline at end of file diff --git a/layouts/_default/archives.html b/layouts/_default/archives.html index 321aa6d..5d5243c 100644 --- a/layouts/_default/archives.html +++ b/layouts/_default/archives.html @@ -1,17 +1,19 @@ {{ define "body-class" }}template-archives{{ end }} {{ define "main" }} - {{- $taxonomy := $.Site.GetPage "taxonomyTerm" "categories" -}} - {{- $terms := $taxonomy.Pages -}} - {{ if $terms }} -

{{ $taxonomy.Title }}

-
-
- {{ range $terms }} - {{ partial "article-list/tile" (dict "context" . "size" "250x150" "Type" "taxonomy") }} - {{ end }} +
+ {{- $taxonomy := $.Site.GetPage "taxonomyTerm" "categories" -}} + {{- $terms := $taxonomy.Pages -}} + {{ if $terms }} +

{{ $taxonomy.Title }}

+
+
+ {{ range $terms }} + {{ partial "article-list/tile" (dict "context" . "size" "250x150" "Type" "taxonomy") }} + {{ end }} +
-
- {{ end }} + {{ end }} + {{ $pages := where .Site.RegularPages "Type" "in" .Site.Params.mainSections }} {{ $notHidden := where .Site.RegularPages "Params.hidden" "!=" true }} diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html index 8a5ff95..081277b 100644 --- a/layouts/_default/baseof.html +++ b/layouts/_default/baseof.html @@ -1,12 +1,20 @@ - + {{- partial "head/head.html" . -}} {{- block "head" . -}}{{ end }} {{- partial "head/colorScheme" . -}} -
+ + {{/* The container is wider when there's any activated widget */}} + {{- $hasWidget := false -}} + {{- range .Site.Params.widgets -}} + {{- if gt (len .) 0 -}} + {{- $hasWidget = true -}} + {{- end -}} + {{- end -}} +
{{- block "left-sidebar" . -}} {{ partial "sidebar/left.html" . }} {{- end -}} diff --git a/layouts/_default/list.html b/layouts/_default/list.html index 90e5b66..9bc618d 100644 --- a/layouts/_default/list.html +++ b/layouts/_default/list.html @@ -1,46 +1,48 @@ {{ define "main" }} -

- {{ if eq .Parent (.GetPage "/") }} - {{ T "list.section" }} - {{ else }} - {{ .Parent.Title }} - {{ end }} -

- -
-
-

{{ T "list.page" (len .Pages) }}

-

{{ .Title }}

- {{ with .Params.description }} -

{{ . }}

+
+

+ {{ if eq .Parent (.GetPage "/") }} + {{ T "list.section" }} + {{ else }} + {{ .Parent.Title }} {{ end }} -

+ - {{- $image := partialCached "helper/image" (dict "Context" . "Type" "section") .RelPermalink "section" -}} - {{ if $image.exists }} -
- {{ if $image.resource }} - {{- $Permalink := $image.resource.RelPermalink -}} - {{- $Width := $image.resource.Width -}} - {{- $Height := $image.resource.Height -}} - - {{- if (default true .Page.Site.Params.imageProcessing.cover.enabled) -}} - {{- $thumbnail := $image.resource.Fill "120x120" -}} - {{- $Permalink = $thumbnail.RelPermalink -}} - {{- $Width = $thumbnail.Width -}} - {{- $Height = $thumbnail.Height -}} - {{- end -}} - - - {{ else }} - +
+
+

{{ T "list.page" (len .Pages) }}

+

{{ .Title }}

+ {{ with .Params.description }} +

{{ . }}

{{ end }}
- {{ end }} -
+ + {{- $image := partialCached "helper/image" (dict "Context" . "Type" "section") .RelPermalink "section" -}} + {{ if $image.exists }} +
+ {{ if $image.resource }} + {{- $Permalink := $image.resource.RelPermalink -}} + {{- $Width := $image.resource.Width -}} + {{- $Height := $image.resource.Height -}} + + {{- if (default true .Page.Site.Params.imageProcessing.cover.enabled) -}} + {{- $thumbnail := $image.resource.Fill "120x120" -}} + {{- $Permalink = $thumbnail.RelPermalink -}} + {{- $Width = $thumbnail.Width -}} + {{- $Height = $thumbnail.Height -}} + {{- end -}} + + + {{ else }} + + {{ end }} +
+ {{ end }} +
+ {{- $subsections := .Sections -}} {{- $pages := .Pages | complement $subsections -}} @@ -53,14 +55,16 @@ {{- end -}} {{- with $subsections -}} -

{{ T "list.subsection" (len $subsections) }}

-
-
- {{ range . }} - {{ partial "article-list/tile" (dict "context" . "size" "250x150" "Type" "section") }} - {{ end }} +
+ {{- end -}} {{/* List only pages that are not a subsection */}} @@ -77,5 +81,5 @@ {{ end }} {{ define "right-sidebar" }} - {{ partialCached "sidebar/right.html" . }} + {{ partial "sidebar/right.html" (dict "Context" . "Scope" "homepage") }} {{ end }} \ No newline at end of file diff --git a/layouts/rss.xml b/layouts/_default/rss.xml similarity index 86% rename from layouts/rss.xml rename to layouts/_default/rss.xml index 178f997..e9f3f1a 100644 --- a/layouts/rss.xml +++ b/layouts/_default/rss.xml @@ -1,9 +1,15 @@ -{{- $pages := where .Site.RegularPages "Type" "in" .Site.Params.mainSections -}} -{{- $notHidden := where .Site.RegularPages "Params.hidden" "!=" true -}} -{{- $filtered := ($pages | intersect $notHidden) -}} +{{- $pctx := . -}} +{{- if .IsHome -}}{{ $pctx = .Site }}{{- end -}} +{{- $pages := slice -}} +{{- if or $.IsHome $.IsSection -}} +{{- $pages = $pctx.RegularPages -}} +{{- else -}} +{{- $pages = $pctx.Pages -}} +{{- end -}} +{{- $pages := where $pages "Params.hidden" "!=" true -}} {{- $limit := .Site.Config.Services.RSS.Limit -}} {{- if ge $limit 1 -}} -{{- $filtered = $filtered | first $limit -}} +{{- $pages = $pages | first $limit -}} {{- end -}} {{- printf "" | safeHTML }} @@ -20,7 +26,7 @@ {{- with .OutputFormats.Get "RSS" -}} {{ printf "" .Permalink .MediaType | safeHTML }} {{- end -}} - {{ range $filtered }} + {{ range $pages }} {{- $content := safeHTML (.Summary | html) -}} {{- if .Site.Params.rssFullContent -}} {{- $content = safeHTML (.Content | html) -}} diff --git a/layouts/_default/single.html b/layouts/_default/single.html index 8ce42e9..5f300bf 100644 --- a/layouts/_default/single.html +++ b/layouts/_default/single.html @@ -1,15 +1,26 @@ {{ define "body-class" }} - {{ $TOCEnabled := default (default false .Site.Params.article.toc) .Params.toc }} - {{- .Scratch.Set "hasTOC" (and (ge (len .TableOfContents) 100) $TOCEnabled) -}} - article-page {{ if (.Scratch.Get "hasTOC") }}has-toc{{ end }} -{{ end }} + article-page + {{/* + Enable the right sidebar if + - Widget different from 'TOC' is enabled + - TOC is enabled and not empty + */}} + {{- $HasWidgetNotTOC := false -}} + {{- $TOCWidgetEnabled := false -}} + {{- range .Site.Params.widgets.page -}} + {{- if ne .type "toc" -}} + {{ $HasWidgetNotTOC = true -}} + {{- else -}} + {{ $TOCWidgetEnabled = true -}} + {{- end -}} + {{- end -}} -{{ define "container-class" }} - {{ if (.Scratch.Get "hasTOC") }} - extended - {{ else }} - on-phone--column {{ if .Site.Params.widgets.enabled }}extended{{ else }}compact{{ end }} - {{ end }} + {{- $TOCManuallyDisabled := eq .Params.toc false -}} + {{- $TOCEnabled := and (not $TOCManuallyDisabled) $TOCWidgetEnabled -}} + {{- $hasTOC := ge (len .TableOfContents) 100 -}} + {{- .Scratch.Set "TOCEnabled" (and $TOCEnabled $hasTOC) -}} + + {{- .Scratch.Set "hasWidget" (or $HasWidgetNotTOC (and $TOCEnabled $hasTOC)) -}} {{ end }} {{ define "main" }} @@ -19,7 +30,7 @@ {{ partial "article/components/links" . }} {{ end }} - {{ partial "article/components/related-contents" . }} + {{ partial "article/components/related-content" . }} {{ if not (eq .Params.comments false) }} {{ partial "comments/include" . }} @@ -30,32 +41,6 @@ {{ partialCached "article/components/photoswipe" . }} {{ end }} -{{ define "left-sidebar" }} - {{ if (.Scratch.Get "hasTOC") }} -
- - {{ (resources.Get "icons/back.svg").Content | safeHTML }} - {{ T "article.back" }} - -
- {{ else }} - {{ partial "sidebar/left.html" . }} - {{ end }} -{{ end }} - {{ define "right-sidebar" }} - {{ if (.Scratch.Get "hasTOC") }} - - {{ end }} + {{ if .Scratch.Get "hasWidget" }}{{ partial "sidebar/right.html" (dict "Context" . "Scope" "page") }}{{ end}} {{ end }} diff --git a/layouts/index.html b/layouts/index.html index 576faef..0cd0b88 100644 --- a/layouts/index.html +++ b/layouts/index.html @@ -15,5 +15,5 @@ {{ end }} {{ define "right-sidebar" }} - {{ partial "sidebar/right.html" . }} + {{ partial "sidebar/right.html" (dict "Context" . "Scope" "homepage") }} {{ end }} \ No newline at end of file diff --git a/layouts/page/search.html b/layouts/page/search.html index 935b384..7c424a6 100644 --- a/layouts/page/search.html +++ b/layouts/page/search.html @@ -16,8 +16,10 @@ -

-
+
+

+
+
{{- end -}} - diff --git a/layouts/partials/comments/provider/twikoo.html b/layouts/partials/comments/provider/twikoo.html index 30c7033..7dd3e50 100644 --- a/layouts/partials/comments/provider/twikoo.html +++ b/layouts/partials/comments/provider/twikoo.html @@ -1,4 +1,4 @@ - +