diff --git a/.gitignore b/.gitignore index 9ff142d08..10aec29ac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ public resources assets/jsconfig.json -.hugo_build.lock \ No newline at end of file +.hugo_build.lock +node_modules +docs/.vitepress/dist +docs/.vitepress/cache \ No newline at end of file diff --git a/README.md b/README.md index b071761e3..7727bb6b1 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,7 @@ Use this template: [CaiJimmy/hugo-theme-stack-starter](https://github.com/CaiJim ## Demo -* Starter template demo: [demo.stack.jimmycai.com](https://demo.stack.jimmycai.com) -* Dev build: [dev.stack.jimmycai.com](https://dev.stack.jimmycai.com) +[stack.jimmycai.com/demo](https://stack.jimmycai.com/demo) ## Documentation diff --git a/archetypes/default.md b/archetypes/default.md index 0556d3a86..129dec23d 100644 --- a/archetypes/default.md +++ b/archetypes/default.md @@ -5,7 +5,6 @@ date: {{ .Date }} image: math: license: -hidden: false comments: true draft: true --- \ No newline at end of file diff --git a/assets/scss/partials/article.scss b/assets/scss/partials/article.scss index 6c2feb183..5d7254136 100644 --- a/assets/scss/partials/article.scss +++ b/assets/scss/partials/article.scss @@ -203,7 +203,6 @@ .article-preview { font-size: 1.4rem; color: var(--card-text-color-tertiary); - margin-top: 10px; line-height: 1.5; } } diff --git a/assets/scss/partials/highlight/dark.scss b/assets/scss/partials/highlight/dark.scss index 0d3f330ee..3ea6c56fd 100644 --- a/assets/scss/partials/highlight/dark.scss +++ b/assets/scss/partials/highlight/dark.scss @@ -11,4 +11,4 @@ $text-color: $color; $name-color: #a6e22e; $literal-color: #e6db74; -@import "common.scss"; +@import "common.scss"; \ No newline at end of file diff --git a/assets/scss/partials/layout/article.scss b/assets/scss/partials/layout/article.scss index 10e2706b0..977c7a624 100644 --- a/assets/scss/partials/layout/article.scss +++ b/assets/scss/partials/layout/article.scss @@ -316,10 +316,12 @@ line-height: 1.428571429; word-break: break-all; padding: var(--card-padding); + // keep Codeblocks LTR [dir="rtl"] & { direction: ltr; } + code { color: unset; border: none; @@ -333,15 +335,11 @@ padding: var(--card-padding); position: relative; - &:hover { - .copyCodeButton { - opacity: 1; - } - } // keep Codeblocks LTR [dir="rtl"] & { direction: ltr; } + pre { margin: initial; padding: 0; @@ -350,20 +348,34 @@ } } - .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; + .codeblock { + header { + background-color: var(--card-background-selected); + padding: 5px var(--card-padding); + display: flex; + justify-content: space-between; + box-shadow: var(--shadow-l1); + + span { + text-transform: uppercase; + font-weight: bold; + color: var(--card-text-color-secondary); + } + } + + .codeblock-copy { + cursor: pointer; + background-color: transparent; + border: none; + padding: 8px 16px; + color: var(--card-text-color-secondary); + font-size: 14px; + font-weight: bold; + } + + pre { + margin: 0; + } } .table-wrapper { @@ -432,7 +444,7 @@ /// Negative margins blockquote, figure, - .highlight, + .codeblock, pre, .gallery, .video-wrapper, diff --git a/assets/scss/partials/layout/search.scss b/assets/scss/partials/layout/search.scss index 89cdcef9a..cbf15b784 100644 --- a/assets/scss/partials/layout/search.scss +++ b/assets/scss/partials/layout/search.scss @@ -31,6 +31,7 @@ input { padding: 40px 20px 20px; + padding-inline-end: var(--button-size); border-radius: var(--card-border-radius); background-color: var(--card-background); box-shadow: var(--shadow-l1); @@ -78,5 +79,4 @@ height: 20px; } } - -} \ No newline at end of file +} diff --git a/assets/scss/partials/sidebar.scss b/assets/scss/partials/sidebar.scss index a6a77c5bc..99b1a322f 100644 --- a/assets/scss/partials/sidebar.scss +++ b/assets/scss/partials/sidebar.scss @@ -11,7 +11,6 @@ flex-direction: column; flex-shrink: 0; align-self: stretch; - gap: var(--sidebar-element-separation); max-width: none; width: 100%; position: relative; @@ -65,6 +64,11 @@ } } } + + .menu-social, + #main-menu { + margin-top: var(--sidebar-element-separation); + } } .right-sidebar { diff --git a/assets/scss/partials/widgets.scss b/assets/scss/partials/widgets.scss index 42cfcc2c2..b1b7b3ebc 100644 --- a/assets/scss/partials/widgets.scss +++ b/assets/scss/partials/widgets.scss @@ -65,3 +65,11 @@ } } } + +/* Color for widget titles */ +.widget-title a.widget-link { + color: var(--accent-color); + &:hover { + color: var(--accent-color-darker); + } +} diff --git a/assets/ts/archives.ts b/assets/ts/archives.ts new file mode 100644 index 000000000..ac930bb2a --- /dev/null +++ b/assets/ts/archives.ts @@ -0,0 +1,165 @@ +interface PageData { + title: string; + content: string; + id: string; +} + +class Search { + private data: PageData[]; + private form: HTMLFormElement; + private input: HTMLInputElement; + private resultTitle: HTMLHeadElement; + private resultTitleTemplate: string; + + constructor({ form, input, resultTitle, resultTitleTemplate }) { + this.form = form; + this.input = input; + this.resultTitle = resultTitle; + this.resultTitleTemplate = resultTitleTemplate; + + this.handleQueryString(); + this.bindQueryStringChange(); + this.bindSearchForm(); + } + + private async getIndex() { + if (!this.data) { + const jsonURL = this.form.dataset.json; + this.data = await fetch(jsonURL).then(res => res.json()); + } + return this.data; + } + + private async searchKeywords(keywords: string[]) { + const index = await this.getIndex(); + /// Return an set of ids that match the keywords + return new Set(index.filter(item => { + return keywords.every(keyword => { + return item.title.includes(keyword) || item.content.includes(keyword); + }); + }).map(item => item.id)); + } + + private async doSearch(keywords: string[]) { + const startTime = performance.now(); + + const results = await this.searchKeywords(keywords); + this.clear(); + + /// Hide all articles except the ones that are in the results + const archiveGroups = document.querySelectorAll('.archives-group') as NodeListOf; + + archiveGroups.forEach(group => { + const articles = Array.from(group.querySelectorAll('article')); + articles.map(article => { + article.style.display = 'none'; + article.style.removeProperty('border-bottom'); + }); + + const matchingArticles = articles.filter(article => results.has(article.id)); + + const hasResults = matchingArticles.length > 0; + if (!hasResults) return group.style.display = 'none'; + + matchingArticles.map(article => article.style.removeProperty('display')); + matchingArticles[matchingArticles.length - 1].style.borderBottom = 'none'; + }); + + const endTime = performance.now(); + this.resultTitle.innerText = this.generateResultTitle(results.size, ((endTime - startTime) / 1000).toPrecision(1)); + this.resultTitle.style.display = 'block'; + } + + private generateResultTitle(resultLen, time) { + return this.resultTitleTemplate.replace("#PAGES_COUNT", resultLen).replace("#TIME_SECONDS", time); + } + + private bindSearchForm() { + let lastSearch = ''; + + const eventHandler = (e) => { + e.preventDefault(); + const keywords = this.input.value.trim(); + + Search.updateQueryString(keywords, true); + + if (keywords === '') { + lastSearch = ''; + 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.resultTitle.style.display = 'none'; + document.querySelectorAll('.archives-group, .archives-group article').forEach(el => el.removeAttribute('style')); + } + + 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()); + } + } +} + +declare global { + interface Window { + searchResultTitleTemplate: string; + } +} + +window.addEventListener('load', () => { + setTimeout(function () { + const searchForm = document.getElementById('search-form') as HTMLFormElement, + searchInput = searchForm.querySelector('input') as HTMLInputElement, + searchResultTitle = document.querySelector('.search-result--title') as HTMLHeadingElement; + + new Search({ + form: searchForm, + input: searchInput, + resultTitle: searchResultTitle, + resultTitleTemplate: window.searchResultTitleTemplate + }); + }, 0); +}) + +export default Search; \ No newline at end of file diff --git a/assets/ts/codeblock.ts b/assets/ts/codeblock.ts new file mode 100644 index 000000000..08c332875 --- /dev/null +++ b/assets/ts/codeblock.ts @@ -0,0 +1,28 @@ +/** + * Copy button for code blocks +*/ +export default () => { + const copyButtons = document.querySelectorAll('.codeblock-copy'); + copyButtons.forEach(button => { + const codeblockID = button.getAttribute('data-id'), + copyText = button.textContent, + copiedText = button.getAttribute('data-copied-text'); + if (!codeblockID) return; + button.addEventListener('click', (e) => { + e.preventDefault(); + const codeblock = document.getElementById(codeblockID) as HTMLElement; + if (!codeblockID) return; + navigator.clipboard.writeText(codeblock.textContent) + .then(() => { + button.textContent = copiedText; + setTimeout(() => { + button.textContent = copyText; + }, 1000); + }) + .catch(err => { + alert(err) + console.log('Something went wrong', err); + }); + }, false); + }); +} \ No newline at end of file diff --git a/assets/ts/color.ts b/assets/ts/color.ts deleted file mode 100644 index 50581d104..000000000 --- a/assets/ts/color.ts +++ /dev/null @@ -1,63 +0,0 @@ -interface colorScheme { - hash: string, /// Regenerate color scheme when the image hash is changed - DarkMuted: { - hex: string, - rgb: Number[], - bodyTextColor: string - }, - Vibrant: { - hex: string, - rgb: Number[], - bodyTextColor: string - } -} - -let colorsCache: { [key: string]: colorScheme } = {}; - -if (localStorage.hasOwnProperty('StackColorsCache')) { - try { - colorsCache = JSON.parse(localStorage.getItem('StackColorsCache')); - } - catch (e) { - colorsCache = {}; - } -} - -async function getColor(key: string, hash: string, imageURL: string) { - if (!key) { - /** - * If no key is provided, do not cache the result - */ - return await Vibrant.from(imageURL).getPalette(); - } - - if (!colorsCache.hasOwnProperty(key) || colorsCache[key].hash !== hash) { - /** - * If key is provided, but not found in cache, or the hash mismatches => Regenerate color scheme - */ - const palette = await Vibrant.from(imageURL).getPalette(); - - colorsCache[key] = { - hash: hash, - Vibrant: { - hex: palette.Vibrant.hex, - rgb: palette.Vibrant.rgb, - bodyTextColor: palette.Vibrant.bodyTextColor - }, - DarkMuted: { - hex: palette.DarkMuted.hex, - rgb: palette.DarkMuted.rgb, - bodyTextColor: palette.DarkMuted.bodyTextColor - } - } - - /* Save the result in localStorage */ - localStorage.setItem('StackColorsCache', JSON.stringify(colorsCache)); - } - - return colorsCache[key]; -} - -export { - getColor -} \ No newline at end of file diff --git a/assets/ts/gallery.ts b/assets/ts/gallery.ts index 9840f1ec1..e60c00645 100644 --- a/assets/ts/gallery.ts +++ b/assets/ts/gallery.ts @@ -1,186 +1,92 @@ -declare global { - interface Window { - PhotoSwipe: any; - PhotoSwipeUI_Default: any - } -} +const wrap = (figures: HTMLElement[]) => { + const galleryContainer = document.createElement('div'); + galleryContainer.className = 'gallery'; -interface PhotoSwipeItem { - w: number; - h: number; - src: string; - msrc: string; - title?: string; - el: HTMLElement; -} + const parentNode = figures[0].parentNode, + first = figures[0]; -class StackGallery { - private galleryUID: number; - private items: PhotoSwipeItem[] = []; - - constructor(container: HTMLElement, galleryUID = 1) { - if (window.PhotoSwipe == undefined || window.PhotoSwipeUI_Default == undefined) { - console.error("PhotoSwipe lib not loaded."); - return; - } + parentNode.insertBefore(galleryContainer, first) - this.galleryUID = galleryUID; - - StackGallery.createGallery(container); - this.loadItems(container); - this.bindClick(); + for (const figure of figures) { + galleryContainer.appendChild(figure); } +} - private loadItems(container: HTMLElement) { - this.items = []; - - const figures = container.querySelectorAll('figure.gallery-image'); - - for (const el of figures) { - const figcaption = el.querySelector('figcaption'), - img = el.querySelector('img'); - - let aux: PhotoSwipeItem = { - w: parseInt(img.getAttribute('width')), - h: parseInt(img.getAttribute('height')), - src: img.src, - msrc: img.getAttribute('data-thumb') || img.src, - el: el - } - - if (figcaption) { - aux.title = figcaption.innerHTML; - } - - this.items.push(aux); +export default (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') as NodeListOf; + 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'); } - } - - 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 isNewLineImage = paragraph.classList.contains('no-text'); + if (!isNewLineImage) continue; - 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); + const hasLink = img.parentElement.tagName == 'A'; - /// 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); - } + 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; } - - const figuresEl = container.querySelectorAll('figure.gallery-image'); - - let currentGallery = []; - - for (const figure of figuresEl) { - if (!currentGallery.length) { - /// First iteration - currentGallery = [figure]; - } - else if (figure.previousElementSibling === currentGallery[currentGallery.length - 1]) { - /// Adjacent figures - currentGallery.push(figure); - } - else if (currentGallery.length) { - /// End gallery - StackGallery.wrap(currentGallery); - currentGallery = [figure]; - } + 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); } - if (currentGallery.length > 0) { - StackGallery.wrap(currentGallery); + /// 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'); + a.setAttribute('data-pswp-width', img.getAttribute('width')); + a.setAttribute('data-pswp-height', img.getAttribute('height')); + img.parentNode.insertBefore(a, img); + a.appendChild(img); } } - /** - * Wrap adjacent figure tags with div.gallery - * @param figures - */ - public static wrap(figures: HTMLElement[]) { - const galleryContainer = document.createElement('div'); - galleryContainer.className = 'gallery'; - - const parentNode = figures[0].parentNode, - first = figures[0]; - - parentNode.insertBefore(galleryContainer, first) - - for (const figure of figures) { - galleryContainer.appendChild(figure); + const figuresEl = container.querySelectorAll('figure.gallery-image') as NodeListOf; + let currentGallery = []; + for (const figure of Array.from(figuresEl)) { + if (!currentGallery.length) { + /// First iteration + currentGallery = [figure]; } - } - - public open(index: number) { - const pswp = document.querySelector('.pswp') as HTMLDivElement; - const ps = new window.PhotoSwipe(pswp, window.PhotoSwipeUI_Default, this.items, { - index: index, - galleryUID: this.galleryUID, - getThumbBoundsFn: (index) => { - const thumbnail = this.items[index].el.getElementsByTagName('img')[0], - pageYScroll = window.pageYOffset || document.documentElement.scrollTop, - rect = thumbnail.getBoundingClientRect(); - - return { x: rect.left, y: rect.top + pageYScroll, w: rect.width }; - } - }); - - ps.init(); - } - - private bindClick() { - for (const [index, item] of this.items.entries()) { - const a = item.el.querySelector('a'); - - a.addEventListener('click', (e) => { - e.preventDefault(); - this.open(index); - }) + else if (figure.previousElementSibling === currentGallery[currentGallery.length - 1]) { + /// Adjacent figures + currentGallery.push(figure); + } + else if (currentGallery.length) { + /// End gallery + wrap(currentGallery); + currentGallery = [figure]; } } -} -export default StackGallery; \ No newline at end of file + if (currentGallery.length > 0) { + wrap(currentGallery); + } +}; \ No newline at end of file diff --git a/assets/ts/main.ts b/assets/ts/main.ts index f3160ae75..0668c7c05 100644 --- a/assets/ts/main.ts +++ b/assets/ts/main.ts @@ -5,8 +5,7 @@ * @website: https://jimmycai.com * @link: https://github.com/CaiJimmy/hugo-theme-stack */ -import StackGallery from "ts/gallery"; -import { getColor } from 'ts/color'; +import StackCodeBlock from "ts/codeblock"; import menu from 'ts/menu'; import createElement from 'ts/createElement'; import StackColorScheme from 'ts/colorScheme'; @@ -22,76 +21,12 @@ let Stack = { const articleContent = document.querySelector('.article-content') as HTMLElement; if (articleContent) { - new StackGallery(articleContent); setupSmoothAnchors(); setupScrollspy(); } - /** - * Add linear gradient background to tile style article - */ - const articleTile = document.querySelector('.article-list--tile'); - if (articleTile) { - let observer = new IntersectionObserver(async (entries, observer) => { - entries.forEach(entry => { - if (!entry.isIntersecting) return; - observer.unobserve(entry.target); - - const articles = entry.target.querySelectorAll('article.has-image'); - articles.forEach(async articles => { - const image = articles.querySelector('img'), - imageURL = image.src, - key = image.getAttribute('data-key'), - hash = image.getAttribute('data-hash'), - articleDetails: HTMLDivElement = articles.querySelector('.article-details'); - - const colors = await getColor(key, hash, imageURL); - - articleDetails.style.background = ` - linear-gradient(0deg, - rgba(${colors.DarkMuted.rgb[0]}, ${colors.DarkMuted.rgb[1]}, ${colors.DarkMuted.rgb[2]}, 0.5) 0%, - rgba(${colors.Vibrant.rgb[0]}, ${colors.Vibrant.rgb[1]}, ${colors.Vibrant.rgb[2]}, 0.75) 100%)`; - }) - }) - }); - - observer.observe(articleTile) - } - - - /** - * Add copy button to code block - */ - const highlights = document.querySelectorAll('.article-content div.highlight'); - const copyText = `Copy`, - copiedText = `Copied!`; - - highlights.forEach(highlight => { - const copyButton = document.createElement('button'); - copyButton.innerHTML = copyText; - copyButton.classList.add('copyCodeButton'); - highlight.appendChild(copyButton); - - const codeBlock = highlight.querySelector('code[data-lang]'); - if (!codeBlock) return; - - copyButton.addEventListener('click', () => { - navigator.clipboard.writeText(codeBlock.textContent) - .then(() => { - copyButton.textContent = copiedText; - - setTimeout(() => { - copyButton.textContent = copyText; - }, 1000); - }) - .catch(err => { - alert(err) - console.log('Something went wrong', err); - }); - }); - }); - new StackColorScheme(document.getElementById('dark-mode-toggle')); + StackCodeBlock(); } } diff --git a/assets/ts/search.tsx b/assets/ts/search.tsx deleted file mode 100644 index 856b48df8..000000000 --- a/assets/ts/search.tsx +++ /dev/null @@ -1,326 +0,0 @@ -interface pageData { - title: string, - date: string, - permalink: string, - content: string, - image?: string, - preview: string, - matchCount: number -} - -interface match { - start: number, - end: 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(); - } - - /** - * Processes search matches - * @param str original text - * @param matches array of matches - * @param ellipsis whether to add ellipsis to the end of each match - * @param charLimit max length of preview string - * @param offset how many characters before and after the match to include in preview - * @returns preview string - */ - private static processMatches(str: string, matches: match[], ellipsis: boolean = true, charLimit = 140, offset = 20): string { - matches.sort((a, b) => { - return a.start - b.start; - }); - - let i = 0, - lastIndex = 0, - charCount = 0; - - const resultArray: string[] = []; - - while (i < matches.length) { - const item = matches[i]; - - /// item.start >= lastIndex (equal only for the first iteration) - /// because of the while loop that comes after, iterating over variable j - - if (ellipsis && item.start - offset > lastIndex) { - resultArray.push(`${replaceHTMLEnt(str.substring(lastIndex, lastIndex + offset))} [...] `); - resultArray.push(`${replaceHTMLEnt(str.substring(item.start - offset, item.start))}`); - charCount += offset * 2; - } - else { - /// If the match is too close to the end of last match, don't add ellipsis - resultArray.push(replaceHTMLEnt(str.substring(lastIndex, item.start))); - charCount += item.start - lastIndex; - } - - let j = i + 1, - end = item.end; - - /// Include as many matches as possible - /// [item.start, end] is the range of the match - while (j < matches.length && matches[j].start <= end) { - end = Math.max(matches[j].end, end); - ++j; - } - - resultArray.push(`${replaceHTMLEnt(str.substring(item.start, end))}`); - charCount += end - item.start; - - i = j; - lastIndex = end; - - if (ellipsis && charCount > charLimit) break; - } - - /// Add the rest of the string - if (lastIndex < str.length) { - let end = str.length; - if (ellipsis) end = Math.min(end, lastIndex + offset); - - resultArray.push(`${replaceHTMLEnt(str.substring(lastIndex, end))}`); - - if (ellipsis && end != str.length) { - resultArray.push(` [...]`); - } - } - - return resultArray.join(''); - } - - private async searchKeywords(keywords: string[]) { - const rawData = await this.getData(); - const results: pageData[] = []; - - const regex = new RegExp(keywords.filter((v, index, arr) => { - arr[index] = escapeRegExp(v); - return v.trim() !== ''; - }).join('|'), 'gi'); - - for (const item of rawData) { - const titleMatches: match[] = [], - contentMatches: match[] = []; - - let result = { - ...item, - preview: '', - matchCount: 0 - } - - const contentMatchAll = item.content.matchAll(regex); - for (const match of Array.from(contentMatchAll)) { - contentMatches.push({ - start: match.index, - end: match.index + match[0].length - }); - } - - const titleMatchAll = item.title.matchAll(regex); - for (const match of Array.from(titleMatchAll)) { - titleMatches.push({ - start: match.index, - end: match.index + match[0].length - }); - } - - if (titleMatches.length > 0) result.title = Search.processMatches(result.title, titleMatches, false); - if (contentMatches.length > 0) { - result.preview = Search.processMatches(result.content, contentMatches); - } - else { - /// If there are no matches in the content, use the first 140 characters as preview - result.preview = replaceHTMLEnt(result.content.substring(0, 140)); - } - - result.matchCount = titleMatches.length + contentMatches.length; - if (result.matchCount > 0) results.push(result); - } - - /// Result with more matches appears first - return results.sort((a, b) => { - return b.matchCount - a.matchCount; - }); - } - - 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()); - const parser = new DOMParser(); - - for (const item of this.data) { - item.content = parser.parseFromString(item.content, 'text/html').body.innerText; - } - } - - return this.data; - } - - private bindSearchForm() { - let lastSearch = ''; - - const eventHandler = (e) => { - e.preventDefault(); - const keywords = this.input.value.trim(); - - Search.updateQueryString(keywords, true); - - if (keywords === '') { - lastSearch = ''; - 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 ; - } -} - -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; \ No newline at end of file diff --git a/config.yaml b/config.yaml deleted file mode 100644 index b1a0bffe1..000000000 --- a/config.yaml +++ /dev/null @@ -1,149 +0,0 @@ -module: - hugoVersion: - extended: true - min: "0.87.0" - -params: - mainSections: - - post - featuredImageField: image - rssFullContent: true - favicon: - - footer: - since: - customText: - - dateFormat: - published: Jan 02, 2006 - lastUpdated: Jan 02, 2006 15:04 MST - - sidebar: - compact: false - emoji: - subtitle: - avatar: - enabled: true - local: true - src: img/avatar.png - - article: - headingAnchor: false - math: false - toc: true - readingTime: true - license: - enabled: false - default: Licensed under CC BY-NC-SA 4.0 - - comments: - enabled: false - provider: disqus - - disqusjs: - shortname: - apiUrl: - apiKey: - admin: - adminLabel: - - utterances: - repo: - issueTerm: pathname - label: - - beaudar: - repo: - issueTerm: pathname - label: - theme: - - remark42: - host: - site: - locale: - - vssue: - platform: - owner: - repo: - clientId: - clientSecret: - autoCreateIssue: false - - # Waline client configuration see: https://waline.js.org/en/reference/client/props.html - waline: - serverURL: - lang: - visitor: - avatar: - emoji: - - https://cdn.jsdelivr.net/gh/walinejs/emojis/weibo - requiredMeta: - - nick - - mail - locale: - admin: Admin - placeholder: - - twikoo: - envId: - region: - path: - lang: - - giscus: - repo: - repoID: - category: - categoryID: - mapping: - strict: - lightTheme: - darkTheme: - reactionsEnabled: 1 - emitMetadata: 0 - inputPosition: - lang: - - gitalk: - owner: - admin: - repo: - clientID: - clientSecret: - - cusdis: - host: - id: - - widgets: - homepage: [] - page: [] - - opengraph: - twitter: - # Your Twitter username - site: - - # Available values: summary, summary_large_image - card: summary_large_image - - defaultImage: - opengraph: - enabled: false - local: false - src: - - colorScheme: - # Display toggle - toggle: true - - # Available values: auto, light, dark - default: auto - - imageProcessing: - cover: - enabled: true - content: - enabled: true diff --git a/config/_default/module.yaml b/config/_default/module.yaml new file mode 100644 index 000000000..b2335a99c --- /dev/null +++ b/config/_default/module.yaml @@ -0,0 +1,3 @@ +hugoVersion: + extended: true + min: 0.100.0 diff --git a/config/_default/params.yaml b/config/_default/params.yaml new file mode 100644 index 000000000..1cae32010 --- /dev/null +++ b/config/_default/params.yaml @@ -0,0 +1,180 @@ +# Theme's default configuration, can be overridden by user configuration + +# Pages in the following sections will appear on the homepage and in RSS +mainSections: + - post + +# Front matter field for cover image +featuredImageField: image + +# Output full content to RSS feed +rssFullContent: true + +# Path to favicon, relative to assets folder +favicon: + +footer: + # Year when site was first published + since: + # Custom text in footer, supports HTML + customText: + +dateFormat: + # Date format for published date + published: "Jan 02, 2006" + # Date format for last updated date + lastUpdated: "Jan 02, 2006 15:04 MST" + +sidebar: + emoji: + subtitle: + compact: false + avatar: img/avatar.png + +article: + headingAnchor: false + # Enable LaTeX math syntax for all pages by default + math: false + readingTime: true + license: + enabled: false + default: Licensed under CC BY-NC-SA 4.0 + +comments: + enabled: false + + # Available providers: cactus, cusdis, disqus, disqusjs, giscus, gitalk, remark42, twikoo, utterances, vssue, waline + provider: disqus + + # Note: for Disqus, set disqusShortname at top level + + disqusjs: + shortname: + apiUrl: + apiKey: + admin: + adminLabel: + + utterances: + repo: + issueTerm: pathname + label: + + beaudar: + repo: + issueTerm: pathname + label: + theme: + + remark42: + host: + site: + locale: + + vssue: + platform: + owner: + repo: + clientId: + clientSecret: + autoCreateIssue: false + + # Waline client configuration see: https://waline.js.org/en/reference/client.html + waline: + serverURL: + lang: + pageview: + emoji: + - https://unpkg.com/@waline/emojis@1.0.1/weibo + requiredMeta: + - name + - email + - url + locale: + admin: Admin + placeholder: + + twikoo: + envId: + region: + path: + lang: + + # See https://cactus.chat/docs/reference/web-client/#configuration for description of the various options + cactus: + 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: + category: + categoryID: + mapping: + lightTheme: + darkTheme: + reactionsEnabled: 1 + emitMetadata: 0 + + gitalk: + owner: + admin: + repo: + clientID: + clientSecret: + + cusdis: + host: + id: + +widgets: + homepage: [] + page: [] + +opengraph: + twitter: + # Your Twitter username + site: + # Available values: summary, summary_large_image + card: summary_large_image + +defaultImage: + opengraph: + enabled: false + local: false + src: + +colorScheme: + # Display toggle + toggle: true + + # Available values: auto, light, dark + default: auto + +imageProcessing: + allowedTypes: + - jpeg + - png + - gif + - webp + resizableTypes: + - jpeg + - png + - webp + cover: + enabled: true + small: + width: 800 + threshold: 1000 # Only process images above this width + big: + width: 1600 + threshold: 2000 + content: + enabled: true + small: + width: 480 + threshold: 600 + big: + width: 1024 + threshold: 1200 diff --git a/data/external.yaml b/data/external.yaml index 4fc0bca8b..1fc350a30 100644 --- a/data/external.yaml +++ b/data/external.yaml @@ -1,25 +1,3 @@ -Vibrant: - - src: https://cdn.jsdelivr.net/npm/node-vibrant@3.1.6/dist/vibrant.min.js - integrity: sha256-awcR2jno4kI5X0zL8ex0vi2z+KMkF24hUW8WePSA9HM= - type: script - -PhotoSwipe: - - src: https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.js - integrity: sha256-ePwmChbbvXbsO02lbM3HoHbSHTHFAeChekF1xKJdleo= - type: script - defer: true - - - src: https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe-ui-default.min.js - integrity: sha256-UKkzOn/w1mBxRmLLGrSeyB4e1xbrp4xylgAWb3M42pU= - type: script - defer: true - - - src: https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/default-skin/default-skin.min.css - type: style - - - src: https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.css - type: style - KaTeX: - src: https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css integrity: sha384-n8MVd4RsNIU0tAv4ct0nTaAbDJwPJzDEaqSD1odI+WdtXRGWt2kTvGFasHpSy3SV diff --git a/debug.sh b/debug.sh deleted file mode 100755 index 4d1312ebd..000000000 --- a/debug.sh +++ /dev/null @@ -1 +0,0 @@ -cd exampleSite && hugo server --gc --themesDir=../.. \ No newline at end of file diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts new file mode 100644 index 000000000..828648717 --- /dev/null +++ b/docs/.vitepress/config.ts @@ -0,0 +1,160 @@ +import { defineConfig } from 'vitepress' + +export default defineConfig({ + lang: 'en-US', + title: 'Stack', + description: 'Card-style Hugo theme designed for bloggers', + lastUpdated: true, + outDir: '../public', + + head: [ + ['link', { rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png' }], + ['link', { rel: 'icon', type: 'image/png', sizes: '32x32', href: '/favicon-32x32.png' }], + ['link', { rel: 'icon', type: 'image/png', sizes: '16x16', href: '/favicon-16x16.png' }], + ['link', { rel: 'manifest', href: '/site.webmanifest' }], + ['link', { rel: 'mask-icon', href: '/safari-pinned-tab.svg', color: '#5bbad5' }], + ['meta', { name: 'msapplication-TileColor', content: '#00aba9' }], + ['meta', { name: 'theme-color', content: '#ffffff' }], + ['script', { defer: "true", "data-domain": "stack.jimmycai.com", src: 'https://stat.jimmycai.com/js/include.js' }], + ], + + markdown: { + lineNumbers: true, + theme: 'one-dark-pro' + }, + + cleanUrls: true, + + themeConfig: { + logo: '/logo.png', + + footer: { + message: "Documentation released under the MIT License, logo designed by Jimmy Cai, all rights reserved.", + copyright: "Copyright © 2020 - Present Jimmy Cai", + }, + + sidebar: { + '/guide/': sidebarGuide(), + '/config/': sidebarGuide(), + '/writing/': sidebarGuide(), + }, + + nav: [ + { text: 'Guide', link: '/guide/' }, + { text: 'Config', link: '/config/' }, + ], + + socialLinks: [ + { icon: 'github', link: 'https://github.com/CaiJimmy/hugo-theme-stack' } + ], + + editLink: { + pattern: 'https://github.com/CaiJimmy/hugo-theme-stack/edit/master/docs/:path', + text: 'Edit this page on GitHub' + }, + + outline: [2, 3], + + carbonAds: { + code: 'CEAIE27W', + placement: 'stackjimmycaicom' + }, + + algolia: { + appId: '6OC1XCG4R5', + apiKey: '7779946cc768ec3699123e60a91d0ddc', + indexName: 'stack-jimmycai', + } + }, +}); + +function sidebarGuide() { + return [ + { + text: 'Introduction', + collapsible: true, + items: [ + { text: 'About Stack', link: '/guide/' }, + { text: 'Getting Started', link: '/guide/getting-started' }, + { text: 'Modify Theme', link: '/guide/modify-theme' } + ] + }, + { + text: 'Writing', + collapsible: true, + items: [ + { text: 'Markdown', link: '/writing/markdown' }, + { + text: 'Frontmatter Configs', link: '/writing/frontmatter' + }, + { text: 'Shortcodes', link: '/writing/shortcodes' }, + ] + }, + { + text: 'Config', + collapsible: true, + items: [ + { + text: 'Introduction', + link: '/config/' + }, + { + text: 'Site Configs', + link: '/config/site' + }, + { + text: 'i18n Configs', + link: '/config/i18n' + }, + { + text: 'Custom Menu', + link: '/config/menu' + }, + { + text: 'Custom Header / Footer', + link: '/config/header-footer' + }, + { + text: 'Date Format', + link: '/config/date-format' + }, + { + text: 'Sidebar', + link: '/config/sidebar' + }, + { + text: 'Footer', + link: '/config/footer' + }, + { + text: 'Article', + link: '/config/article' + }, + { + text: 'Comments', + link: '/config/comments' + }, + { + text: 'Widgets', + link: '/config/widgets' + }, + { + text: 'Open Graph', + link: '/config/open-graph' + }, + { + text: 'Default Image', + link: '/config/default-image' + }, + { + text: 'Color Scheme', + link: '/config/color-scheme' + }, + { + text: 'Image Processing', + link: '/config/image-processing' + } + ] + }, + ] +} \ No newline at end of file diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css new file mode 100644 index 000000000..b8ceb0cc4 --- /dev/null +++ b/docs/.vitepress/theme/custom.css @@ -0,0 +1,6 @@ +:root { + --vp-c-brand-1: var(--vp-c-green-1); + --vp-c-brand-2: var(--vp-c-green-2); + --vp-c-brand-3: var(--vp-c-green-3); + --vp-c-brand-soft: var(--vp-c-green-soft); +} \ No newline at end of file diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts new file mode 100644 index 000000000..3b7e84b8b --- /dev/null +++ b/docs/.vitepress/theme/index.ts @@ -0,0 +1,15 @@ +import DefaultTheme from 'vitepress/theme' +import './custom.css' + +export default { + ...DefaultTheme, + enhanceApp({ router }) { + const oldOnAfterRouteChanged = router.onAfterRouteChanged; + + router.onAfterRouteChanged = () => { + oldOnAfterRouteChanged && oldOnAfterRouteChanged(); + if (typeof _carbonads !== 'undefined') + _carbonads.refresh(); + } + } +} \ No newline at end of file diff --git a/docs/config/article.md b/docs/config/article.md new file mode 100644 index 000000000..37b3da02c --- /dev/null +++ b/docs/config/article.md @@ -0,0 +1,49 @@ +# Article + +Configuration for the article page. + +Fields under `[Params.Article]`. + +## math + +- Type: `bool` + +Enable math support by [KaTeX](https://katex.org/). Can be overridden by front matter field `toc`. + +## toc + +- Type: `bool` + +Enable by default table of contents. Can be overridden by front matter field `toc`. + +::: warning +You will still need to add [`toc` widget](widgets.md#toc) to the sidebar to display the table of contents. +::: + + +## readingTime + +- Type: `bool` +- Default: `true` + +Display an estimated reading time for the article. + +## license + +- Type: `map[string]:(bool|string)` + +Configurations related with license. + +### license.enabled + +- Type: `bool` +- Default: `false` + +Display license information under the article. + +### license.default + +- Type: `string` +- Default: `Licensed under CC BY-NC-SA 4.0` + +Default license text displayed under the article. Can be overridden by front matter field `license`. \ No newline at end of file diff --git a/docs/config/color-scheme.md b/docs/config/color-scheme.md new file mode 100644 index 000000000..9c187e8cb --- /dev/null +++ b/docs/config/color-scheme.md @@ -0,0 +1,22 @@ +# Color Scheme + +Light and dark color schemes are available in this theme. + + +## toggle + +- Type: `bool` +- Default: `true` + +Display the color scheme toggle button. + +If it's set to `false`, the color scheme will be determined by the `default` option. + +## default + +- Type: `string (light|dark|auto)` +- Default: `auto` + +The default color scheme, used when the `toggle` option is set to `false` or when the user visits the site for the first time. + +When set to `auto`, the color scheme will be determined by the user's system preference (`prefers-color-scheme` media query). \ No newline at end of file diff --git a/docs/config/comments.md b/docs/config/comments.md new file mode 100644 index 000000000..4ef7129a0 --- /dev/null +++ b/docs/config/comments.md @@ -0,0 +1,56 @@ +# Comments + +Comment system is a very important part of a blog. It allows readers to express their opinions and thoughts about the post. It also allows the author to interact with the readers. + +Stack currently supports the following comment systems: + +- [Cactus](https://cactus.chat/) +- [Cusdis](https://cusdis.com/) +- [Disqus](https://disqus.com/) +- [DisqusJS](https://github.com/SukkaW/DisqusJS) +- [Giscus](https://giscus.app/) +- [Gitalk](https://github.com/gitalk/gitalk) +- [Remark42](https://remark42.com/) +- [Twikoo](https://twikoo.js.org/) +- [utterances](https://utteranc.es/) +- [Vssue](https://vssue.js.org/) +- [Waline](https://waline.js.org/) + +Each comment system has its own configuration options placed under `[Params.Comments.COMMENT_SYSTEM]` section. + +For example, utterances's configuration options are placed under `[Params.Comments.utterances]` section. + +::: tip +A full list of supported configuration options can be found in [here](https://github.com/CaiJimmy/hugo-theme-stack/blob/master/config.yaml#L38) + +For more information about the meaning of each configuration option, please refer to the documentation of the comment system. +::: + +::: warning +In case of Disqus, the only configuration option is `disqusShortname`, which is not available at `[Params.Comments.disqus]` section. Instead, it is placed at root section of configuration file. +::: + +## enabled + +- Type: `bool` +- Default: `false` + +Enable / disable comment system. + +## provider + +- Type: `string` + +Comment system provider. Possible values are: + +- `cactus` +- `cusdis` +- `disqus` +- `disqusjs` +- `giscus` +- `gitalk` +- `remark42` +- `twikoo` +- `utterances` +- `vssue` +- `waline` \ No newline at end of file diff --git a/docs/config/date-format.md b/docs/config/date-format.md new file mode 100644 index 000000000..70cc9446a --- /dev/null +++ b/docs/config/date-format.md @@ -0,0 +1,19 @@ +# Date format + +Fields under `[Params.DateFormat]`. + +Date format setting. Notice that Go's date format is slightly different than other programming language, take a look at official documentation: [dateFormat](https://gohugo.io/functions/dateformat/) + +## published + +- Type: `string` +- Default: `Jan 02, 2006` + +Page's publish date format. + +## lastUpdated + +- Type: `string` +- Default: `Jan 02, 2006 15:04 MST` + +Page's last updated date format \ No newline at end of file diff --git a/docs/config/default-image.md b/docs/config/default-image.md new file mode 100644 index 000000000..aa88e8117 --- /dev/null +++ b/docs/config/default-image.md @@ -0,0 +1,29 @@ +# Default Image + +The default image is the image that will be used on a page if no featured image is set. This is useful for Open Graph and Twitter cards. + +## opengraph + +The default image for Open Graph and Twitter. + +### opengraph.enabled + +- Type: `bool` +- Default: `false` + +Enable the default image for Open Graph and Twitter. + +### opengraph.src + +- Type: `string` + +Path to the image file. + +### opengraph.local + +- Type: `bool` +- Default: `false` + +If `true`, the image is a local file, and must be placed under `assets` folder. Otherwise, it is a remote URL. + +For example, if `src` is set to `img/default.jpg`, the image file must be placed under `assets/img/default.jpg`. \ No newline at end of file diff --git a/docs/config/footer.md b/docs/config/footer.md new file mode 100644 index 000000000..0245e7595 --- /dev/null +++ b/docs/config/footer.md @@ -0,0 +1,17 @@ +# Footer + +The footer is the last section of the page. It is usually used to display the copyright information. + +Fields under `[Params.Footer]`. + +## since + +- Type: `int` + +The year when the site is created. + +## customText + +- Type: `string` + +Custom text displayed in the footer. HTML is supported. \ No newline at end of file diff --git a/docs/config/header-footer.md b/docs/config/header-footer.md new file mode 100644 index 000000000..477a582e7 --- /dev/null +++ b/docs/config/header-footer.md @@ -0,0 +1,38 @@ +# Custom Header / Footer + +There are two empty files reserved for custom HTML in the theme, useful for adding custom scripts or stylesheets: + +* `layouts/partials/head/custom.html` +* `layouts/partials/footer/custom.html` + +To overwrite them: + +1. Create `layout/partials/footer/custom.html` under your Hugo site folder +2. Insert custom code in that file. + +## Example: Custom font family for article content + +By default, this theme uses [Lato](https://fonts.google.com/specimen/Lato) for article content. This example shows how to use another font instead. For example, let's change article font family to [Merriweather](https://fonts.google.com/specimen/Merriweather). + +Create `layouts/partials/head/custom.html` under your Hugo site folder, with following code: + +```html + + + +``` \ No newline at end of file diff --git a/docs/config/i18n.md b/docs/config/i18n.md new file mode 100644 index 000000000..ad2ab0184 --- /dev/null +++ b/docs/config/i18n.md @@ -0,0 +1,38 @@ +# i18n + +Hugo has built-in support for multilingual sites. You can find more information about it in the [official documentation](https://gohugo.io/content-management/multilingual/). + +Translation files are placed in the `i18n` directory. The file name is the language code. For example, the `en.yaml` file is the translation file for English. + +In order to use a language, set `DefaultContentLanguage` to the language code in the configuration file. For example, if you want to use English, set `DefaultContentLanguage` to `en`. + +Currently, the theme supports the following languages: + +* `ar`: Arabic +* `bn`: Bengali +* `ca`: Catalan +* `de`: German +* `el`: Greek +* `en`: English +* `es`: Spanish +* `fa`: Persian +* `fr`: French +* `hu`: Hungarian +* `id`: Indonesian +* `it`: Italian +* `ja`: Japanese +* `ko`: Korean +* `nl`: Dutch +* `pl`: Polish +* `pt-br`: Portuguese +* `ru`: Russian +* `th`: Thai +* `tr`: Turkish +* `uk`: Ukrainian +* `zh-cn`: Chinese (Simplified) +* `zh-hk`: Chinese (Traditional) (Hong Kong) +* `zh-tw`: Chinese (Traditional) (Taiwan) + +::: tip +PRs for more language support are welcome 😉. +::: \ No newline at end of file diff --git a/docs/config/image-processing.md b/docs/config/image-processing.md new file mode 100644 index 000000000..3ab7ca92f --- /dev/null +++ b/docs/config/image-processing.md @@ -0,0 +1,27 @@ +# Image Processing + +This theme uses Hugo's built-in image processing features to resize and optimize local images (included using page bundle feature). This is done automatically when you build your site. + +When there are many images in your site, this can slow down the build process. You can choose to disable this feature here. + +## cover + +- Type: `map[string]bool` + +### cover.enabled + +- Type: `bool` +- Default: `true` + +Enable image processing for cover (featured) images. + +## content + +- Type: `map[string]bool` + +### content.enabled + +- Type: `bool` +- Default: `true` + +Enable image processing for images in content. \ No newline at end of file diff --git a/docs/config/index.md b/docs/config/index.md new file mode 100644 index 000000000..89ad563cd --- /dev/null +++ b/docs/config/index.md @@ -0,0 +1,13 @@ +# Introduction + +Hugo acepts `TOML`, `YAML` and `JSON` as configuration formats. This theme currently uses `YAML` and `TOML` as configuration formats. + +::: info +In the foreseeable future, this theme will migrate all its configurations to `TOML` format. +::: + +If you are using `hugo-theme-stack-starter` template, you can find the configuration file under `config/_default/` folder, separated in different major sections to make it easier to find the configuration you want to modify. + +A full list of available configurations can be found in `config.yaml` file located in the root directory of this theme. (If it is not there, please send an issue to let me know.) + +There are plenty tools that converts `YAML` to `TOML` and vice versa. You can use them to convert the configuration file to the format you prefer. \ No newline at end of file diff --git a/docs/config/menu.md b/docs/config/menu.md new file mode 100644 index 000000000..b4df46907 --- /dev/null +++ b/docs/config/menu.md @@ -0,0 +1,67 @@ +# Custom Menu + +There are two menus in the theme: the main menu (`menu.main`) and the social menu (`menu.social`, icon only). They can be configured in a similar way. + +## First Method (Recommended) +If the menu item you'd like to add is a page, add `menu` field to its Front Matter: + +```yaml +menu: + main: + name: title (optional) + weight: -90 + params: + icon: icon-name +``` + +## Second Method + +::: warning +This method is not recommended, because the theme can not detect if the current page is in the menu, and the menu item will not be highlighted. +::: + +If the menu item you'd like to add is not a page, you can add it to the menu section in the config file: + +Example in TOML: + +```toml +[menu] +[[menu.main]] + name = "Home" + url = "/" + weight = 10 + identifier = "home" + [menu.main.params] + icon = "home" + newTab = true +``` + +Or in YAML: + +```yaml +menu: + main: + - identifier: home + name: Home + url: / + weight: -100 + params: + icon: home + newTab: true +``` + +* `identifier`: Item ID +* `name`: Display text +* `url`: Link +* `weight`: Priority of the item, lower value means higher priority. +* `params`: + * `icon`: Specify which SVG icon should be used + * `newTab`: Open this link in new tab + +If `params.icon` is set to `archive`, theme will look for `archive.svg` under `assets/icons` folder. + +## Add custom icon + +This theme comes with some SVG icons from [Tabler Icons](https://tablericons.com). You can find them under theme folder `assets/icons`. + +To include more icons, just download them from website above, and place them under `assets/icons` folder of your Hugo site. \ No newline at end of file diff --git a/docs/config/open-graph.md b/docs/config/open-graph.md new file mode 100644 index 000000000..20c3561d4 --- /dev/null +++ b/docs/config/open-graph.md @@ -0,0 +1,26 @@ +# Open Graph + +The Open Graph protocol enables any web page to become a rich object in a social graph. + +For more information, see [Open Graph protocol](http://ogp.me/). + +Fields are under `[Params.opengraph]` section. + +## twitter + +- type: `map[string]string` + +Available fields: + +### site + +- type: `string` + +The Twitter account name of the site (without `@`). + +### card + +- type: `string` + +[Twitter card type](https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/abouts-cards). Available values: `summary`, `summary_large_image`. + diff --git a/docs/config/sidebar.md b/docs/config/sidebar.md new file mode 100644 index 000000000..bbc5df8fd --- /dev/null +++ b/docs/config/sidebar.md @@ -0,0 +1,51 @@ +# Sidebar + +Settings related with left-side sidebar. + +Fields are under `[Params.Sidebar]` section. + +## compact + +- Type: `bool` +- Default: `false` + +Enable compact version of sidebar. + +## emoji + +- Type: `string` + +Emoji displayed above the avatar. + +## subtitle + +- Type: `string` + +Subtitle displayed below the site title. + +## avatar + +- Type: `map[string]:(bool|string)` + +Configurations related with avatar. + +### avatar.enable + +- Type: `bool` +- Default: `true` + +Enable avatar. + +### avatar.src + +- Type: `string` +- Default: `img/avatar.png` + +Path to avatar image. + +### avatar.local + +- Type: `bool` +- Default: `true` + +If `true`, the avatar image should be placed at `assets/${avatar.src}`, this allows theme to automatically resize the image. diff --git a/docs/config/site.md b/docs/config/site.md new file mode 100644 index 000000000..d68729a9a --- /dev/null +++ b/docs/config/site.md @@ -0,0 +1,40 @@ +# Site-wide settings + +Fields under `[Params]`: + +## description + +- Type: `string` + +Site description. By default, it falls back to `.Params.Sidebar.Subtitle`. + +## mainSections + +- Type: `[string]` +- Default: `["post"]` + +Pages places under this/those sections will be shown on homepage and archive page. + +For more information, take a look at Hugo's documentation on [Content Sections](https://gohugo.io/content-management/sections/). + +## featuredImageField + +- Type: `string` +- Default: `image` + +Front Matter **field** used to get the featured image of a page. + +## rssFullContent + +- Type: `bool` +- Default: `true` + +Output page's full content in RSS. + +## favicon + +- Type: `string` + +Site favicon path. + +For example, if you want to use the favicon in `static/favicon.ico`, set `favicon` to `/favicon.ico`. \ No newline at end of file diff --git a/docs/config/widgets.md b/docs/config/widgets.md new file mode 100644 index 000000000..1373a4897 --- /dev/null +++ b/docs/config/widgets.md @@ -0,0 +1,46 @@ +# Widgets + +Widgets are placed at right sidebar of the blog. They are used to display some information such as categories, tags, etc. + +You can configure which widgets to display and their order in the homepage and post page. + +`widget.homepage` and `widget.page` are arrays of maps. Each map contains two keys: `type` and `params`. `type` is the name of the widget. `params` is the configuration of the widget. + +## Available widgets + +### archives + +Display a list of years with the number of posts published in each year. + +You need to create a page with `layout: archives` previously. + +#### Paramters + +- `limit`: Number of years to display. Default: `10`. + +### search + +Display a search box. + +You need to create a page with `layout: search` previously. + +### categories + +Display a list of categories available in the blog. + +#### Parameters + +- `limit`: number of categories to display. Default: 10 + +### toc + +Display a table of contents of the page. + +### tag-cloud + +Display a tag cloud. + +#### Parameters + +- `limit`: number of tags to display. Default: 10 + diff --git a/docs/guide/configuration.md b/docs/guide/configuration.md new file mode 100644 index 000000000..902e54f16 --- /dev/null +++ b/docs/guide/configuration.md @@ -0,0 +1 @@ +## Configuration \ No newline at end of file diff --git a/docs/guide/getting-started.md b/docs/guide/getting-started.md new file mode 100644 index 000000000..ec1c07d1b --- /dev/null +++ b/docs/guide/getting-started.md @@ -0,0 +1,92 @@ +# Getting Started + +::: tip +Try this quickstart template to get started with Stack and Hugo in a few minutes: +https://github.com/CaiJimmy/hugo-theme-stack-starter +::: + +## Requirements +Before you start, make sure you have installed Hugo **extended version**. For more information, see [Hugo's documentation](https://gohugo.io/getting-started/installing/). + +This theme uses SCSS and TypeScript, that's why Hugo extended version is required. If you are using a non-extended Hugo installation, you will get the following error: + +``` +Error: Error building site: TOCSS: failed to transform "scss/style.scss" (text/x-scss): this feature is not available in your current Hugo version +``` + +Once you have installed Hugo, you can check the version by running the following command: + +```bash +hugo version +``` + +Which should output something like this (the version number may be different), notice the `extended` keyword: + +``` +hugo v0.102.3-b76146b129d7caa52417f8e914fc5b9271bf56fc+extended windows/amd64 BuildDate=2022-09-01T10:16:19Z VendorInfo=gohugoio +``` + +The minimum required Hugo version can be seen in the [theme's `theme.toml` file](https://github.com/CaiJimmy/hugo-theme-stack/blob/master/theme.toml#L23) + +## Installation + +### Git +On the master branch, you can find the theme's latest source code. To use the latest version, you can clone the repository to `themes/hugo-theme-stack` by running the following command in the root directory of your Hugo site: + +```bash +git clone https://github.com/CaiJimmy/hugo-theme-stack/ themes/hugo-theme-stack +``` + +If you are already using Git for your site, you can add the theme as a submodule by running the following command in the root directory of your Hugo site: + +```bash +git submodule add https://github.com/CaiJimmy/hugo-theme-stack/ themes/hugo-theme-stack +``` + +### Hugo module + +::: warning +Using this method, there won't be any file under `themes` directory. In order to modify the theme, you will have to copy the file you want to modify to the same directory under `layouts` directory. + +For example, in order to modify the `themes/hugo-theme-stack/layouts/partials/header.html` file, you will have to copy it to `layouts/partials/header.html` and modify it there (copy the code from theme's repository). The same applies to `assets` and `static` directories. +::: + +This theme is also available as a [Hugo module](https://gohugo.io/hugo-modules/). Run the following command in the root directory of your Hugo site: + +First turn your site into a Hugo module (in case you haven't done it yet): + +```sh +hugo mod init github.com/me/my-new-blog +``` + +Then import the theme as a dependency adding the following line to the `module` section of your site's configuration file. + +```toml +# config.toml +[[module.imports]] +path = "github.com/CaiJimmy/hugo-theme-stack/v3" +``` + +```yaml +# config.yaml +module: + imports: + - path: github.com/CaiJimmy/hugo-theme-stack/v3 +``` + +This makes Hugo use the latest stable `v3` version of the theme (available in release page, which probably won't coincide with the latest commit in the `master` branch). + +To update the theme to the latest version, run the following command: + +```sh +hugo mod get -u github.com/CaiJimmy/hugo-theme-stack/v3 +hugo mod tidy +``` + +::: info +In the future, if a new major version of the theme is released, you will need to manually update the version number in the `path` field. +::: + +### Download manually (not recommended) + +You can also download the theme from the [release page](https://github.com/CaiJimmy/hugo-theme-stack/releases) and extract it to `themes/hugo-theme-stack` directory. \ No newline at end of file diff --git a/docs/guide/index.md b/docs/guide/index.md new file mode 100644 index 000000000..021d7d4a7 --- /dev/null +++ b/docs/guide/index.md @@ -0,0 +1,54 @@ +# Welcome + +Stack is a simple card-style Hugo theme designed for Bloggers. Here are some of the features: + +* Responsive images support +* Lazy load images +* Dark mode +* Local search +* [PhotoSwipe](https://photoswipe.com/) integration +* Archive page template +* Full native JavaScript, no jQuery or any other frameworks are used +* No CSS framework, keep it simple and minimal +* Properly cropped thumbnails +* Subsection support +* Table of contents + +## Copyright + +**Licensed under the GNU General Public License v3.0** + +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🙏. + +## Sponsoring + +If you like this theme, give it a star, and consider supporting its development: + + + +Buy Me a Coffee at ko-fi.com + +Your support is greatly appreciated :) + +## Thanks to + +| Project | Licence | +| ---------------------------------------------------------------- | ---------------------------------------------------------------------------- | +| [PhotoSwipe](https://photoswipe.com/) | [MIT](https://github.com/dimsemenov/PhotoSwipe/blob/master/LICENSE) | +| [Normalize.css](https://github.com/necolas/normalize.css) | [MIT](https://github.com/necolas/normalize.css/blob/master/LICENSE.md) | +| [Node Vibrant](https://github.com/Vibrant-Colors/node-vibrant) | [MIT](https://github.com/Vibrant-Colors/node-vibrant/blob/master/LICENSE.md) | +| [Tabler icons](https://github.com/tabler/tabler-icons) | [MIT](https://github.com/tabler/tabler-icons/blob/master/LICENSE) | +| [jonsuh/hamburgers](https://github.com/jonsuh/hamburgers) | [MIT](https://github.com/jonsuh/hamburgers/blob/master/LICENSE) | +| [lepture/yue.css](https://github.com/lepture/yue.css) | MIT | +| [Typlog](https://typlog.com/) | The author gave me the permission | +| [xieranmaya/blog#6](https://github.com/xieranmaya/blog/issues/6) | - | + +### References +Some references that I took while building this theme: + +| Project | Licence | +| --------------------------------------------------------------------------- | ------------------------------------------------------------------------ | +| [artchen/hexo-theme-element](https://github.com/artchen/hexo-theme-element) | [MIT](https://github.com/artchen/hexo-theme-element/blob/master/LICENSE) | +| [MunifTanjim/minimo](https://github.com/MunifTanjim/minimo) | [MIT](https://github.com/MunifTanjim/minimo/blob/master/LICENSE) | \ No newline at end of file diff --git a/docs/guide/modify-theme.md b/docs/guide/modify-theme.md new file mode 100644 index 000000000..13b9e9443 --- /dev/null +++ b/docs/guide/modify-theme.md @@ -0,0 +1,22 @@ +# Modify theme + +Depending on how you installed the theme, it might be harder or easier to modify it. + +## Hugo module + +Using this method, there won't be any file under `themes` directory. In order to modify the theme, you will have to copy the file you want to modify to the same directory under `layouts` directory. + +For example, in order to modify the `themes/hugo-theme-stack/layouts/partials/head/custom.html` file, you will have to copy it to `layouts/partials/head/custom.html` and modify it there (copy the code from theme's repository). +The same applies to `assets` and `static` directories. + +## Git submodule + +::: tip +The method described above for Hugo module works here too. In fact it's the recommended way for small changes. +::: + +If you installed the theme through Git / Git submodule, you can modify the theme file directly and see the changes in your local site. + +However, **you can not commit and push the changes directly** since you don't have the permission to push to the theme repository. + +You need to **fork** the theme repository and push your changes to your forked repository (change submodule's repository url). Then, you can commit those changes to your site repository. diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 000000000..2a6187fc5 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,38 @@ +--- +layout: home + +title: Stack +titleTemplate: Card-style Hugo theme designed for bloggers + +hero: + name: Stack + text: Card-style theme designed for bloggers + image: + src: /logo.png + alt: Stack + actions: + - theme: brand + text: Get Started + link: /guide/getting-started + - theme: alt + text: View Demo + link: /demo/ + target: _blank + - theme: alt + text: View on GitHub + link: https://github.com/CaiJimmy/hugo-theme-stack + +features: + - title: No CSS and JavaScript framework + details: Keep your site lightweight and fast. All the styles are written in SCSS and the scripts are written in vanilla JavaScript. + icon: ⚡️ + - title: Dark mode + details: Dark mode is supported by default. It will be automatically enabled when the system is in dark mode. + icon: 🌙 + - title: Multilingual mode and RTL support + details: Support for multiple languages and right-to-left languages out of the box. No need to worry about i18n. + icon: 🌐 + - title: A set of useful features + details: Table of contents, local search, code highlighting, image zooming, and more. + icon: 🧰 +--- \ No newline at end of file diff --git a/docs/writing/frontmatter.md b/docs/writing/frontmatter.md new file mode 100644 index 000000000..0fa241001 --- /dev/null +++ b/docs/writing/frontmatter.md @@ -0,0 +1,73 @@ +# Frontmatter Configs + +[[toc]] + +## description + +* Type: `string` +* Available in: single pages and list pages + +Description of the page. + +## image + +* Type: `string` +* Available in: single pages and list pages + +Featured image of the page. + +## comments + +* Type: `bool` +* Available in: single pages + +Show / hide comment section of the page. + +## license + +* Type: `string|bool` +* Available in: single pages +* Default: `.Site.Params.Article.License.Default` + +License of the page. If it's set to `false`, the license section will be hidden. + +## math + +* Type: `bool` +* Available in: single pages + +Enable / disable KaTeX rendering. + +## toc + +* Type: `bool` +* Available in: single pages +* Default: `.Site.Params.Article.toc` + +Show / hide table of contents of the page. + +::: info +TOC will be shown only if the page has at least one heading. +::: + +## style + +* Type: `map[string]string` +* Available in: list pages + +Additional CSS styles for taxonomy term badge that appears in article page. + +Currently only `background` (background of the badge) and `color` (text color) are supported. + +## keywords + +* Type: `[]string` + +Keywords of the page. Useful for SEO. + +## readingTime + +* Type: `bool` +* Default: `.Site.Params.Article.ReadingTime` + +Show / hide reading time of the page. diff --git a/docs/writing/markdown.md b/docs/writing/markdown.md new file mode 100644 index 000000000..a8c5649a2 --- /dev/null +++ b/docs/writing/markdown.md @@ -0,0 +1,52 @@ +# Writing + +Stack uses Hugo's **page bundles** to organize your content. A page bundle is a directory that contains a content file and any related resources. For example, a page bundle for a blog post might look like this: + +``` +content +└── post + └── my-first-post + ├── index.md + ├── image1.png + └── image2.png +``` + +This is the recommended way to organize your content. You can read more about page bundles in [Hugo's documentation](https://gohugo.io/content-management/page-bundles/). + +::: warning +Inserting external images is supported, but **it is not recommended**. + +Features like image gallery and image zooming will not work with external images. Those feature needs to know the image's dimensions, which is not possible with external images. +::: + +With above organization, you can insert images in your content like this: + +```markdown +--- content/post/my-first-post/index.md --- +![Image 1](image1.png) +![Image 2](image2.png) +``` + +## Insert image gallery + +To insert an image gallery, you need to create a page bundle for the gallery. For example: + +``` +content +└── gallery + └── my-first-gallery + ├── index.md + ├── image1.png + ├── image2.png + └── image3.png +``` + +Then, you can insert the gallery in your content like this: + +```markdown +--- content/gallery/my-first-gallery/index.md --- +![Image 1](image1.png) ![Image 2](image2.png) +![Image 3](image3.png) +``` + +Which will render in two rows, with two images in the first row and one image in the second row. diff --git a/docs/writing/shortcodes.md b/docs/writing/shortcodes.md new file mode 100644 index 000000000..5b4e55ce1 --- /dev/null +++ b/docs/writing/shortcodes.md @@ -0,0 +1,69 @@ +# Shortcodes + +Stack comes with a set of [shortcodes](https://gohugo.io/content-management/shortcodes/) that you can use in your content. + +This page only includes the shortcodes that are specific to Stack. Hugo's built-in shortcodes are documented [here](https://gohugo.io/content-management/shortcodes/#use-hugos-built-in-shortcodes). + +## Bilibili video + +Embed a [Bilibili](https://www.bilibili.com/) video. + +```markdown +{{< bilibili VIDEO_ID PART_NUMBER >}} +``` + +The `Video_ID` can be found in the URL of the video. For example, the video ID of `https://www.bilibili.com/video/av12345678` is `av12345678`. Both `AV` and `BV` are supported. + +The `PART_NUMBER` is optional. It can be used to specify the part of the video to play. For example, the part number of `https://www.bilibili.com/video/av12345678?p=2` is `2`. + +## Tencent video + +Embed a [Tencent Video](https://v.qq.com/) video. + +```markdown +{{< tencent VIDEO_ID >}} +``` + +The `Video_ID` can be found in the URL of the video. For example, the video ID of `https://v.qq.com/x/cover/hzgtnf6tbvfekfv/g0014r3khdw.html` is `g0014r3khdw`. + +## YouTube video + +Embed a [YouTube](https://www.youtube.com/) video. + +```markdown +{{< youtube VIDEO_ID >}} +``` + +The `Video_ID` can be found in the URL of the video. For example, the video ID of `https://www.youtube.com/watch?v=VIDEO_ID` is `VIDEO_ID`. + +## Generic video file + +Embed a video file. + +```markdown +{{< video VIDEO_URL >}} + +{{< video src="VIDEO_URL" autoplay="true" poster="./video-poster.png" >}} +``` + +The `VIDEO_URL` can be a URL or a path relative to the `static` directory. For example, `src="/video/my-video.mp4"` will embed the video file `static/video/my-video.mp4` of your site folder. + +The `autoplay` attribute is optional. It can be used to specify whether the video should be played automatically. The `poster` attribute is optional. It can be used to specify the poster image of the video. + +## GitLab + +Embed a [GitLab](https://gitlab.com/) snippets. + +```markdown +{{< gitlab SNIPPET_ID >}} +``` + +The `SNIPPET_ID` can be found in the URL of the snippet. For example, the snippet ID of `https://gitlab.com/-/snippets/1234567` is `1234567`. + +## Quote + +```markdown +{{< quote author="A famous person" source="The book they wrote" url="https://en.wikipedia.org/wiki/Book">}} +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +{{< /quote >}} +``` \ No newline at end of file diff --git a/exampleSite/assets/img/favicon.png b/exampleSite/assets/img/favicon.png new file mode 100644 index 000000000..74e8efae1 Binary files /dev/null and b/exampleSite/assets/img/favicon.png differ diff --git a/exampleSite/assets/img/logo.jpg b/exampleSite/assets/img/logo.jpg new file mode 100644 index 000000000..145804ecd Binary files /dev/null and b/exampleSite/assets/img/logo.jpg differ diff --git a/exampleSite/config/_default/hugo.yaml b/exampleSite/config/_default/hugo.yaml new file mode 100644 index 000000000..617c6d023 --- /dev/null +++ b/exampleSite/config/_default/hugo.yaml @@ -0,0 +1,25 @@ +baseurl: https://stack.jimmycai.com/demo/ +languageCode: en-us + +# Note: This title is overridden by the title in i18n config file +title: Hugo Theme Stack Starter + +theme: hugo-theme-stack + +DefaultContentLanguage: en + +# Set hasCJKLanguage to true if DefaultContentLanguage is in [zh-cn ja ko] +# This will make .Summary and .WordCount behave correctly for CJK languages. +hasCJKLanguage: false + +services: + disqus: + shortname: hugo-theme-stack + # GA Tracking ID + googleAnalytics: + id: + +publishDir: ../public/demo + +pagination: + pagerSize: 3 \ No newline at end of file diff --git a/exampleSite/config/_default/languages.yaml b/exampleSite/config/_default/languages.yaml new file mode 100644 index 000000000..68178f1da --- /dev/null +++ b/exampleSite/config/_default/languages.yaml @@ -0,0 +1,22 @@ +# Enable multilanguage site support +en: + languageName: English + title: Hugo Theme Stack Example Site + weight: 1 + params: + sidebar: + subtitle: Example description +zh-cn: + languageName: 中文 + title: Hugo 主题 Stack 演示站点 + weight: 2 + params: + sidebar: + subtitle: 演示说明 +ar: + languageName: عربي + languagedirection: rtl + title: موقع تجريبي + weight: 3 + sidebar: + subtitle: وصف تجريبي diff --git a/exampleSite/config/_default/markup.yaml b/exampleSite/config/_default/markup.yaml new file mode 100644 index 000000000..035a69849 --- /dev/null +++ b/exampleSite/config/_default/markup.yaml @@ -0,0 +1,27 @@ +goldmark: + extensions: + passthrough: + enable: true + delimiters: + block: + - - \[ + - \] + - - $$ + - $$ + inline: + - - \( + - \) + renderer: + unsafe: false # Allow HTML in markdown +tableOfContents: + endLevel: 4 + ordered: true + startLevel: 2 +highlight: + noClasses: false + codeFences: true + guessSyntax: true + lineNoStart: 1 + lineNos: true + lineNumbersInTable: true + tabWidth: 4 diff --git a/exampleSite/config/_default/menu.yaml b/exampleSite/config/_default/menu.yaml new file mode 100644 index 000000000..811ff41d1 --- /dev/null +++ b/exampleSite/config/_default/menu.yaml @@ -0,0 +1,15 @@ +### Custom menu +### See https://stack.jimmycai.com/config/menu +### To remove about, archive and search page menu item, remove `menu` field from their FrontMatter +main: [] +social: + - identifier: github + name: GitHub + url: https://github.com/CaiJimmy/hugo-theme-stack + params: + icon: brand-github + - identifier: twitter + name: Twitter + url: https://twitter.com + params: + icon: brand-twitter diff --git a/exampleSite/config/_default/params.yaml b/exampleSite/config/_default/params.yaml new file mode 100644 index 000000000..e3919f022 --- /dev/null +++ b/exampleSite/config/_default/params.yaml @@ -0,0 +1,34 @@ +# This params.yaml overrides the theme's default params.yaml. +# A full list of available params with their default values can be found in the theme's config/_default/params.yaml file. +favicon: img/favicon.png + +footer: + since: 2020 + +sidebar: + emoji: 🍥 + subtitle: Lorem ipsum dolor sit amet, consectetur adipiscing elit. + avatar: img/logo.jpg + +comments: + enabled: true + provider: disqus + +widgets: + homepage: + - type: search + - type: archives + params: + limit: 5 + - type: taxonomy + params: + limit: 10 + type: tags + icon: tag + - type: taxonomy + params: + limit: 10 + type: categories + icon: categories + page: + - type: toc diff --git a/exampleSite/config/_default/permalinks.yaml b/exampleSite/config/_default/permalinks.yaml new file mode 100644 index 000000000..23cf7332d --- /dev/null +++ b/exampleSite/config/_default/permalinks.yaml @@ -0,0 +1,3 @@ +# Permalinks format of each content section +post: /p/:slug/ +page: /:slug/ \ No newline at end of file diff --git a/exampleSite/config/_default/related.yaml b/exampleSite/config/_default/related.yaml new file mode 100644 index 000000000..269e46ad1 --- /dev/null +++ b/exampleSite/config/_default/related.yaml @@ -0,0 +1,9 @@ +# Related contents configuration +includeNewer: true +threshold: 60 +toLower: false +indices: + - name: tags + weight: 100 + - name: categories + weight: 200 diff --git a/exampleSite/content/page/archives/index.md b/exampleSite/content/page/archives/index.md index 2862debfb..f164e9e0e 100644 --- a/exampleSite/content/page/archives/index.md +++ b/exampleSite/content/page/archives/index.md @@ -3,6 +3,9 @@ title: "Archives" date: 2019-05-28 layout: "archives" slug: "archives" +outputs: + - html + - json menu: main: weight: -70 diff --git a/exampleSite/content/page/search/index.md b/exampleSite/content/page/search/index.md deleted file mode 100644 index b2a5943d0..000000000 --- a/exampleSite/content/page/search/index.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: "Search" -slug: "search" -layout: "search" -outputs: - - html - - json -menu: - main: - weight: -60 - params: - icon: search ---- \ No newline at end of file diff --git a/exampleSite/content/post/emoji-support/index.md b/exampleSite/content/post/emoji-support/index.md deleted file mode 100644 index bc3e3488d..000000000 --- a/exampleSite/content/post/emoji-support/index.md +++ /dev/null @@ -1,50 +0,0 @@ -+++ -author = "Hugo Authors" -title = "Emoji Support" -date = "2019-03-05" -description = "Guide to emoji usage in Hugo" -categories = [ - "Test" -] -tags = [ - "emoji", -] -image = "the-creative-exchange-d2zvqp3fpro-unsplash.jpg" -+++ - -Emoji can be enabled in a Hugo project in a number of ways. - -The [`emojify`](https://gohugo.io/functions/emojify/) function can be called directly in templates or [Inline Shortcodes](https://gohugo.io/templates/shortcode-templates/#inline-shortcodes). - -To enable emoji globally, set `enableEmoji` to `true` in your site's [configuration](https://gohugo.io/getting-started/configuration/) and then you can type emoji shorthand codes directly in content files; e.g. - -

🙈 :see_no_evil: 🙉 :hear_no_evil: 🙊 :speak_no_evil:

-
- -The [Emoji cheat sheet](http://www.emoji-cheat-sheet.com/) is a useful reference for emoji shorthand codes. - -*** - -**N.B.** The above steps enable Unicode Standard emoji characters and sequences in Hugo, however the rendering of these glyphs depends on the browser and the platform. To style the emoji you can either use a third party emoji font or a font stack; e.g. - -{{< highlight html >}} -.emoji { - font-family: Apple Color Emoji, Segoe UI Emoji, NotoColorEmoji, Segoe UI Symbol, Android Emoji, EmojiSymbols; -} -{{< /highlight >}} - -{{< css.inline >}} - -{{< /css.inline >}} diff --git a/exampleSite/content/post/emoji-support/the-creative-exchange-d2zvqp3fpro-unsplash.jpg b/exampleSite/content/post/emoji-support/the-creative-exchange-d2zvqp3fpro-unsplash.jpg deleted file mode 100644 index e34a59dba..000000000 Binary files a/exampleSite/content/post/emoji-support/the-creative-exchange-d2zvqp3fpro-unsplash.jpg and /dev/null differ diff --git a/exampleSite/content/post/markdown-syntax/index.md b/exampleSite/content/post/markdown-syntax/index.md index c584c4c4f..d710d8ef3 100644 --- a/exampleSite/content/post/markdown-syntax/index.md +++ b/exampleSite/content/post/markdown-syntax/index.md @@ -42,12 +42,12 @@ Itatur? Quiatae cullecum rem ent aut odis in re eossequodi nonsequ idebis ne sap The blockquote element represents content that is quoted from another source, optionally with a citation which must be within a `footer` or `cite` element, and optionally with in-line changes such as annotations and abbreviations. -#### Blockquote without attribution +### Blockquote without attribution > Tiam, ad mint andaepu dandae nostion secatur sequo quae. > **Note** that you can use *Markdown syntax* within a blockquote. -#### Blockquote with attribution +### Blockquote with attribution > Don't communicate by sharing memory, share memory by communicating.
> — Rob Pike[^1] @@ -63,7 +63,7 @@ Tables aren't part of the core Markdown spec, but Hugo supports supports them ou Bob | 27 Alice | 23 -#### Inline Markdown within tables +### Inline Markdown within tables | Italics | Bold | Code | | -------- | -------- | ------ | @@ -74,8 +74,7 @@ Tables aren't part of the core Markdown spec, but Hugo supports supports them ou | Lorem ipsum dolor sit amet, consectetur adipiscing elit. | Phasellus ultricies, sapien non euismod aliquam, dui ligula tincidunt odio, at accumsan nulla sapien eget ex. | Proin eleifend dictum ipsum, non euismod ipsum pulvinar et. Vivamus sollicitudin, quam in pulvinar aliquam, metus elit pretium purus | Proin sit amet velit nec enim imperdiet vehicula. | Ut bibendum vestibulum quam, eu egestas turpis gravida nec | Sed scelerisque nec turpis vel viverra. Vivamus vitae pretium sapien | ## Code Blocks - -#### Code block with backticks +### Code block with backticks ```html @@ -90,7 +89,7 @@ Tables aren't part of the core Markdown spec, but Hugo supports supports them ou ``` -#### Code block indented with four spaces +### Code block indented with four spaces @@ -103,21 +102,7 @@ Tables aren't part of the core Markdown spec, but Hugo supports supports them ou -#### Code block with Hugo's internal highlight shortcode -{{< highlight html >}} - - - - - Example HTML5 Document - - -

Test

- - -{{< /highlight >}} - -#### Diff code block +### Diff code block ```diff [dependencies.bevy] @@ -127,21 +112,27 @@ rev = "11f52b8c72fc3a568e8bb4a4cd1f3eb025ac2e13" + features = ["jpeg", "dynamic"] ``` +### One line code block + +```html +

A paragraph

+``` + ## List Types -#### Ordered List +### Ordered List 1. First item 2. Second item 3. Third item -#### Unordered List +### Unordered List * List item * Another item * And another item -#### Nested list +### Nested list * Fruit * Apple diff --git a/exampleSite/hugo.yaml b/exampleSite/hugo.yaml deleted file mode 100644 index 7cda528c3..000000000 --- a/exampleSite/hugo.yaml +++ /dev/null @@ -1,269 +0,0 @@ -baseurl: https://example.com/ -languageCode: en-us -theme: hugo-theme-stack -title: Example Site -copyright: Example Person - -# Theme i18n support -# Available values: ar, bn, 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] -# This will make .Summary and .WordCount behave correctly for CJK languages. -hasCJKLanguage: false - -languages: - en: - languageName: English - title: Example Site - weight: 1 - params: - sidebar: - subtitle: Example description - zh-cn: - languageName: 中文 - title: 演示站点 - weight: 2 - params: - sidebar: - subtitle: 演示说明 - ar: - languageName: عربي - languagedirection: rtl - title: موقع تجريبي - weight: 3 - params: - sidebar: - subtitle: وصف تجريبي - -services: - # Change it to your Disqus shortname before using - disqus: - shortname: "hugo-theme-stack" - # GA Tracking ID - googleAnalytics: - id: - -pagination: - pagerSize: 3 - -permalinks: - post: /p/:slug/ - page: /:slug/ - -params: - mainSections: - - post - featuredImageField: image - rssFullContent: true - favicon: # e.g.: favicon placed in `static/favicon.ico` of your site folder, then set this field to `/favicon.ico` (`/` is necessary) - - footer: - since: 2020 - customText: - - dateFormat: - published: Jan 02, 2006 - lastUpdated: Jan 02, 2006 15:04 MST - - sidebar: - emoji: 🍥 - subtitle: Lorem ipsum dolor sit amet, consectetur adipiscing elit. - avatar: - enabled: true - local: true - src: img/avatar.png - - article: - math: false - toc: true - readingTime: true - license: - enabled: true - default: Licensed under CC BY-NC-SA 4.0 - - comments: - enabled: true - provider: disqus - - disqusjs: - shortname: - apiUrl: - apiKey: - admin: - adminLabel: - - utterances: - repo: - issueTerm: pathname - label: - - beaudar: - repo: - issueTerm: pathname - label: - theme: - - remark42: - host: - site: - locale: - - vssue: - platform: - owner: - repo: - clientId: - clientSecret: - autoCreateIssue: false - - # Waline client configuration see: https://waline.js.org/en/reference/component.html - waline: - serverURL: - lang: - pageview: - emoji: - - https://unpkg.com/@waline/emojis@1.0.1/weibo - requiredMeta: - - name - - email - - url - locale: - admin: Admin - placeholder: - - twikoo: - envId: - region: - path: - lang: - - # See https://cactus.chat/docs/reference/web-client/#configuration for description of the various options - cactus: - 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: - category: - categoryID: - mapping: - lightTheme: - darkTheme: - reactionsEnabled: 1 - emitMetadata: 0 - - gitalk: - owner: - admin: - repo: - clientID: - clientSecret: - proxy: - - cusdis: - host: - id: - widgets: - homepage: - - type: search - - type: archives - params: - limit: 5 - - type: categories - params: - limit: 10 - - type: tag-cloud - params: - limit: 10 - page: - - type: toc - - opengraph: - twitter: - # Your Twitter username - site: - - # Available values: summary, summary_large_image - card: summary_large_image - - defaultImage: - opengraph: - enabled: false - local: false - src: - - colorScheme: - # Display toggle - toggle: true - - # Available values: auto, light, dark - default: auto - - imageProcessing: - cover: - enabled: true - content: - enabled: true - -### Custom menu -### See https://stack.jimmycai.com/config/menu -### To remove about, archive and search page menu item, remove `menu` field from their FrontMatter -menu: - main: [] - - social: - - identifier: github - name: GitHub - url: https://github.com/CaiJimmy/hugo-theme-stack - params: - icon: brand-github - - - identifier: twitter - name: Twitter - url: https://twitter.com - params: - icon: brand-twitter - -related: - includeNewer: true - threshold: 60 - toLower: false - indices: - - name: tags - weight: 100 - - - name: categories - weight: 200 - -markup: - goldmark: - extensions: - passthrough: - enable: true - delimiters: - block: - - - \[ - - \] - - - $$ - - $$ - inline: - - - \( - - \) - renderer: - ## Set to true if you have HTML content inside Markdown - unsafe: true - tableOfContents: - endLevel: 4 - ordered: true - startLevel: 2 - highlight: - noClasses: false - codeFences: true - guessSyntax: true - lineNoStart: 1 - lineNos: true - lineNumbersInTable: true - tabWidth: 4 diff --git a/go.mod b/go.mod index 63df63501..e75e573d2 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ -module github.com/CaiJimmy/hugo-theme-stack/v3 +module github.com/CaiJimmy/hugo-theme-stack/v4 go 1.17 diff --git a/i18n/ar.yaml b/i18n/ar.yaml index 63101aab8..6e391e571 100644 --- a/i18n/ar.yaml +++ b/i18n/ar.yaml @@ -1,74 +1,39 @@ -toggleMenu: - other: اخفي القائمة +toggleMenu: اخفي القائمة -darkMode: - other: الوضع الداكن +darkMode: الوضع الداكن list: page: one: "{{ .Count }} صفحه" other: "{{ .Count }} صفحات" - - section: - other: قسم - + section: قسم subsection: one: قسم فرعي other: اقسام فرعية article: - back: - other: خلف - - tableOfContents: - other: جدول المحتويات - - relatedContent: - other: محتوى مشابهه - - lastUpdatedOn: - other: التعديل الاخير - + back: خلف + tableOfContents: جدول المحتويات + relatedContent: محتوى مشابهه + lastUpdatedOn: التعديل الاخير readingTime: one: "تُقرأ خلال دقيقة" other: "تُقرأ خلال {{ .Count }} دقائق" notFound: - title: - other: غير موجود - - subtitle: - other: تعذر العثور على الصفحة المطلوبة. + title: غير موجود + subtitle: تعذر العثور على الصفحة المطلوبة. widget: archives: - title: - other: الارشيفات - - more: - other: اكثر - - tagCloud: - title: - other: وسوم - - categoriesCloud: - title: - other: التصنيفات + title: الارشيفات + more: اكثر search: - title: - other: بحث - - placeholder: - other: اكتب... - - resultTitle: - other: "#PAGES_COUNT نتيجة (#TIME_SECONDS ثواني)" + title: بحث + placeholder: اكتب... + resultTitle: "#PAGES_COUNT نتيجة (#TIME_SECONDS ثواني)" footer: - builtWith: - other: "مبني بستخدام {{ .Generator }}" - - designedBy: - other: "قالب {{ .Theme }} مصمم من {{ .DesignedBy }}" + builtWith: "مبني بستخدام {{ .Generator }}" + designedBy: "قالب {{ .Theme }} مصمم من {{ .DesignedBy }}" diff --git a/i18n/bn.yaml b/i18n/bn.yaml index 36f25a3d5..ede587e28 100644 --- a/i18n/bn.yaml +++ b/i18n/bn.yaml @@ -1,73 +1,48 @@ -toggleMenu: - other: টগল মেনু +toggleMenu: টগল মেনু -darkMode: - other: ডার্ক মোড +darkMode: ডার্ক মোড list: page: one: "{{ .Count }} পাতা" other: "{{ .Count }} পাতা" - section: - other: অনুচ্ছেদ + section: অনুচ্ছেদ subsection: one: উপ-অনুচ্ছেদ other: উপ-অনুচ্ছেদ article: - back: - other: পেছনে + back: পেছনে - tableOfContents: - other: সূচিপত্র + tableOfContents: সূচিপত্র - relatedContent: - other: সম্পর্কিত বিষয়বস্তু + relatedContent: সম্পর্কিত বিষয়বস্তু - lastUpdatedOn: - other: সর্বশেষ আপডেট করা হয়েছে + lastUpdatedOn: সর্বশেষ আপডেট করা হয়েছে readingTime: one: "{{ .Count }} মিনিটে পড়া যাবে" other: "{{ .Count }} মিনিটে পড়া যাবে" notFound: - title: - other: পাওয়া যায়নি + title: পাওয়া যায়নি - subtitle: - other: এই পাতাটি বিদ্যমান নেই + subtitle: এই পাতাটি বিদ্যমান নেই widget: archives: - title: - other: আর্কাইভ - - more: - other: আরও - - tagCloud: - title: - other: ট্যাগ - categoriesCloud: - title: - other: বিভাগ + title: আর্কাইভ + more: আরও search: - title: - other: অনুসন্ধান + title: অনুসন্ধান - placeholder: - other: কিছু টাইপ করুন... + placeholder: কিছু টাইপ করুন... - resultTitle: - other: "#PAGES_COUNT পাতা (#TIME_SECONDS সেকেন্ড)" + resultTitle: "#PAGES_COUNT পাতা (#TIME_SECONDS সেকেন্ড)" footer: - builtWith: - other: "{{ .Generator }} দিয়ে নির্মিত" - - designedBy: - other: "থিম {{ .Theme }} ডিজাইন করেছেন {{ .DesignedBy }}" + builtWith: "{{ .Generator }} দিয়ে নির্মিত" + designedBy: "থিম {{ .Theme }} ডিজাইন করেছেন {{ .DesignedBy }}" diff --git a/i18n/ca.yaml b/i18n/ca.yaml index af4167eea..7812049c3 100644 --- a/i18n/ca.yaml +++ b/i18n/ca.yaml @@ -1,73 +1,39 @@ -toggleMenu: - other: Toggle Menu +toggleMenu: Toggle Menu -darkMode: - other: Mode fosc +darkMode: Mode fosc list: page: one: "{{ .Count }} pàgina" other: "{{ .Count }} pàgines" - - section: - other: Secció - + section: Secció subsection: one: Subsecció other: Subseccions article: - back: - other: Tornar - - tableOfContents: - other: Taula de contingut - - relatedContent: - other: Continguts relacionats - - lastUpdatedOn: - other: Última vegada actualitzat - + back: Tornar + tableOfContents: Taula de contingut + relatedContent: Continguts relacionats + lastUpdatedOn: Ú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 + title: No Trobat + subtitle: Aquesta pàgina no existeix widget: archives: - title: - other: Arxiu - - more: - other: Més - - tagCloud: - title: - other: Etiquetes - categoriesCloud: - title: - other: Categories + title: Arxiu + more: Més search: - title: - other: Cerca - - placeholder: - other: Tecleja alguna cosa... - - resultTitle: - other: "#PAGES_COUNT pàgines en (#TIME_SECONDS segons)" + title: Cerca + placeholder: Tecleja alguna cosa... + resultTitle: "#PAGES_COUNT pàgines en (#TIME_SECONDS segons)" footer: - builtWith: - other: Creat amb {{ .Generator }} - - designedBy: - other: Tema {{ .Theme }} dissenyat per {{ .DesignedBy }} + builtWith: Creat amb {{ .Generator }} + designedBy: Tema {{ .Theme }} dissenyat per {{ .DesignedBy }} diff --git a/i18n/de.yaml b/i18n/de.yaml index 7ab5b56ec..f7b4c7369 100644 --- a/i18n/de.yaml +++ b/i18n/de.yaml @@ -1,74 +1,39 @@ -toggleMenu: - other: Menü umschalten +toggleMenu: Menü umschalten -darkMode: - other: Dunkler Modus +darkMode: Dunkler Modus list: page: one: "{{ .Count }} Seite" other: "{{ .Count }} Seiten" - - section: - other: Abschnitt - + section: Abschnitt subsection: one: Unterabschnitt other: Unterabschnitte article: - back: - other: Zurück - - tableOfContents: - other: Inhaltsverzeichnis - - relatedContent: - other: Verwandte Inhalte - - lastUpdatedOn: - other: Zuletzt aktualisiert am - + back: Zurück + tableOfContents: Inhaltsverzeichnis + relatedContent: Verwandte Inhalte + lastUpdatedOn: Zuletzt aktualisiert am readingTime: one: "{{ .Count }} Minute Lesezeit" other: "{{ .Count }} Minuten Lesezeit" notFound: - title: - other: Seite nicht gefunden - - subtitle: - other: Diese Seite existiert nicht + title: Seite nicht gefunden + subtitle: Diese Seite existiert nicht widget: archives: - title: - other: Archiv - - more: - other: Weitere - - tagCloud: - title: - other: Schlagwörter - - categoriesCloud: - title: - other: Kategorien + title: Archiv + more: Weitere search: - title: - other: Suche - - placeholder: - other: Etwas tippen... - - resultTitle: - other: "#PAGES_COUNT Seiten (#TIME_SECONDS Sekunden)" + title: Suche + placeholder: Etwas tippen... + resultTitle: "#PAGES_COUNT Seiten (#TIME_SECONDS Sekunden)" footer: - builtWith: - other: Erstellt mit {{ .Generator }} - - designedBy: - other: Theme {{ .Theme }} gestaltet von {{ .DesignedBy }} + builtWith: Erstellt mit {{ .Generator }} + designedBy: Theme {{ .Theme }} gestaltet von {{ .DesignedBy }} diff --git a/i18n/el.yaml b/i18n/el.yaml index 27a147d73..3f478bc2f 100644 --- a/i18n/el.yaml +++ b/i18n/el.yaml @@ -1,70 +1,39 @@ -toggleMenu: - other: Εναλλαγή Μενού +toggleMenu: Εναλλαγή Μενού -darkMode: - other: Σκοτεινό θέμα +darkMode: Σκοτεινό θέμα list: page: one: "{{ .Count }} σελιδα" other: "{{ .Count }} σελιδες" - - section: - other: Ενότητα - + section: Ενότητα subsection: one: Υποενότητα other: Υποενότητες article: - back: - other: Πισω - - tableOfContents: - other: Πινακας περιεχομενων - - relatedContent: - other: Σχετικο περιεχομενο - - lastUpdatedOn: - other: Τελευταια τροποποιηση στις - + back: Πισω + tableOfContents: Πινακας περιεχομενων + relatedContent: Σχετικο περιεχομενο + lastUpdatedOn: Τελευταια τροποποιηση στις readingTime: one: "{{ .Count }} λεπτό ανάγνωσης" - ### Seems that there's no need to add 's' even if it's plural in English other: "{{ .Count }} λεπτά ανάγνωσης" notFound: - title: - other: Δε βρέθηκε - subtitle: - other: Η σελίδα δε βρέθηκε. + title: Δε βρέθηκε + subtitle: Η σελίδα δε βρέθηκε. widget: archives: - title: - other: Αρχειο - - more: - other: Περισσότερα - - tagCloud: - title: - other: Tags + title: Αρχειο + more: Περισσότερα search: - title: - other: Αναζήτηση - - placeholder: - other: Πληκτρολογήστε κάτι... - - resultTitle: - other: "#PAGES_COUNT σελιδες (#TIME_SECONDS δευτερολεπτα)" + title: Αναζήτηση + placeholder: Πληκτρολογήστε κάτι... + resultTitle: "#PAGES_COUNT σελιδες (#TIME_SECONDS δευτερολεπτα)" footer: - builtWith: - other: Δημιουργήθηκε με τη χρήση {{ .Generator }} - - designedBy: - other: Το θέμα {{ .Theme }} σχεδιάστηκε από το {{ .DesignedBy }} + builtWith: Δημιουργήθηκε με τη χρήση {{ .Generator }} + designedBy: Το θέμα {{ .Theme }} σχεδιάστηκε από το {{ .DesignedBy }} diff --git a/i18n/en.yaml b/i18n/en.yaml index fb07328b9..38ba63c7e 100644 --- a/i18n/en.yaml +++ b/i18n/en.yaml @@ -1,73 +1,42 @@ -toggleMenu: - other: Toggle Menu +toggleMenu: Toggle Menu -darkMode: - other: Dark Mode +darkMode: Dark Mode list: page: one: "{{ .Count }} page" other: "{{ .Count }} pages" - - section: - other: Section - + section: Section subsection: one: Subsection other: Subsections article: - back: - other: Back - - tableOfContents: - other: Table of contents - - relatedContent: - other: Related content - - lastUpdatedOn: - other: Last updated on - + back: Back + tableOfContents: Table of contents + relatedContent: Related content + lastUpdatedOn: Last updated on readingTime: one: "{{ .Count }} minute read" other: "{{ .Count }} minute read" + codeblock: + copy: Copy + copied: Copied! notFound: - title: - other: Not Found - - subtitle: - other: This page does not exist + title: Not Found + subtitle: This page does not exist widget: archives: - title: - other: Archives - - more: - other: More - - tagCloud: - title: - other: Tags - categoriesCloud: - title: - other: Categories + title: Archives + more: More search: - title: - other: Search - - placeholder: - other: Type something... - - resultTitle: - other: "#PAGES_COUNT pages (#TIME_SECONDS seconds)" + title: Search + placeholder: Type something... + resultTitle: "#PAGES_COUNT pages (#TIME_SECONDS seconds)" footer: - builtWith: - other: Built with {{ .Generator }} - - designedBy: - other: Theme {{ .Theme }} designed by {{ .DesignedBy }} + builtWith: Built with {{ .Generator }} + designedBy: Theme {{ .Theme }} designed by {{ .DesignedBy }} diff --git a/i18n/es.yaml b/i18n/es.yaml index 6b4b3af09..248e3777b 100644 --- a/i18n/es.yaml +++ b/i18n/es.yaml @@ -1,73 +1,39 @@ -toggleMenu: - other: Ocultar menú +toggleMenu: Ocultar menú -darkMode: - other: Modo oscuro +darkMode: Modo oscuro list: page: one: "{{ .Count }} página" other: "{{ .Count }} páginas" - - section: - other: Sección - + section: Sección subsection: one: Subsección other: Subsecciones article: - back: - other: Volver - - tableOfContents: - other: Tabla de contenido - - relatedContent: - other: Contenidos relacionados - - lastUpdatedOn: - other: Última actualización - + back: Volver + tableOfContents: Tabla de contenido + relatedContent: Contenidos relacionados + lastUpdatedOn: Última actualización readingTime: one: "Tiempo de lectura {{ .Count }} minuto" other: "Tiempo de lectura {{ .Count }} minutos" notFound: - title: - other: No Encontrado - - subtitle: - other: Esta página no existe + title: No Encontrado + subtitle: Esta página no existe widget: archives: - title: - other: Archivo - - more: - other: Más - - tagCloud: - title: - other: Etiquetas - categoriesCloud: - title: - other: Categorías + title: Archivo + more: Más search: - title: - other: Búsqueda - - placeholder: - other: Escribe algo... - - resultTitle: - other: "#PAGES_COUNT páginas en (#TIME_SECONDS segundos)" + title: Búsqueda + placeholder: Escribe algo... + resultTitle: "#PAGES_COUNT páginas en (#TIME_SECONDS segundos)" footer: - builtWith: - other: Creado con {{ .Generator }} - - designedBy: - other: Tema {{ .Theme }} diseñado por {{ .DesignedBy }} + builtWith: Creado con {{ .Generator }} + designedBy: Tema {{ .Theme }} diseñado por {{ .DesignedBy }} diff --git a/i18n/fa.yaml b/i18n/fa.yaml index 365575784..bcefbe396 100644 --- a/i18n/fa.yaml +++ b/i18n/fa.yaml @@ -1,73 +1,39 @@ -toggleMenu: - other: منو +toggleMenu: منو -darkMode: - other: حالت شب +darkMode: حالت شب list: page: one: "{{ .Count }} صفحه" other: "{{ .Count }} صفحه" - - section: - other: بخش - + section: بخش subsection: one: زیربخش other: زیربخش article: - back: - other: قبلی - - tableOfContents: - other: فهرست - - relatedContent: - other: مطالب مرتبط - - lastUpdatedOn: - other: آخرین بروزرسانی در - + back: قبلی + tableOfContents: فهرست + relatedContent: مطالب مرتبط + lastUpdatedOn: آخرین بروزرسانی در readingTime: one: "مطالعه در {{ .Count }} دقیقه" other: "مطالعه در {{ .Count }} دقیقه" notFound: - title: - other: یافت نشد - - subtitle: - other: این صحه وجود ندارد + title: یافت نشد + subtitle: این صحه وجود ندارد widget: archives: - title: - other: آرشیو - - more: - other: بیشتر - - tagCloud: - title: - other: تگ ها - categoriesCloud: - title: - other: دسته بندی + title: آرشیو + more: بیشتر search: - title: - other: جستجو - - placeholder: - other: تایپ کنید ... - - resultTitle: - other: "#PAGES_COUNT صفحه (#TIME_SECONDS ثانیه)" + title: جستجو + placeholder: تایپ کنید ... + resultTitle: "#PAGES_COUNT صفحه (#TIME_SECONDS ثانیه)" footer: - builtWith: - other: قدرت گرفته از {{ .Generator }} - - designedBy: - other: قالب {{ .Theme }} ساخته شده توسط {{ .DesignedBy }} + builtWith: قدرت گرفته از {{ .Generator }} + designedBy: قالب {{ .Theme }} ساخته شده توسط {{ .DesignedBy }} diff --git a/i18n/fr.yaml b/i18n/fr.yaml index 4e6e1f87b..2bec05184 100644 --- a/i18n/fr.yaml +++ b/i18n/fr.yaml @@ -1,72 +1,45 @@ -toggleMenu: - other: Afficher le menu +toggleMenu: Afficher le menu -darkMode: - other: Mode sombre +darkMode: Mode sombre list: page: one: "{{ .Count }} page" other: "{{ .Count }} pages" - - section: - other: Section - + section: Section subsection: one: Sous-section other: Sous-sections article: - back: - other: Retour - - tableOfContents: - other: Table des matières - - relatedContent: - other: Contenus liés - - lastUpdatedOn: - other: Dernière mise à jour le - + back: Retour + tableOfContents: Table des matières + relatedContent: Contenus liés + lastUpdatedOn: Dernière mise à jour le readingTime: one: "{{ .Count }} minute de lecture" other: "{{ .Count }} minutes de lecture" notFound: - title: - other: Page non trouvée - subtitle: - other: Cette page n'existe pas. + title: Page non trouvée + subtitle: Cette page n'existe pas. widget: archives: - title: - other: Archives - - more: - other: Autres + title: Archives + more: Autres tagCloud: - title: - other: Mots clés + title: Mots clés + categoriesCloud: - title: - other: Catégories + title: Catégories search: - title: - other: Rechercher - - placeholder: - other: Cherchez un article, une publication, etc. - - resultTitle: - other: "#PAGES_COUNT pages (#TIME_SECONDS secondes)" + title: Rechercher + placeholder: Cherchez un article, une publication, etc. + resultTitle: "#PAGES_COUNT pages (#TIME_SECONDS secondes)" footer: - builtWith: - other: Généré avec {{ .Generator }} - - designedBy: - other: Thème {{ .Theme }} conçu par {{ .DesignedBy }} + builtWith: Généré avec {{ .Generator }} + designedBy: Thème {{ .Theme }} conçu par {{ .DesignedBy }} diff --git a/i18n/hu.yaml b/i18n/hu.yaml index 5e5af92eb..8baf956f1 100644 --- a/i18n/hu.yaml +++ b/i18n/hu.yaml @@ -1,73 +1,39 @@ -toggleMenu: - other: Menü Kapcsolása +toggleMenu: Menü Kapcsolása -darkMode: - other: Sötét Mód +darkMode: Sötét Mód list: page: one: "{{ .Count }} oldal" other: "{{ .Count }} oldalak" - - section: - other: Szekció - + section: 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 - + back: Vissza + tableOfContents: Tartalomjegyzék + relatedContent: Kapcsolódó tartalom + lastUpdatedOn: 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 + title: Nem található + subtitle: 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 + title: Archívum + more: Több search: - title: - other: Keresés - - placeholder: - other: Írj valamit... - - resultTitle: - other: "#PAGES_COUNT oldal (#TIME_SECONDS másodperc alatt)" + title: Keresés + placeholder: Írj valamit... + resultTitle: "#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 + builtWith: "{{ .Generator }} használatával készült" + designedBy: A {{ .Theme }} dizájnt {{ .DesignedBy }} tervezte diff --git a/i18n/id.yaml b/i18n/id.yaml index 8104351cb..1f10ee107 100644 --- a/i18n/id.yaml +++ b/i18n/id.yaml @@ -1,73 +1,39 @@ -toggleMenu: - other: Tampilkan Menu +toggleMenu: Tampilkan Menu -darkMode: - other: Mode Gelap +darkMode: Mode Gelap list: page: one: "{{ .Count }} halaman" other: "{{ .Count }} halaman" - - section: - other: Bagian - + section: Bagian subsection: one: Subbagian other: Subbagian article: - back: - other: Kembali - - tableOfContents: - other: Daftar Isi - - relatedContent: - other: Konten terkait - - lastUpdatedOn: - other: Terakhir diperbarui pada - + back: Kembali + tableOfContents: Daftar Isi + relatedContent: Konten terkait + lastUpdatedOn: Terakhir diperbarui pada readingTime: one: "Waktu Membaca: {{ .Count }} menit" other: "Waktu Membaca: {{ .Count }} menit" notFound: - title: - other: Tidak ditemukan - subtitle: - other: Halaman yang Anda akses tidak ditemukan. + title: Tidak ditemukan + subtitle: Halaman yang Anda akses tidak ditemukan. widget: archives: - title: - other: Arsip - - more: - other: Lebih - - tagCloud: - title: - other: Tag - - categoriesCloud: - title: - other: Kategori + title: Arsip + more: Lebih search: - title: - other: Cari - - placeholder: - other: Ketik sesuatu... - - resultTitle: - other: "#PAGES_COUNT halaman (#TIME_SECONDS detik)" + title: Cari + placeholder: Ketik sesuatu... + resultTitle: "#PAGES_COUNT halaman (#TIME_SECONDS detik)" footer: - builtWith: - other: Dibangun dengan {{ .Generator }} - - designedBy: - other: Tema {{ .Theme }} dirancang oleh {{ .DesignedBy }} + builtWith: Dibangun dengan {{ .Generator }} + designedBy: Tema {{ .Theme }} dirancang oleh {{ .DesignedBy }} diff --git a/i18n/it.yaml b/i18n/it.yaml index 0cbeeabd6..9c4a0aaeb 100644 --- a/i18n/it.yaml +++ b/i18n/it.yaml @@ -1,73 +1,39 @@ -toggleMenu: - other: Toggle Menu +toggleMenu: Toggle Menu -darkMode: - other: Dark Mode +darkMode: Dark Mode list: page: one: "{{ .Count }} pagina" other: "{{ .Count }} pagine" - - section: - other: Sezione - + section: Sezione subsection: one: Sottosezione other: Sottosezioni article: - back: - other: Indietro - - tableOfContents: - other: Indice - - relatedContent: - other: Contenuti correlati - - lastUpdatedOn: - other: Aggiornato il - + back: Indietro + tableOfContents: Indice + relatedContent: Contenuti correlati + lastUpdatedOn: Aggiornato il readingTime: one: "{{ .Count }} min per leggere" other: "{{ .Count }} min per leggere" notFound: - title: - other: Non trovato - subtitle: - other: Questa pagina non esiste. + title: Non trovato + subtitle: Questa pagina non esiste. widget: archives: - title: - other: Archivi - - more: - other: Di più - - tagCloud: - title: - other: Tags - - categoriesCloud: - title: - other: Categorie + title: Archivi + more: Di più search: - title: - other: Cerca - - placeholder: - other: Scrivi qualcosa... - - resultTitle: - other: "#PAGES_COUNT pagine (#TIME_SECONDS secondi)" + title: Cerca + placeholder: Scrivi qualcosa... + resultTitle: "#PAGES_COUNT pagine (#TIME_SECONDS secondi)" footer: - builtWith: - other: Realizzato con {{ .Generator }} - - designedBy: - other: Tema {{ .Theme }} realizzato da {{ .DesignedBy }} + builtWith: Realizzato con {{ .Generator }} + designedBy: Tema {{ .Theme }} realizzato da {{ .DesignedBy }} diff --git a/i18n/ja.yaml b/i18n/ja.yaml index 12352ee3e..677b5c870 100644 --- a/i18n/ja.yaml +++ b/i18n/ja.yaml @@ -1,70 +1,33 @@ -toggleMenu: - other: メニューを開く・閉じる +toggleMenu: メニューを開く・閉じる -darkMode: - other: ダークモード +darkMode: ダークモード list: - page: - other: "{{ .Count }} ページ目" - - section: - other: セクション - - subsection: - other: サブセクション + page: "{{ .Count }} ページ目" + section: セクション + subsection: サブセクション article: - back: - other: 前のページ - - tableOfContents: - other: 目次 - - relatedContent: - other: 関連するコンテンツ - - lastUpdatedOn: - other: 最終更新 - - readingTime: - other: "読了時間: {{ .Count }}分" + back: 前のページ + tableOfContents: 目次 + relatedContent: 関連するコンテンツ + lastUpdatedOn: 最終更新 + readingTime: "読了時間: {{ .Count }}分" notFound: - title: - other: 404 Not Found - subtitle: - other: 指定されたページは存在しません。 + title: 404 Not Found + subtitle: 指定されたページは存在しません。 widget: archives: - title: - other: アーカイブ - - more: - other: さらに見る - - tagCloud: - title: - other: タグ - - categoriesCloud: - title: - other: カテゴリ + title: アーカイブ + more: さらに見る search: - title: - other: 検索 - - placeholder: - other: 入力... - - resultTitle: - other: "#PAGES_COUNT 件 (#TIME_SECONDS 秒)" + title: 検索 + placeholder: 入力... + resultTitle: "#PAGES_COUNT 件 (#TIME_SECONDS 秒)" footer: - builtWith: - other: "{{ .Generator }} で構築されています。" - - designedBy: - other: テーマ {{ .Theme }} は {{ .DesignedBy }} によって設計されています。 + builtWith: "{{ .Generator }} で構築されています。" + designedBy: テーマ {{ .Theme }} は {{ .DesignedBy }} によって設計されています。 diff --git a/i18n/ko.yaml b/i18n/ko.yaml index 11cdc4a2f..da8a88fc1 100644 --- a/i18n/ko.yaml +++ b/i18n/ko.yaml @@ -1,72 +1,39 @@ -toggleMenu: - other: 메뉴 여닫기 +toggleMenu: 메뉴 여닫기 -darkMode: - other: 다크 모드 +darkMode: 다크 모드 list: page: one: "{{ .Count }} 페이지" other: "{{ .Count }} 페이지" - - section: - other: 섹션 - + section: 섹션 subsection: one: 서브섹션 other: 서브섹션 article: - back: - other: 뒤로가기 - - tableOfContents: - other: 목차 - - relatedContent: - other: 관련 글 - - lastUpdatedOn: - other: "마지막 수정: " - + back: 뒤로가기 + tableOfContents: 목차 + relatedContent: 관련 글 + lastUpdatedOn: "마지막 수정: " readingTime: one: "{{ .Count }} 분 정도" other: "{{ .Count }} 분 정도" notFound: - title: - other: 찾을 수 없음 - - subtitle: - other: 페이지를 찾을 수 없습니다. + title: 찾을 수 없음 + subtitle: 페이지를 찾을 수 없습니다. widget: archives: - title: - other: 보관함 - more: - other: 더보기 - - categoriesCloud: - title: - other: 카테고리 - - tagCloud: - title: - other: 태그 + title: 보관함 + more: 더보기 search: - title: - other: 검색 - - placeholder: - other: 검색어를 입력하세요... - - resultTitle: - other: "#PAGES_COUNT 페이지 (#TIME_SECONDS 초)" + title: 검색 + placeholder: 검색어를 입력하세요... + resultTitle: "#PAGES_COUNT 페이지 (#TIME_SECONDS 초)" footer: - builtWith: - other: "{{ .Generator }}로 만듦" - designedBy: - other: "{{ .DesignedBy }}의 {{ .Theme }} 테마 사용 중" + builtWith: "{{ .Generator }}로 만듦" + designedBy: "{{ .DesignedBy }}의 {{ .Theme }} 테마 사용 중" diff --git a/i18n/nl.yaml b/i18n/nl.yaml index b5bf264dc..7d42bd5cb 100644 --- a/i18n/nl.yaml +++ b/i18n/nl.yaml @@ -1,59 +1,35 @@ -toggleMenu: - other: Open Menu +toggleMenu: Open Menu -darkMode: - other: Donkere modus +darkMode: Donkere modus list: page: one: "{{ .Count }} pagina" other: "{{ .Count }} pagina's" - - section: - other: Sectie - + section: Sectie subsection: one: Subsectie other: Subsecties article: - relatedContent: - other: Gerelateerde inhoud - lastUpdatedOn: - other: Laatst bijgewerkt op - readingTime: - other: "{{ .Count }} leestijd" + relatedContent: Gerelateerde inhoud + lastUpdatedOn: Laatst bijgewerkt op + readingTime: "{{ .Count }} leestijd" notFound: - title: - other: Niet gevonden - subtitle: - other: Deze pagina bestaat niet. + title: Niet gevonden + subtitle: Deze pagina bestaat niet. widget: archives: - title: - other: Archief - more: - other: Meer - tagCloud: - title: - other: Tags - - categoriesCloud: - title: - other: Categorie + title: Archief + more: Meer search: - title: - other: Zoeken - placeholder: - other: Typ iets - resultTitle: - other: "#PAGES_COUNT pagina's (#TIME_SECONDS seconden)" + title: Zoeken + placeholder: Typ iets + resultTitle: "#PAGES_COUNT pagina's (#TIME_SECONDS seconden)" footer: - builtWith: - other: Gemaakt met {{ .Generator }} - designedBy: - other: Theme {{ .Theme }} ontworpen door {{ .DesignedBy }} + builtWith: Gemaakt met {{ .Generator }} + designedBy: Theme {{ .Theme }} ontworpen door {{ .DesignedBy }} diff --git a/i18n/pl.yaml b/i18n/pl.yaml index 9f2982fcd..ce508b71d 100644 --- a/i18n/pl.yaml +++ b/i18n/pl.yaml @@ -1,8 +1,6 @@ -toggleMenu: - other: Przełącz Menu +toggleMenu: Przełącz Menu -darkMode: - other: Tryb ciemny +darkMode: Tryb ciemny list: page: @@ -10,10 +8,7 @@ list: few: "{{ .Count }} strony" many: "{{ .Count }} stron" other: "{{ .Count }} stron" - - section: - other: Sekcja - + section: Sekcja subsection: one: Podsekcja few: Podsekcje @@ -21,18 +16,10 @@ list: other: Podsekcji article: - back: - other: Wróć - - tableOfContents: - other: Spis treści - - relatedContent: - other: Powiązane artykuły - - lastUpdatedOn: - other: Ostatnio zaktualizowany - + back: Wróć + tableOfContents: Spis treści + relatedContent: Powiązane artykuły + lastUpdatedOn: Ostatnio zaktualizowany readingTime: one: "Przeczytasz w {{ .Count }} minutę" few: "Przeczytasz w {{ .Count }} minuty" @@ -40,33 +27,18 @@ article: other: "Przeczytasz w {{ .Count }} minut" notFound: - title: - other: Nie znaleziono - subtitle: - other: Ta strona nie istnieje + title: Nie znaleziono + subtitle: Ta strona nie istnieje widget: archives: - title: - other: Archiwum - - more: - other: Więcej - - tagCloud: - title: - other: Tagi - - categoriesCloud: - title: - other: Kategorie + title: Archiwum + more: Więcej search: - title: - other: Szukaj + title: Szukaj - placeholder: - other: Wpisz coś... + placeholder: Wpisz coś... resultTitle: one: "#PAGES_COUNT strona (#TIME_SECONDS sekund)" @@ -75,8 +47,5 @@ search: other: "#PAGES_COUNT stron (#TIME_SECONDS sekund)" footer: - builtWith: - other: Zbudowano z {{ .Generator }} - - designedBy: - other: Motyw {{ .Theme }} zaprojektowany przez {{ .DesignedBy }} + builtWith: Zbudowano z {{ .Generator }} + designedBy: Motyw {{ .Theme }} zaprojektowany przez {{ .DesignedBy }} diff --git a/i18n/pt-br.yaml b/i18n/pt-br.yaml index 2784f3d90..df63aae87 100644 --- a/i18n/pt-br.yaml +++ b/i18n/pt-br.yaml @@ -1,67 +1,39 @@ -toggleMenu: - other: Alternar Menu +toggleMenu: Alternar Menu -darkMode: - other: Modo Escuro +darkMode: Modo Escuro list: page: one: "{{ .Count }} página" other: "{{ .Count }} páginas" - - section: - other: Seção - + section: Seção subsection: one: Subseção other: Subseções article: - back: - other: Voltar - - tableOfContents: - other: Índice - - relatedContent: - other: Conteúdo relacionado - - lastUpdatedOn: - other: Última atualização em - + back: Voltar + tableOfContents: Índice + relatedContent: Conteúdo relacionado + lastUpdatedOn: Última atualização em readingTime: one: "{{ .Count }} minuto de leitura" other: "{{ .Count }} minutos de leitura" notFound: - title: - other: Não Encontrado - subtitle: - other: Esta página não existe. + title: Não Encontrado + subtitle: Esta página não existe. widget: archives: - title: - other: Arquivos - more: - other: Mais - tagCloud: - title: - other: Tags - categoriesCloud: - title: - other: Categorias + title: Arquivos + more: Mais search: - title: - other: Busca - placeholder: - other: Digite algo... - resultTitle: - other: "#PAGES_COUNT páginas (#TIME_SECONDS segundos)" + title: Busca + placeholder: Digite algo... + resultTitle: "#PAGES_COUNT páginas (#TIME_SECONDS segundos)" footer: - builtWith: - other: Criado com {{ .Generator }} - designedBy: - other: Tema {{ .Theme }} desenvolvido por {{ .DesignedBy }} + builtWith: Criado com {{ .Generator }} + designedBy: Tema {{ .Theme }} desenvolvido por {{ .DesignedBy }} diff --git a/i18n/pt-pt.yaml b/i18n/pt-pt.yaml index f524969c6..2b2407509 100644 --- a/i18n/pt-pt.yaml +++ b/i18n/pt-pt.yaml @@ -45,12 +45,6 @@ widget: other: Arquivos more: other: Mais - tagCloud: - title: - other: Tags - categoriesCloud: - title: - other: Categorias search: title: diff --git a/i18n/ru.yaml b/i18n/ru.yaml index b1f1e5105..59997a7c2 100644 --- a/i18n/ru.yaml +++ b/i18n/ru.yaml @@ -1,8 +1,6 @@ -toggleMenu: - other: Показать/скрыть меню +toggleMenu: Показать/скрыть меню -darkMode: - other: Тёмный режим +darkMode: Тёмный режим list: page: @@ -10,10 +8,7 @@ list: few: "{{ .Count }} страницы" many: "{{ .Count }} страниц" other: "{{ .Count }} страниц" - - section: - other: Раздел - + section: Раздел subsection: one: Подраздел few: Подразделы @@ -21,43 +16,30 @@ list: other: Подразделы article: - back: - other: Назад - relatedContent: - other: Также рекомендуем - lastUpdatedOn: - other: Обновлено - tableOfContents: - other: Содержание - readingTime: - other: "Время чтения: {{ .Count }} мин." + back: Назад + relatedContent: Также рекомендуем + lastUpdatedOn: Обновлено + tableOfContents: Содержание + readingTime: "Время чтения: {{ .Count }} мин." notFound: - title: - other: Не найдено - subtitle: - other: Запрашиваемая страница не существует + title: Не найдено + subtitle: Запрашиваемая страница не существует widget: archives: - title: - other: Архивы - more: - other: Ещё + title: Архивы + more: Ещё tagCloud: - title: - other: Теги + title: Теги + categoriesCloud: + title: Категории search: - title: - other: Поиск - placeholder: - other: Введите что-нибудь... - resultTitle: - other: "Найдено #PAGES_COUNT страниц (за #TIME_SECONDS с.)" + title: Поиск + placeholder: Введите что-нибудь... + resultTitle: "Найдено #PAGES_COUNT страниц (за #TIME_SECONDS с.)" footer: - builtWith: - other: Создано при помощи {{ .Generator }} - designedBy: - other: Тема {{ .Theme }}, дизайн {{ .DesignedBy }} + builtWith: Создано при помощи {{ .Generator }} + designedBy: Тема {{ .Theme }}, дизайн {{ .DesignedBy }} diff --git a/i18n/th.yaml b/i18n/th.yaml index 9982c06ad..e64ab2e08 100644 --- a/i18n/th.yaml +++ b/i18n/th.yaml @@ -1,70 +1,39 @@ -toggleMenu: - other: สลับเมนู +toggleMenu: สลับเมนู -darkMode: - other: ธีมมืด +darkMode: ธีมมืด list: page: one: "{{ .Count }} หน้า" other: "{{ .Count }} หน้า" - - section: - other: หมวดหมู่ - + section: หมวดหมู่ subsection: one: หมวดหมู่ย่อย other: หมวดหมู่ย่อยอื่นๆ article: - back: - other: กลับไป - - tableOfContents: - other: สารบัญ - - relatedContent: - other: เนื้อหาคล้ายคลึงกัน - - lastUpdatedOn: - other: อัปเดตล่าสุดเมื่อ - + back: กลับไป + tableOfContents: สารบัญ + relatedContent: เนื้อหาคล้ายคลึงกัน + lastUpdatedOn: อัปเดตล่าสุดเมื่อ readingTime: one: "น่าจะใช้เวลา {{ .Count }} นาทีในการอ่าน" other: "น่าจะใช้เวลา {{ .Count }} นาทีในการอ่าน" notFound: - title: - other: ไม่พบหัวข้อ - - subtitle: - other: ไม่พบหน้านี้ในระบบ + title: ไม่พบหัวข้อ + subtitle: ไม่พบหน้านี้ในระบบ widget: archives: - title: - other: เนื้อหาที่เก็บถาวรแล้ว - - more: - other: อื่นๆ นอกจากนี้ - - tagCloud: - title: - other: แท็ก + title: เนื้อหาที่เก็บถาวรแล้ว + more: อื่นๆ นอกจากนี้ search: - title: - other: ค้นหา - - placeholder: - other: พิมพ์เพื่อค้นหา ... - - resultTitle: - other: "#PAGES_COUNT pages (#TIME_SECONDS seconds)" + title: ค้นหา + placeholder: พิมพ์เพื่อค้นหา ... + resultTitle: "#PAGES_COUNT pages (#TIME_SECONDS seconds)" footer: - builtWith: - other: ถูกสร้างด้วย {{ .Generator }} - - designedBy: - other: ธีม {{ .Theme }} ออกแบบโดย {{ .DesignedBy }} + builtWith: ถูกสร้างด้วย {{ .Generator }} + designedBy: ธีม {{ .Theme }} ออกแบบโดย {{ .DesignedBy }} diff --git a/i18n/tr.yaml b/i18n/tr.yaml index 2dbb9d525..2d4d15791 100644 --- a/i18n/tr.yaml +++ b/i18n/tr.yaml @@ -1,53 +1,34 @@ -toggleMenu: - other: Menüyü Gizle +toggleMenu: Menüyü Gizle -darkMode: - other: Koyu Mod +darkMode: Koyu Mod list: page: one: "{{ .Count }} makale" other: "{{ .Count }} makale" - - section: - other: Bölüm - + section: Bölüm subsection: one: Alt bölüm other: Alt bölümler article: - relatedContent: - other: Alakalı içerikler - lastUpdatedOn: - other: Son güncelleme + relatedContent: Alakalı içerikler + lastUpdatedOn: Son güncelleme notFound: - title: - other: Bulunamadı - subtitle: - other: Aradığınız sayfa mevcut değil. + title: Bulunamadı + subtitle: Aradığınız sayfa mevcut değil. widget: archives: - title: - other: Arşiv - more: - other: Daha fazla - tagCloud: - title: - other: Etiketler + title: Arşiv + more: Daha fazla search: - title: - other: Arama - placeholder: - other: Birşeyler yazın... - resultTitle: - other: "#PAGES_COUNT sayfa (#TIME_SECONDS saniye)" + title: Arama + placeholder: Birşeyler yazın... + resultTitle: "#PAGES_COUNT sayfa (#TIME_SECONDS saniye)" footer: - builtWith: - other: "{{ .Generator }} ile oluşturuldu." - designedBy: - other: "{{ .Theme }} teması {{ .DesignedBy }} tarafından tasarlandı" + builtWith: "{{ .Generator }} ile oluşturuldu." + designedBy: "{{ .Theme }} teması {{ .DesignedBy }} tarafından tasarlandı" diff --git a/i18n/uk.yaml b/i18n/uk.yaml index 3bd4f7161..ba36891ba 100644 --- a/i18n/uk.yaml +++ b/i18n/uk.yaml @@ -1,71 +1,44 @@ -toggleMenu: - other: Показати меню +toggleMenu: Показати меню -darkMode: - other: Темна тема +darkMode: Темна тема list: page: one: "{{ .Count }} сторінка" few: "{{ .Count }} сторінки" other: "{{ .Count }} сторінок" - - section: - other: Секція - + section: Секція subsection: one: Підсекція other: Підсекції article: - back: - other: Назад - - tableOfContents: - other: Зміст - - relatedContent: - other: Схожі матеріали - - lastUpdatedOn: - other: Востаннє оновлено - + back: Назад + tableOfContents: Зміст + relatedContent: Схожі матеріали + lastUpdatedOn: Востаннє оновлено readingTime: one: "Час читання: {{ .Count }} хв" other: "Час читання: {{ .Count }} хв" notFound: - title: - other: Не знайдено - - subtitle: - other: Ця сторінка не існує + title: Не знайдено + subtitle: Ця сторінка не існує widget: archives: - title: - other: Архіви - - more: - other: Більше - + title: Архіви + more: Більше tagCloud: - title: - other: Теґи + title: Теґи + categoriesCloud: + title: Категорії search: - title: - other: Пошук - - placeholder: - other: Напишіть що-небудь... - - resultTitle: - other: "#PAGES_COUNT сторінок (#TIME_SECONDS секунд)" + title: Пошук + placeholder: Напишіть що-небудь... + resultTitle: "#PAGES_COUNT сторінок (#TIME_SECONDS секунд)" footer: - builtWith: - other: Створено з {{ .Generator }} - - designedBy: - other: Тема {{ .Theme }}, дизайн {{ .DesignedBy }} + builtWith: Створено з {{ .Generator }} + designedBy: Тема {{ .Theme }}, дизайн {{ .DesignedBy }} diff --git a/i18n/vi.yaml b/i18n/vi.yaml index 13dc624a5..b1605b918 100644 --- a/i18n/vi.yaml +++ b/i18n/vi.yaml @@ -48,14 +48,6 @@ widget: more: other: Còn nữa - tagCloud: - title: - other: Nhãn dán - - categoriesCloud: - title: - other: Chuỗi bài - search: title: other: Tìm kiếm diff --git a/i18n/zh-cn.yaml b/i18n/zh-cn.yaml index da39c8fd7..ac42d8f8e 100644 --- a/i18n/zh-cn.yaml +++ b/i18n/zh-cn.yaml @@ -1,67 +1,33 @@ -toggleMenu: - other: 切换菜单 +toggleMenu: 切换菜单 -darkMode: - other: 暗色模式 +darkMode: 暗色模式 list: page: "{{ .Count }} 个页面" - section: 章节 - subsection: 子章节 article: - back: - other: 返回 - - tableOfContents: - other: 目录 - - relatedContent: - other: 相关文章 - - lastUpdatedOn: - other: 最后更新于 - - readingTime: - other: "阅读时长: {{ .Count }} 分钟" + back: 返回 + tableOfContents: 目录 + relatedContent: 相关文章 + lastUpdatedOn: 最后更新于 + readingTime: "阅读时长: {{ .Count }} 分钟" notFound: - title: - other: 404 错误 - subtitle: - other: 页面不存在 + title: 404 错误 + subtitle: 页面不存在 widget: archives: - title: - other: 归档 - - more: - other: 更多 - - tagCloud: - title: - other: 标签云 - - categoriesCloud: - title: - other: 分类 + title: 归档 + more: 更多 search: - title: - other: 搜索 - - placeholder: - other: 输入关键词... - - resultTitle: - other: "#PAGES_COUNT 个结果 (用时 #TIME_SECONDS 秒)" + title: 搜索 + placeholder: 输入关键词... + resultTitle: "#PAGES_COUNT 个结果 (用时 #TIME_SECONDS 秒)" footer: - builtWith: - other: 使用 {{ .Generator }} 构建 - - designedBy: - other: 主题 {{ .Theme }} 由 {{ .DesignedBy }} 设计 + builtWith: 使用 {{ .Generator }} 构建 + designedBy: 主题 {{ .Theme }} 由 {{ .DesignedBy }} 设计 diff --git a/i18n/zh-hk.yaml b/i18n/zh-hk.yaml index 9e3c246b1..97f747648 100644 --- a/i18n/zh-hk.yaml +++ b/i18n/zh-hk.yaml @@ -1,73 +1,39 @@ -toggleMenu: - other: 切換選單 +toggleMenu: 切換選單 -darkMode: - other: 深色模式 +darkMode: 深色模式 list: page: one: "第 {{ .Count }} 頁" other: "第 {{ .Count }} 頁" - - section: - other: Section - + section: Section subsection: one: Subsection other: Subsections article: - back: - other: 返回 - - tableOfContents: - other: 目錄 - - relatedContent: - other: 相關內容 - - lastUpdatedOn: - other: 上次改過於 - + back: 返回 + tableOfContents: 目錄 + relatedContent: 相關內容 + lastUpdatedOn: 上次改過於 readingTime: one: "需要 {{ .Count }} 分鐘閱讀" other: "需要 {{ .Count }} 分鐘閱讀" notFound: - title: - other: Not Found - - subtitle: - other: 頁面不存在 + title: Not Found + subtitle: 頁面不存在 widget: archives: - title: - other: Archives - - more: - other: 更多 - - tagCloud: - title: - other: Tags - categoriesCloud: - title: - other: Categories + title: Archives + more: 更多 search: - title: - other: 搜尋 - - placeholder: - other: Type 關鍵字... - - resultTitle: - other: "#PAGES_COUNT pages (#TIME_SECONDS seconds)" + title: 搜尋 + placeholder: Type 關鍵字... + resultTitle: "#PAGES_COUNT pages (#TIME_SECONDS seconds)" footer: - builtWith: - other: Built with {{ .Generator }} - - designedBy: - other: 主題 {{ .Theme }} 由 {{ .DesignedBy }} 設計 + builtWith: Built with {{ .Generator }} + designedBy: 主題 {{ .Theme }} 由 {{ .DesignedBy }} 設計 diff --git a/i18n/zh-tw.yaml b/i18n/zh-tw.yaml index 4b71572e5..674734ff7 100644 --- a/i18n/zh-tw.yaml +++ b/i18n/zh-tw.yaml @@ -1,8 +1,6 @@ -toggleMenu: - other: 切換選單 +toggleMenu: 切換選單 -darkMode: - other: 夜晚模式 +darkMode: 夜晚模式 list: page: @@ -17,57 +15,26 @@ list: other: 小節 article: - back: - other: 返回 - - tableOfContents: - other: 目錄 - - relatedContent: - other: 相關文章 - - lastUpdatedOn: - other: 最後更新 - - readingTime: - one: "閱讀時間: {{ .Count }} 分鐘" - other: "閱讀時間: {{ .Count }} 分鐘" + back: 返回 + tableOfContents: 目錄 + relatedContent: 相關文章 + lastUpdatedOn: 最後更新 + readingTime: "閱讀時間: {{ .Count }} 分鐘" notFound: - title: - other: 404 錯誤 - - subtitle: - other: 頁面不存在 + title: 404 錯誤 + subtitle: 頁面不存在 widget: archives: - title: - other: 紀錄 - - more: - other: 更多 - - tagCloud: - title: - other: 標籤雲 - categoriesCloud: - title: - other: 分類 + title: 紀錄 + more: 更多 search: - title: - other: 搜尋 - - placeholder: - other: 輸入關鍵字... - - resultTitle: - other: "#PAGES_COUNT 個結果 (用時 #TIME_SECONDS 秒)" + title: 搜尋 + placeholder: 輸入關鍵字... + resultTitle: "#PAGES_COUNT 個結果 (用時 #TIME_SECONDS 秒)" footer: - builtWith: - other: 使用 {{ .Generator }} 建立 - - designedBy: - other: 主題 {{ .Theme }} 由 {{ .DesignedBy }} 設計 + builtWith: 使用 {{ .Generator }} 建立 + designedBy: 主題 {{ .Theme }} 由 {{ .DesignedBy }} 設計 diff --git a/layouts/_default/_markup/render-codeblock.html b/layouts/_default/_markup/render-codeblock.html new file mode 100644 index 000000000..f9f077e43 --- /dev/null +++ b/layouts/_default/_markup/render-codeblock.html @@ -0,0 +1,20 @@ +{{- $class := .Attributes.class | default "" -}} +{{- $lang := .Attributes.lang | default .Type -}} +
+
+ {{ $lang }} + +
+ + {{- if transform.CanHighlight $lang -}} +
{{- highlight .Inner $lang .Options -}}
+ {{- else -}} +
{{- .Inner -}}
+ {{- end -}} +
diff --git a/layouts/_default/_markup/render-image.html b/layouts/_default/_markup/render-image.html index 0ed55841a..642e095d3 100644 --- a/layouts/_default/_markup/render-image.html +++ b/layouts/_default/_markup/render-image.html @@ -3,24 +3,35 @@ {{- $alt := .PlainText | safeHTML -}} {{- $Width := 0 -}} {{- $Height := 0 -}} -{{- $Srcset := "" -}} - -{{/* SVG and external images won't work with gallery layout, because their width and height attributes are unknown */}} +{{- $Srcset := slice -}} +{{- $imageProcessing := .Page.Site.Params.imageProcessing.content.enabled -}} +{{- $allowedTypes := .Page.Site.Params.ImageProcessing.AllowedTypes -}} +{{- $resizableTypes := .Page.Site.Params.ImageProcessing.ResizableTypes -}} {{- $galleryImage := false -}} {{- if $image -}} - {{- $notSVG := ne (path.Ext .Destination) ".svg" -}} + {{- $type := $image.MediaType.SubType -}} + {{- $allowed := in $allowedTypes $type -}} + {{- $resizable := in $resizableTypes $type -}} + {{- $imageProcessing := and $imageProcessing $resizable -}} {{- $Permalink = $image.RelPermalink -}} - {{- if $notSVG -}} + {{- if $allowed -}} {{- $Width = $image.Width -}} {{- $Height = $image.Height -}} {{- $galleryImage = true -}} - {{- if (default true .Page.Site.Params.imageProcessing.content.enabled) -}} - {{- $small := $image.Resize `480x` -}} - {{- $big := $image.Resize `1024x` -}} - {{- $Srcset = printf `%s 480w, %s 1024w` $small.RelPermalink $big.RelPermalink -}} + {{- if $imageProcessing -}} + {{- $keys := slice "small" "big" -}} + {{- range $keys -}} + {{- with (index $.Page.Site.Params.ImageProcessing.Content .) -}} + {{- if gt $Width .Threshold -}} + {{- $resized := $image.Resize (printf "%dx" .Width) -}} + {{- $Srcset = $Srcset | append (printf `%s %dw` $resized.RelPermalink .Width) -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- $Srcset = $Srcset | append (printf `%s %dw` $Permalink $Width) -}} {{- end -}} {{- end -}} {{- end -}} @@ -28,7 +39,7 @@ {{ . }} \ No newline at end of file +> diff --git a/layouts/_default/archives.html b/layouts/_default/archives.html index 5d5243c26..71ce866c9 100644 --- a/layouts/_default/archives.html +++ b/layouts/_default/archives.html @@ -1,9 +1,14 @@ -{{ define "body-class" }}template-archives{{ end }} +{{ define "body-class" }}template-archives template-search{{ end }} +{{ define "head" }} + {{- with .OutputFormats.Get "json" -}} + + {{- end -}} +{{ end }} {{ define "main" }} + {{- $taxonomy := $.Site.GetPage "taxonomyTerm" "categories" -}} + {{- $terms := $taxonomy.Pages -}} + {{ if $terms }}
- {{- $taxonomy := $.Site.GetPage "taxonomyTerm" "categories" -}} - {{- $terms := $taxonomy.Pages -}} - {{ if $terms }}

{{ $taxonomy.Title }}

@@ -12,14 +17,25 @@

{{ $taxonomy.Title }}

{{ end }}
- {{ end }}
+ {{ end }} - {{ $pages := where .Site.RegularPages "Type" "in" .Site.Params.mainSections }} - {{ $notHidden := where .Site.RegularPages "Params.hidden" "!=" true }} - {{ $filtered := ($pages | intersect $notHidden) }} +
+

+ + +

+ + +
- {{ range $filtered.GroupByDate "2006" }} +

+ + {{ $pages := where .Site.RegularPages "Type" "in" .Site.Params.mainSections }} + + {{ range $pages.GroupByDate "2006" }} {{ $id := lower (replace .Key " " "-") }}

{{ .Key }}

@@ -32,4 +48,16 @@

+ window.searchResultTitleTemplate = "{{ T `search.resultTitle` }}" + + + {{- $opts := dict "minify" hugo.IsProduction -}} + {{- $archivesScript := resources.Get "ts/archives.ts" | js.Build $opts -}} + {{ end }} + +{{ define "right-sidebar" }} + {{ partial "sidebar/right.html" (dict "Context" . "Scope" "homepage") }} +{{ end }} \ No newline at end of file diff --git a/layouts/_default/archives.json b/layouts/_default/archives.json new file mode 100644 index 000000000..48b4f5259 --- /dev/null +++ b/layouts/_default/archives.json @@ -0,0 +1,13 @@ +{{- $pages := where .Site.RegularPages "Type" "in" .Site.Params.mainSections -}} +{{- $result := slice -}} + +{{- range $pages -}} + {{- $data := dict + "title" .Title + "content" (.Plain) + "id" .File.UniqueID + -}} + {{- $result = $result | append $data -}} +{{- end -}} + +{{ jsonify $result }} \ No newline at end of file diff --git a/layouts/_default/list.html b/layouts/_default/list.html index 9bc618d9a..a8a2620bb 100644 --- a/layouts/_default/list.html +++ b/layouts/_default/list.html @@ -11,7 +11,7 @@

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

-

{{ .Title }}

+

{{ default (strings.FirstUpper .Type) .Title }}

{{ with .Params.description }}

{{ . }}

{{ end }} @@ -25,7 +25,7 @@

{{ . }}

{{- $Width := $image.resource.Width -}} {{- $Height := $image.resource.Height -}} - {{- if (default true .Page.Site.Params.imageProcessing.cover.enabled) -}} + {{- if .Page.Site.Params.imageProcessing.cover.enabled -}} {{- $thumbnail := $image.resource.Fill "120x120" -}} {{- $Permalink = $thumbnail.RelPermalink -}} {{- $Width = $thumbnail.Width -}} diff --git a/layouts/_default/rss.xml b/layouts/_default/rss.xml index 3d2e59208..99b8be023 100644 --- a/layouts/_default/rss.xml +++ b/layouts/_default/rss.xml @@ -6,7 +6,6 @@ {{- else -}} {{- $pages = $pctx.Pages -}} {{- end -}} -{{- $pages := where $pages "Params.hidden" "!=" true -}} {{- $limit := .Site.Config.Services.RSS.Limit -}} {{- if ge $limit 1 -}} {{- $pages = $pages | first $limit -}} diff --git a/layouts/index.html b/layouts/index.html index 0cd0b88ce..5c1eaa529 100644 --- a/layouts/index.html +++ b/layouts/index.html @@ -1,9 +1,6 @@ {{ define "main" }} {{ $pages := where .Site.RegularPages "Type" "in" .Site.Params.mainSections }} - {{ $notHidden := where .Site.RegularPages "Params.hidden" "!=" true }} - {{ $filtered := ($pages | intersect $notHidden) }} - {{ $pag := .Paginate ($filtered) }} - + {{ $pag := .Paginate ($pages) }}
{{ range $index, $element := $pag.Pages }} {{ partial "article-list/default" . }} diff --git a/layouts/page/search.html b/layouts/page/search.html deleted file mode 100644 index fbfb74d43..000000000 --- a/layouts/page/search.html +++ /dev/null @@ -1,33 +0,0 @@ -{{ define "body-class" }}template-search{{ end }} -{{ define "head" }} - {{- with .OutputFormats.Get "json" -}} - - {{- end -}} -{{ end }} -{{ define "main" }} -
-

- - -

- - -
- -
-

-
-
- - - -{{- $opts := dict "minify" hugo.IsProduction "JSXFactory" "createElement" -}} -{{- $searchScript := resources.Get "ts/search.tsx" | js.Build $opts -}} - - -{{ partialCached "footer/footer" . }} -{{ end }} \ No newline at end of file diff --git a/layouts/page/search.json b/layouts/page/search.json deleted file mode 100644 index 5d4e62789..000000000 --- a/layouts/page/search.json +++ /dev/null @@ -1,26 +0,0 @@ -{{- $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 $image.exists -}} - {{- $imagePermalink := "" -}} - {{- if and $image.resource (default true .Page.Site.Params.imageProcessing.cover.enabled) -}} - {{- $thumbnail := $image.resource.Fill "120x120" -}} - {{- $imagePermalink = (absURL $thumbnail.Permalink) -}} - {{- else -}} - {{- $imagePermalink = $image.permalink -}} - {{- end -}} - - {{- $data = merge $data (dict "image" (absURL $imagePermalink)) -}} - {{- end -}} - - {{- $result = $result | append $data -}} -{{- end -}} - -{{ jsonify $result }} \ No newline at end of file diff --git a/layouts/partials/article-list/compact.html b/layouts/partials/article-list/compact.html index 376512a16..4b3924cd4 100644 --- a/layouts/partials/article-list/compact.html +++ b/layouts/partials/article-list/compact.html @@ -1,4 +1,4 @@ -
+

@@ -19,7 +19,7 @@

{{- $Width := $image.resource.Width -}} {{- $Height := $image.resource.Height -}} - {{- if (default true .Page.Site.Params.imageProcessing.cover.enabled) -}} + {{- if .Page.Site.Params.imageProcessing.cover.enabled -}} {{- $thumbnail := $image.resource.Fill "120x120" -}} {{- $Permalink = $thumbnail.RelPermalink -}} {{- $Width = $thumbnail.Width -}} diff --git a/layouts/partials/article/components/header.html b/layouts/partials/article/components/header.html index 7582ec25b..8f29d1c22 100644 --- a/layouts/partials/article/components/header.html +++ b/layouts/partials/article/components/header.html @@ -7,19 +7,23 @@ {{- $Permalink := $image.resource.RelPermalink -}} {{- $Width := $image.resource.Width -}} {{- $Height := $image.resource.Height -}} - {{- $Srcset := "" -}} + {{- $Srcset := slice -}} - {{- if (default true .Page.Site.Params.imageProcessing.cover.enabled) -}} - {{- $thumbnail := $image.resource.Resize "800x" -}} - {{- $thumbnailRetina := $image.resource.Resize "1600x" -}} - {{- $Srcset = printf "%s 800w, %s 1600w" $thumbnail.RelPermalink $thumbnailRetina.RelPermalink -}} - {{- $Permalink = $thumbnail.RelPermalink -}} - {{- $Width = $thumbnail.Width -}} - {{- $Height = $thumbnail.Height -}} + {{- if .Page.Site.Params.ImageProcessing.Cover.Enabled -}} + {{- $keys := slice "small" "big" -}} + {{- range $keys -}} + {{- with (index $.Page.Site.Params.ImageProcessing.Cover .) -}} + {{- if gt $Width .Threshold -}} + {{- $resized := $image.resource.Resize (printf "%dx" .Width) -}} + {{- $Srcset = $Srcset | append (printf `%s %dw` $resized.RelPermalink .Width) -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- $Srcset = $Srcset | append (printf `%s %dw` $Permalink $Width) -}} {{- end -}} - - -{{- partial "helper/external" (dict "Context" . "Namespace" "PhotoSwipe") -}} \ No newline at end of file +{{- $opts := dict "minify" hugo.IsProduction "format" "esm" -}} +{{- $galleryScript := resources.Get "ts/gallery.ts" | js.Build $opts -}} + + + + \ No newline at end of file diff --git a/layouts/partials/article/components/related-content.html b/layouts/partials/article/components/related-content.html index aba88e33c..822fc7322 100644 --- a/layouts/partials/article/components/related-content.html +++ b/layouts/partials/article/components/related-content.html @@ -1,4 +1,4 @@ -{{ $related := (where (.Site.RegularPages.Related .) "Params.hidden" "!=" true) | first 5 }} +{{ $related := .Site.RegularPages.Related . | first 5 }} {{ with $related }}