2 Commits

Author SHA1 Message Date
kodiakhq[bot] 619c046222 Merge branch 'main' into autoprefixer-1667142184 2022-10-30 16:46:46 +00:00
kodiakhq[bot] 0cb3365b6a add vendor specific css prefixes 2022-10-30 15:03:03 +00:00
512 changed files with 151387 additions and 5403 deletions
-1
View File
@@ -1 +0,0 @@
node_modules
-12
View File
@@ -1,12 +0,0 @@
env:
browser: true
es2021: true
extends:
- standard
- plugin:no-jquery/all
- prettier
plugins:
- no-jquery
parserOptions:
ecmaVersion: latest
sourceType: module
+1 -1
View File
@@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout to latest commit - name: Checkout to latest commit
uses: actions/checkout@v3.2.0 uses: actions/checkout@v3.1.0
- name: Setup Node - name: Setup Node
uses: actions/setup-node@v3 uses: actions/setup-node@v3
+6 -12
View File
@@ -9,26 +9,20 @@ jobs:
runs-on: ubuntu-18.04 runs-on: ubuntu-18.04
steps: steps:
# checkout to the commit that has been pushed # checkout to the commit that has been pushed
- uses: actions/checkout@v3.2.0 - uses: actions/checkout@v3.1.0
with: with:
submodules: true # Fetch Hugo themes (true OR recursive) submodules: true # Fetch Hugo themes (true OR recursive)
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
- name: Setup Node # install Hugo
uses: actions/setup-node@v3
with:
node-version: 16
- name: Install node modules
run: npm install
- name: Setup Hugo - name: Setup Hugo
uses: peaceiris/actions-hugo@v2.6.0 uses: peaceiris/actions-hugo@v2.6.0
with: with:
hugo-version: 'latest' hugo-version: 'latest'
extended: true extended: true
# build website
- name: Create Config
run: touch config.toml
- name: Build - name: Build
run: | run: hugo --minify
cd exampleSite
hugo --minify
+1 -1
View File
@@ -39,7 +39,7 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v3.2.0 uses: actions/checkout@v3.1.0
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
+1 -1
View File
@@ -10,6 +10,6 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
# Create/Update release draft # Create/Update release draft
- uses: release-drafter/release-drafter@v5.22.0 - uses: release-drafter/release-drafter@v5.21.1
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+1 -1
View File
@@ -8,6 +8,6 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
# checkout to latest commit # checkout to latest commit
- uses: actions/checkout@v3.2.0 - uses: actions/checkout@v3.1.0
# run markdown linter # run markdown linter
- uses: gaurav-nelson/github-action-markdown-link-check@1.0.14 - uses: gaurav-nelson/github-action-markdown-link-check@1.0.14
-5
View File
@@ -1,5 +0,0 @@
printWidth: 100
tabWidth: 2
semi: false
singleQuote: true
trailingComma: "all"
-1
View File
@@ -1 +0,0 @@
nodejs 18.12.1
-1
View File
@@ -62,7 +62,6 @@ For more details about the features please visit [here](https://toha-guides.netl
- Turkish - Turkish
- Arabic (العربية) - Arabic (العربية)
- Português - Português
- Català
To know more about how to translate your site, please visit [here](https://toha-guides.netlify.app/posts/translation/). Follow, the data and post format from this [example site](https://hugo-toha.github.io). To know more about how to translate your site, please visit [here](https://toha-guides.netlify.app/posts/translation/). Follow, the data and post format from this [example site](https://hugo-toha.github.io).
-8
View File
@@ -1,8 +0,0 @@
import 'popper.js'
import 'bootstrap'
import '@fortawesome/fontawesome-free/js/all'
import './core'
import './features'
import './sections'
import './pages'
-36
View File
@@ -1,36 +0,0 @@
let deviceState = {
isMobile: false,
isTablet: false,
isLaptop: false
}
function detectDeviceState () {
if (window.innerWidth <= 425) {
deviceState = {
isMobile: true,
isTablet: false,
isLaptop: false
}
} else if (window.innerWidth <= 768) {
deviceState = {
isMobile: false,
isTablet: true,
isLaptop: false
}
} else {
deviceState = {
isMobile: false,
isTablet: false,
isLaptop: true
}
}
}
detectDeviceState()
window.addEventListener('resize', detectDeviceState)
// returns a copy of the device state
// so other parts of code can't override this.
export function getDeviceState () {
return { ...deviceState }
}
-2
View File
@@ -1,2 +0,0 @@
export * from './device'
export * from './insertScript'
-14
View File
@@ -1,14 +0,0 @@
export const insertScript = (id, src, onload) => {
// script is already inserted, do nothing
if (document.getElementById(id)) return
// insert script
const firstScriptTag = document.getElementsByTagName('script')[0]
const scriptTag = document.createElement('script')
scriptTag.id = id
scriptTag.onload = onload
scriptTag.src = src
scriptTag.defer = true
scriptTag.async = true
firstScriptTag.parentNode.insertBefore(scriptTag, firstScriptTag)
}
@@ -1,30 +0,0 @@
import { enable, disable, auto, setFetchMethod } from 'darkreader'
import * as params from '@params'
const darkreader = params?.darkmode?.darkreader || {}
const defaultColorScheme = darkreader.defaultColorScheme || 'system'
const theme = {
brightness: 100,
contrast: 100,
sepia: 0,
...(darkreader.theme || {})
}
const fixes = {
invert: ['img[src$=".svg"]'],
...(darkreader.fixes || {})
}
setFetchMethod(window.fetch)
export function setSchemeDark () {
enable(theme, fixes)
}
export function setSchemeLight () {
disable()
}
export function setSchemeSystem () {
auto(theme, fixes)
}
export { defaultColorScheme }
-60
View File
@@ -1,60 +0,0 @@
const PERSISTENCE_KEY = 'darkmode:color-scheme'
async function getService () {
if (process.env.FEATURE_DARKMODE_DARKREADER === '1') {
return await import('./darkreader')
}
throw Error(' No service defined for feature darkMode.')
}
window.addEventListener('DOMContentLoaded', async () => {
const menu = document.getElementById('themeMenu')
const $icon = document.getElementById('navbar-theme-icon-svg')
if (menu == null || $icon == null) return
const btns = menu.getElementsByTagName('a')
const iconMap = Array.from(btns).reduce((map, btn) => {
const $img = btn.getElementsByTagName('img')[0]
map[btn.dataset.scheme] = $img.src
return map
}, {})
const {
setSchemeDark,
setSchemeLight,
setSchemeSystem,
defaultColorScheme
} = await getService()
function loadScheme () {
return localStorage.getItem(PERSISTENCE_KEY) || defaultColorScheme
}
function saveScheme (scheme) {
localStorage.setItem(PERSISTENCE_KEY, scheme)
}
function setScheme (newScheme) {
$icon.src = iconMap[newScheme]
if (newScheme === 'dark') {
setSchemeDark()
} else if (newScheme === 'system') {
setSchemeSystem()
} else {
setSchemeLight()
}
saveScheme(newScheme)
}
setScheme(loadScheme())
Array.from(menu.getElementsByTagName('a')).forEach((btn) => {
btn.addEventListener('click', () => {
const { scheme } = btn.dataset
setScheme(scheme)
})
})
})
-165
View File
@@ -1,165 +0,0 @@
import { insertScript } from '../../core'
const PDFJS_BUNDLE = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@3.0.279/build/pdf.min.js'
const WORKER_BUNDLE = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@3.0.279/build/pdf.worker.min.js'
class PDFViewer {
constructor (el) {
const {
url,
hidePaginator,
hideLoader,
scale,
pageNum
} = el.dataset
if (url == null) {
throw new Error('Cannot load PDF! Attribute `data-url` is not set.')
}
// props
this.url = url
this.hidePaginator = hidePaginator !== 'false'
this.hideLoader = hideLoader !== 'false'
this.scale = scale || 3
// initial state
this.pageNum = parseInt(pageNum, 10) || 1
this.loaded = false
this.pageRendering = false
this.pageNumPending = null
// DOM elements
this.canvas = el.getElementsByClassName('pdf-canvas')[0]
if (this.canvas == null) {
throw new Error('canvas element not found!')
};
this.paginator = el.getElementsByClassName('paginator')[0]
this.loadingWrapper = el.getElementsByClassName('loading-wrapper')[0]
this.next = el.getElementsByClassName('next')[0]
this.prev = el.getElementsByClassName('prev')[0]
this.pageNum = el.getElementsByClassName('page-num')[0]
this.pageCount = el.getElementsByClassName('page-count')[0]
// context
this.ctx = this.canvas.getContext('2d')
// events
this.next.addEventListener('click', this.handleNextPage.bind(this))
this.prev.addEventListener('click', this.handlePrevPage.bind(this))
this.showPaginator()
this.showLoader()
this.loadPDF()
}
/**
* If we haven't disabled the loader, show loader and hide canvas
*/
showLoader () {
if (this.hideLoader) return
this.loadingWrapper.style.display = 'flex'
this.canvas.style.display = 'none'
}
/**
* If we haven't disabled the paginator, show paginator
*/
showPaginator () {
if (this.hidePaginator) return
this.paginator.style.display = 'block'
}
/**
* Hides loader and shows canvas
*/
showContent () {
this.loadingWrapper.style.display = 'none'
this.canvas.style.display = 'block'
}
/**
* Asynchronously downloads PDF.
*/
async loadPDF () {
this.pdfDoc = await window.pdfjsLib.getDocument(this.url).promise
this.pageCount.textContent = this.pdfDoc.numPages
// If the user passed in a number that is out of range, render the last page.
if (this.pageNum > this.pdfDoc.numPages) {
this.pageNum = this.pdfDoc.numPages
}
this.renderPage(this.pageNum)
}
/**
* Get page info from document, resize canvas accordingly, and render page.
* @param num Page number.
*/
async renderPage (num) {
this.pageRendering = true
const page = await this.pdfDoc.getPage(num)
const viewport = page.getViewport({ scale: this.scale })
this.canvas.height = viewport.height
this.canvas.width = viewport.width
// Wait for rendering to finish
await page.render({
canvasContext: this.ctx,
viewport
}).promise
this.pageRendering = false
this.showContent()
if (this.pageNumPending !== null) {
// New page rendering is pending
this.renderPage(this.pageNumPending)
this.pageNumPending = null
}
// Update page counters
this.pageNum.textContent = num
}
/**
* If another page rendering in progress, waits until the rendering is
* finished. Otherwise, executes rendering immediately.
*/
queueRenderPage (num) {
if (this.pageRendering) {
this.pageNumPending = num
} else {
this.renderPage(num)
}
}
/**
* Displays previous page.
*/
handlePrevPage () {
if (this.pageNum <= 1) {
return
}
this.pageNum--
this.queueRenderPage(this.pageNum)
}
/**
* Displays next page.
*/
handleNextPage () {
if (this.pageNum >= this.pdfDoc.numPages) {
return
}
this.pageNum++
this.queueRenderPage(this.pageNum)
}
}
insertScript('pdfjs', PDFJS_BUNDLE, () => {
window.pdfjsLib.GlobalWorkerOptions.workerSrc = WORKER_BUNDLE
Array.from(document.getElementsByClassName('pdf-viewer')).forEach(el => new PDFViewer(el))
})
@@ -1,3 +0,0 @@
if (process.env.FEATURE_FLOWCHART_MERMAID === '1') {
import('./mermaid')
}
@@ -1,7 +0,0 @@
import mermaid from 'mermaid'
import * as params from '@params'
const mermaidOptions = params.flowchart?.mermaid || {}
const options = Object.assign({}, mermaidOptions, { startOnLoad: true })
mermaid.initialize(options)
-27
View File
@@ -1,27 +0,0 @@
if (process.env.FEATURE_VIDEOPLAYER === '1') {
import('./videoplayer')
}
if (process.env.FEATURE_TOC === '1') {
import('./toc')
}
if (process.env.FEATURE_DARKMODE === '1') {
import('./darkmode')
}
if (process.env.FEATURE_FLOWCHART === '1') {
import('./flowchart')
}
if (process.env.FEATURE_SYNTAXHIGHLIGHT === '1') {
import('./syntaxhighlight')
}
if (process.env.FEATURE_MATH === '1') {
import('./math')
}
if (process.env.FEATURE_EMBEDPDF === '1') {
import('./embedpdf')
}
-3
View File
@@ -1,3 +0,0 @@
if (process.env.FEATURE_MATH_KATEX === '1') {
import('./katex')
}
-21
View File
@@ -1,21 +0,0 @@
import renderMathInElement from 'katex/contrib/auto-render'
import * as params from '@params'
const defaultOptions = {
delimiters: [
{ left: '$$', right: '$$', display: true },
{ left: '\\[', right: '\\]', display: true },
{ left: '$', right: '$', display: false },
{ left: '\\(', right: '\\)', display: false }
]
}
window.addEventListener('DOMContentLoaded', () => {
renderMathInElement(
document.body,
{
...defaultOptions,
...(params.math?.katex || {})
}
)
})
@@ -1,4 +0,0 @@
import hljs from 'highlight.js'
import * as params from '@params'
hljs.highlightAll(params.syntaxhighlight?.hljs)
@@ -1,3 +0,0 @@
if (process.env.FEATURE_SYNTAXHIGHLIGHT_HLJS === '1') {
import('./hljs')
}
-48
View File
@@ -1,48 +0,0 @@
import { getDeviceState } from '../../core'
// Toggle Table of Contents on click. Here, class "hide" open the toc
function toggleTOC () {
const toc = document.getElementById('toc-section')
if (toc == null) {
return
}
if (toc.classList.contains('hide')) {
toc.classList.remove('hide')
} else {
// if sidebar-section is open, then close it first
const sidebar = document.getElementById('sidebar-section')
if (sidebar != null && sidebar.classList.contains('hide')) {
sidebar.classList.remove('hide')
}
// add "hide" class
toc.classList.add('hide')
// if it is mobile device. then scroll to top.
const { isMobile } = getDeviceState()
if (isMobile && toc.classList.contains('hide')) {
document.body.scrollTop = 0
document.documentElement.scrollTop = 0
}
}
if (document.getElementById('hero-area') != null) {
document.getElementById('hero-area').classList.toggle('hide')
}
}
window.addEventListener('DOMContentLoaded', () => {
// bind click event to #toc-toggle in navbar-2.html
const toggle = document.getElementById('toc-toggler')
if (toggle) toggle.addEventListener('click', toggleTOC)
// hide TOC when user clicks on a TOC link.
// Only applies if it's mobile.
const toc = document.getElementById('TableOfContents')
if (toc) {
toc.addEventListener('click', (event) => {
const { isMobile } = getDeviceState()
if (isMobile && event.target.nodeName === 'A') {
toggleTOC()
}
})
}
})
@@ -1,3 +0,0 @@
if (process.env.FEATURE_VIDEOPLAYER_PLYR === '1') {
import('./plyr')
}
@@ -1,5 +0,0 @@
import Plyr from 'plyr'
import * as params from '@params'
const options = params.videoplayer?.plyr
window.addEventListener('DOMContentLoaded', () => Plyr.setup('.video-player', options))
-16
View File
@@ -1,16 +0,0 @@
import { init } from 'ityped'
// =========== Typing Carousel ================
// get data from hidden ul and set as typing data
document.addEventListener('DOMContentLoaded', () => {
const $ul = document.getElementById('typing-carousel-data')?.children
if ($ul == null || $ul.length === 0) return
const strings = Array.from($ul).map($el => $el.textContent)
init('#ityped', {
strings,
startDelay: 200,
loop: true
})
})
-4
View File
@@ -1,4 +0,0 @@
import './note'
import './search'
import './single'
import './home'
-30
View File
@@ -1,30 +0,0 @@
import imagesLoaded from 'imagesloaded'
document.addEventListener('DOMContentLoaded', function () {
function resizeGridItem (item) {
const grid = document.getElementsByClassName('note-card-holder')[0]
const rowHeight = parseInt(window.getComputedStyle(grid).getPropertyValue('grid-auto-rows'))
const rowGap = parseInt(window.getComputedStyle(grid).getPropertyValue('grid-row-gap'))
const rowSpan = Math.ceil((item.querySelector('.item').getBoundingClientRect().height + rowGap) / (rowHeight + rowGap))
item.style.gridRowEnd = 'span ' + rowSpan
}
function resizeAllGridItems () {
const allItems = document.getElementsByClassName('note-card')
for (let x = 0; x < allItems.length; x++) {
resizeGridItem(allItems[x])
}
}
function resizeInstance (instance) {
const item = instance.elements[0]
resizeGridItem(item)
}
window.addEventListener('resize', resizeAllGridItems)
const allItems = document.getElementsByClassName('note-card')
for (let x = 0; x < allItems.length; x++) {
imagesLoaded(allItems[x], resizeInstance)
}
})
-133
View File
@@ -1,133 +0,0 @@
import Fuse from 'fuse.js'
import Mark from 'mark.js'
window.addEventListener('DOMContentLoaded', () => {
const summaryInclude = 60
const fuseOptions = {
shouldSort: true,
includeMatches: true,
threshold: 0.0,
tokenize: true,
location: 0,
distance: 100,
maxPatternLength: 32,
minMatchCharLength: 1,
keys: [
{ name: 'title', weight: 0.8 },
{ name: 'hero', weight: 0.7 },
{ name: 'summary', weight: 0.6 },
{ name: 'date', weight: 0.5 },
{ name: 'contents', weight: 0.5 },
{ name: 'tags', weight: 0.3 },
{ name: 'categories', weight: 0.3 }
]
}
const searchQuery = param('keyword')
if (searchQuery) {
document.getElementById('search-query').value = searchQuery
executeSearch(searchQuery)
} else {
const node = document.createElement('p')
node.textContent = 'Please enter a word or phrase above'
document.getElementById('search-results')?.append(node)
}
function executeSearch (searchQuery) {
const url = window.location.href.split('/search/')[0] + '/index.json'
fetch(url).then(function (data) {
const pages = data
const fuse = new Fuse(pages, fuseOptions)
const results = fuse.search(searchQuery)
document.getElementById('search-box').value = searchQuery
if (results.length > 0) {
populateResults(results)
} else {
const node = document.createElement('p')
node.textContent = 'No matches found'
document.getElementById('search-results')?.append(node)
}
})
}
function populateResults (results) {
results.forEach(function (value, key) {
const contents = value.item.contents
let snippet = ''
const snippetHighlights = []
if (fuseOptions.tokenize) {
snippetHighlights.push(searchQuery)
} else {
value.matches.forEach(function (mvalue) {
if (mvalue.key === 'tags' || mvalue.key === 'categories') {
snippetHighlights.push(mvalue.value)
} else if (mvalue.key === 'contents') {
const start = mvalue.indices[0][0] - summaryInclude > 0 ? mvalue.indices[0][0] - summaryInclude : 0
const end = mvalue.indices[0][1] + summaryInclude < contents.length ? mvalue.indices[0][1] + summaryInclude : contents.length
snippet += contents.substring(start, end)
snippetHighlights.push(mvalue.value.substring(mvalue.indices[0][0], mvalue.indices[0][1] - mvalue.indices[0][0] + 1))
}
})
}
if (snippet.length < 1) {
snippet += contents.substring(0, summaryInclude * 2)
}
// pull template from hugo template definition
const templateDefinition = document.getElementById('search-result-template').innerHTML
// replace values
const output = render(templateDefinition, {
key,
title: value.item.title,
hero: value.item.hero,
date: value.item.date,
summary: value.item.summary,
link: value.item.permalink,
tags: value.item.tags,
categories: value.item.categories,
snippet
})
const doc = new DOMParser().parseFromString(output, 'text/html')
document.getElementById('search-results').append(doc)
snippetHighlights.forEach(function (snipvalue) {
const context = document.getElementById('#summary-' + key)
const instance = new Mark(context)
instance.mark(snipvalue)
})
})
}
function param (name) {
return decodeURIComponent((location.search.split(name + '=')[1] || '').split('&')[0]).replace(/\+/g, ' ')
}
function render (templateString, data) {
let conditionalMatches, copy
const conditionalPattern = /\$\{\s*isset ([a-zA-Z]*) \s*\}(.*)\$\{\s*end\s*}/g
// since loop below depends on re.lastInxdex, we use a copy to capture any manipulations whilst inside the loop
copy = templateString
while ((conditionalMatches = conditionalPattern.exec(templateString)) !== null) {
if (data[conditionalMatches[1]]) {
// valid key, remove conditionals, leave contents.
copy = copy.replace(conditionalMatches[0], conditionalMatches[2])
} else {
// not valid, remove entire section
copy = copy.replace(conditionalMatches[0], '')
}
}
templateString = copy
// now any conditionals removed we can do simple substitution
let key, find, re
for (key in data) {
find = '\\$\\{\\s*' + key + '\\s*\\}'
re = new RegExp(find, 'g')
templateString = templateString.replace(re, data[key])
}
return templateString
}
})
-60
View File
@@ -1,60 +0,0 @@
window.addEventListener('DOMContentLoaded', () => {
// =========== Add anchor to the headers ================
function addAnchor (element) {
element.innerHTML = `<a href="#${element.id}" class="header-anchor">${element.innerHTML}<sup><i class="fas fa-link fa-sm"></i></sup></a>`
}
const postContent = document.getElementById('post-content')
if (postContent != null) {
const headerTypes = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']
for (let i = 0; i < headerTypes.length; i++) {
const headers = postContent.querySelectorAll(headerTypes[i])
if (headers) {
headers.forEach(addAnchor)
}
}
}
// =============== Make TOC Compatible wit Bootstrap Scroll Spy ========
// add "navbar" class to the "nav" element
const toc = document.getElementById('TableOfContents')
if (toc) {
toc.classList.add('navbar')
// add "nav-pills" class to the "ul" elements
let elems = toc.getElementsByTagName('ul')
for (let i = 0; i < elems.length; i++) {
elems[i].classList.add('nav-pills')
}
// add "nav-item" class to the "li" elements
elems = toc.getElementsByTagName('li')
for (let i = 0; i < elems.length; i++) {
elems[i].classList.add('nav-item')
}
// add "nav-link" class to the "a" elements
elems = toc.getElementsByTagName('a')
for (let i = 0; i < elems.length; i++) {
elems[i].classList.add('nav-link')
}
}
// add scroll to top button
const btn = document.getElementById('scroll-to-top')
if(btn) {
window.addEventListener('scroll', function () {
if (window.scrollY > 300) {
btn.classList.add('show')
} else {
btn.classList.remove('show')
}
})
btn.addEventListener('click', function (e) {
e.preventDefault()
window.scrollTo({
top: 0,
behavior: 'smooth'
})
})
}
})
-3
View File
@@ -1,3 +0,0 @@
export const process = {
env: {}
}
-220
View File
@@ -1,220 +0,0 @@
import { getDeviceState } from '../core'
function fourColumRow (gallery, entries, i) {
const entry1 = document.createElement('div')
entry1.classList.add('col-lg-6', 'm-0', 'p-0')
entry1.appendChild(entries[i].cloneNode(true))
entry1.children[0].classList.add('img-type-1')
gallery.appendChild(entry1)
i++
const entry2 = document.createElement('div')
entry2.classList.add('col-lg-3', 'm-0', 'p-0')
entry2.appendChild(entries[i].cloneNode(true))
entry2.children[0].classList.add('img-type-1')
gallery.appendChild(entry2)
i++
const entry3 = document.createElement('div')
entry3.classList.add('col-lg-3', 'm-0', 'p-0')
entry3.appendChild(entries[i].cloneNode(true))
entry3.children[0].classList.add('img-type-2')
i++
entry3.appendChild(entries[i].cloneNode(true))
entry3.children[1].classList.add('img-type-2')
gallery.appendChild(entry3)
i++
}
function fourColumnReversedRow (gallery, entries, i) {
const entry1 = document.createElement('div')
entry1.classList.add('col-lg-3', 'm-0', 'p-0')
entry1.appendChild(entries[i].cloneNode(true))
entry1.children[0].classList.add('img-type-2')
i++
entry1.appendChild(entries[i].cloneNode(true))
entry1.children[1].classList.add('img-type-2')
gallery.appendChild(entry1)
i++
const entry2 = document.createElement('div')
entry2.classList.add('col-lg-3', 'm-0', 'p-0')
entry2.appendChild(entries[i].cloneNode(true))
entry2.children[0].classList.add('img-type-1')
gallery.appendChild(entry2)
i++
const entry3 = document.createElement('div')
entry3.classList.add('col-lg-6', 'm-0', 'p-0')
entry3.appendChild(entries[i].cloneNode(true))
entry3.children[0].classList.add('img-type-1')
gallery.appendChild(entry3)
i++
}
function threeColumnRow (gallery, entries, i) {
console.log(i)
const entry1 = document.createElement('div')
entry1.classList.add('col-lg-6', 'col-md-6', 'm-0', 'p-0')
entry1.appendChild(entries[i].cloneNode(true))
entry1.children[0].classList.add('img-type-1')
gallery.appendChild(entry1)
i++
const entry2 = document.createElement('div')
entry2.classList.add('col-lg-3', 'col-md-3', 'm-0', 'p-0')
entry2.appendChild(entries[i].cloneNode(true))
entry2.children[0].classList.add('img-type-1')
gallery.appendChild(entry2)
i++
const entry3 = document.createElement('div')
entry3.classList.add('col-lg-3', 'col-md-3', 'm-0', 'p-0')
entry3.appendChild(entries[i].cloneNode(true))
entry3.children[0].classList.add('img-type-1')
gallery.appendChild(entry3)
i++
}
function threeColumnReversedRow (gallery, entries, i) {
const entry1 = document.createElement('div')
entry1.classList.add('col-lg-3', 'col-md-3', 'm-0', 'p-0')
entry1.appendChild(entries[i].cloneNode(true))
entry1.children[0].classList.add('img-type-1')
gallery.appendChild(entry1)
i++
const entry2 = document.createElement('div')
entry2.classList.add('col-lg-3', 'col-md-3', 'm-0', 'p-0')
entry2.appendChild(entries[i].cloneNode(true))
entry2.children[0].classList.add('img-type-1')
gallery.appendChild(entry2)
i++
const entry3 = document.createElement('div')
entry3.classList.add('col-lg-6', 'col-md-3', 'm-0', 'p-0')
entry3.appendChild(entries[i].cloneNode(true))
entry3.children[0].classList.add('img-type-1')
gallery.appendChild(entry3)
i++
}
function twoColumnRow (gallery, entries, i) {
const entry1 = document.createElement('div')
entry1.classList.add('col-6', 'm-0', 'p-0')
entry1.appendChild(entries[i].cloneNode(true))
entry1.children[0].classList.add('img-type-1')
gallery.appendChild(entry1)
i++
const entry2 = document.createElement('div')
entry2.classList.add('col-6', 'm-0', 'p-0')
entry2.appendChild(entries[i].cloneNode(true))
entry2.children[0].classList.add('img-type-1')
gallery.appendChild(entry2)
i++
}
function singleColumnRow (gallery, entries, i) {
const entry1 = document.createElement('div')
entry1.classList.add('col-12', 'm-0', 'p-0')
entry1.appendChild(entries[i].cloneNode(true))
entry1.children[0].classList.add('img-type-1')
gallery.appendChild(entry1)
i++
}
function showAchievements () {
const { isLaptop, isTablet } = getDeviceState()
// show achievements from achievements-holder div
const gallery = document.getElementById('gallery')
if (gallery == null) {
return
}
gallery.innerHTML = ''
const entries = document.getElementById('achievements-holder').children
let len = entries.length
let i = 0
let rowNumber = 1
while (i < len) {
if (isLaptop) {
if (i + 4 <= len) {
if (rowNumber % 2) {
fourColumRow(gallery, entries, i)
} else {
fourColumnReversedRow(gallery, entries, i)
}
i += 4
} else if (i + 3 <= len) {
if (rowNumber % 2) {
threeColumnRow(gallery, entries, i)
} else {
threeColumnReversedRow(gallery, entries, i)
}
i += 3
} else if (i + 2 <= len) {
twoColumnRow(gallery, entries, i)
i += 2
} else {
singleColumnRow(gallery, entries, i)
i++
}
} else if (isTablet) {
if (i + 2 <= len) {
twoColumnRow(gallery, entries, i)
i += 2
} else {
singleColumnRow(gallery, entries, i)
i++
}
} else {
singleColumnRow(gallery, entries, i)
i++
}
rowNumber++
}
// show full image on click
const elements = document.getElementsByClassName('achievement-entry')
len = elements.length
for (let i = 0; i < len; i++) {
elements[i].onclick = function () {
const achievements = document.getElementsByClassName('achievement-entry')
const len2 = achievements.length
for (let j = 0; j < len2; j++) {
achievements[j].classList.toggle('hidden')
}
this.classList.toggle('achievement-details')
this.classList.toggle('hidden')
this.parentElement.classList.toggle('col-lg-12')
this.parentElement.classList.toggle('col-md-12')
this.parentElement.classList.toggle('col-sm-12')
if (this.children.SmallImage.hasAttribute('active')) {
const mainLogo = this.children.LargeImage.getAttribute('Style')
this.children.LargeImage.setAttribute('active', true)
this.children.SmallImage.removeAttribute('active')
this.setAttribute('Style', mainLogo)
} else {
const mainLogo = this.children.SmallImage.getAttribute('Style')
this.children.SmallImage.setAttribute('active', true)
this.children.LargeImage.removeAttribute('active')
this.setAttribute('Style', mainLogo)
}
if (this.children.caption !== undefined) {
this.children.caption.classList.toggle('hidden')
}
if (this.children['enlarge-icon'] !== undefined) {
this.getElementsByClassName('fa-xmark')[0].classList.toggle('hidden')
this.getElementsByClassName('fa-magnifying-glass-plus')[0].classList.toggle('hidden')
}
if (this.children['achievement-title'] !== undefined) {
this.children['achievement-title'].classList.toggle('hidden')
}
}
}
}
['DOMContentLoaded', 'resize'].forEach((event) =>
document.addEventListener(event, showAchievements))
-33
View File
@@ -1,33 +0,0 @@
// Show more rows in the taken courses table
function toggleCourseVisibility (elem) {
// find the courses
const courses = elem.parentNode.getElementsByClassName('course')
if (courses == null) {
return
}
// toggle hidden-course class from the third elements
for (const course of courses) {
if (course.classList.contains('hidden-course') || course.classList.contains('toggled-hidden-course')) {
course.classList.toggle('hidden-course')
course.classList.add('toggled-hidden-course')
}
}
// toggle the buttons visibility
const buttonsToToggle = elem.parentNode.getElementsByClassName('show-more-btn')
for (const buttonToToggle of buttonsToToggle) {
buttonToToggle.classList.toggle('hidden')
}
}
window.addEventListener('DOMContentLoaded', () => {
const els = [
document.getElementById('show-more-btn'),
document.getElementById('show-less-btn')
]
els.filter((el) => el != null).forEach((el) =>
el.addEventListener('click', ({ target }) =>
toggleCourseVisibility(target)))
})
-7
View File
@@ -1,7 +0,0 @@
import './navbar'
import './sidebar'
import './education'
import './achievements'
import './projects'
import './publications'
-60
View File
@@ -1,60 +0,0 @@
const updateNavBar = () => {
const topNavbar = document.getElementById('top-navbar')
const navbarToggler = document.getElementById('navbar-toggler')
const themeIcon = document.getElementById('navbar-theme-icon-svg')
if (window.scrollY > 40) {
topNavbar?.classList.remove('initial-navbar')
topNavbar?.classList.add('final-navbar', 'shadow')
navbarToggler?.classList.remove('navbar-dark')
navbarToggler?.classList.add('navbar-light')
// color theme selector a.k.a. dark mode
themeIcon?.classList.remove('navbar-icon-svg-dark')
// get the main logo from hidden img tag
const mainLogo = document.getElementById('main-logo')
if (mainLogo) {
const logoURL = mainLogo.getAttribute('src')
document.getElementById('logo')?.setAttribute('src', logoURL)
}
} else {
topNavbar?.classList.remove('final-navbar', 'shadow')
topNavbar?.classList.add('initial-navbar')
navbarToggler?.classList.remove('navbar-light')
navbarToggler?.classList.add('navbar-dark')
// color theme selector a.k.a. dark mode
themeIcon?.classList.add('navbar-icon-svg-dark')
// get the inverted logo from hidden img tag
const invertedLogo = document.getElementById('inverted-logo')
if (invertedLogo) {
const logoURL = invertedLogo.getAttribute('src')
document.getElementById('logo')?.setAttribute('src', logoURL)
}
}
}
document.addEventListener('DOMContentLoaded', function () {
// change navbar style on scroll
// ==================================================
// When the user scrolls down 80px from the top of the document,
// resize the navbar's padding and the logo's font size
document.addEventListener('scroll', updateNavBar)
// Creates a click handler to collapse the navigation when
// anchors in the mobile nav pop up are clicked
const navMain =document.getElementsByClassName('navbar-collapse')
Array.from(navMain).forEach(function(el) {
el.addEventListener('click', function (e) {
if (e.target.tagName === 'A') {
el.classList.add('collapse')
}
})
})
updateNavBar()
})
-19
View File
@@ -1,19 +0,0 @@
import Filterizr from 'filterizr'
import { insertScript } from '../core'
document.addEventListener('DOMContentLoaded', () => {
// ================== Project cards =====================
// setup project filter buttons
const projectCardHolder = document.getElementById('project-card-holder')
if (projectCardHolder != null && projectCardHolder.children.length !== 0) {
// eslint-disable-next-line no-new
new Filterizr('.filtr-projects', {
layout: 'sameWidth',
controlsSelector: '.project-filtr-control'
})
}
})
// dynamically insert github buttons script.
insertScript('github-buttons', 'https://buttons.github.io/buttons.js')
-13
View File
@@ -1,13 +0,0 @@
import Filterizr from 'filterizr'
document.addEventListener('DOMContentLoaded', () => {
const publicationCardHolder = document.getElementById('publication-card-holder')
if (publicationCardHolder != null && publicationCardHolder.children.length !== 0) {
// eslint-disable-next-line no-new
new Filterizr('.filtr-publications', {
layout: 'sameWidth',
gridItemsSelector: '.pub-filtr-item',
controlsSelector: '.pub-filtr-control'
})
}
})
-38
View File
@@ -1,38 +0,0 @@
import { getDeviceState } from '../core/device'
// Toggle sidebar on click. Here, class "hide" open the sidebar
function toggleSidebar () {
const sidebar = document.getElementById('sidebar-section')
if (sidebar == null) {
return
}
if (sidebar.classList.contains('hide')) {
sidebar.classList.remove('hide')
} else {
// if toc-section is open, then close it first
const toc = document.getElementById('toc-section')
if (toc != null && toc.classList.contains('hide')) {
toc.classList.remove('hide')
}
// add "hide" class
sidebar.classList.add('hide')
// if it is mobile device. then scroll to top.
const { isMobile } = getDeviceState()
if (isMobile && sidebar.classList.contains('hide')) {
document.body.scrollTop = 0
document.documentElement.scrollTop = 0
if (document.getElementById('hero-area') != null) {
document.getElementById('hero-area').classList.toggle('hide')
}
}
}
if (document.getElementById('content-section') != null) {
document.getElementById('content-section').classList.toggle('hide')
}
}
window.addEventListener('DOMContentLoaded', () => {
// bind click event to #sidebar-toggler in navbar-2.html
const toggle = document.getElementById('sidebar-toggler')
if (toggle) toggle.addEventListener('click', toggleSidebar)
})
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+1 -1
View File
@@ -43,7 +43,7 @@ Esto expone los valores en /index.json: por ejemplo, para agregar `categories`
\``` \```
### Editar las opciones de fuse.js para buscar ### Editar las opciones de fuse.js para buscar
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -13,7 +13,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -41,7 +41,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+1 -1
View File
@@ -43,7 +43,7 @@ Esto expone los valores en /index.json: por ejemplo, para agregar `categories`
\``` \```
### Editar las opciones de fuse.js para buscar ### Editar las opciones de fuse.js para buscar
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
+2 -2
View File
@@ -15,7 +15,7 @@ No content shown here is rendered, all content is based in the template layouts/
Setting a very low sitemap priority will tell search engines this is not important content. Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs and mark.js This implementation uses Fusejs, jquery and mark.js
## Initial setup ## Initial setup
@@ -43,7 +43,7 @@ i.e. add `category`
\``` \```
### Edit fuse.js options to Search ### Edit fuse.js options to Search
`assets/scripts/pages/search.js` `static/js/search.js`
\``` \```
keys: [ keys: [
"title", "title",
-292
View File
@@ -1,292 +0,0 @@
baseURL: http://example.org/
languageCode: en-us
title: Example Site
module:
imports:
- path: github.com/hugo-toha/hugo-toha.github.io
disable: false
mounts:
- source: content
target: content
- source: layouts
target: layouts
- source: data
target: data
- source: assets
target: assets
- source: static
target: static
- path: github.com/hugo-toha/toha/v4
# Manage languages
# For any more details, you can check the official documentation: https://gohugo.io/content-management/multilingual/
languages:
en:
languageName: English
weight: 1
bn:
languageName: বাংলা
weight: 3
# Force a locale to be use, really useful to develop the application ! Should be commented in production, the "weight" should rocks.
# DefaultContentLanguage: bn
# Allow raw html in markdown file
markup:
goldmark:
renderer:
unsafe: true
tableOfContents:
startLevel: 2
endLevel: 6
ordered: false
# At least HTML and JSON are required for the main HTML content and
# client-side JavaScript search
outputs:
home:
- HTML
- RSS
- JSON
# Enable global emoji support
enableEmoji: true
# Site parameters
params:
# Background image of the landing page
background: /images/site/background.jpg
# Provide logos for your site. The inverted logo will be used in the initial
# transparent navbar and the main logo will be used in the non-transparent navbar.
logo:
main: /images/site/main-logo.png
inverted: /images/site/inverted-logo.png
favicon: /images/site/favicon.png
# GitHub repo of your site
gitRepo: https://github.com/hugo-toha/hugo-toha.github.io
# Default branch of your Git repo
gitBranch: main
# Configure the number of section title visible in the top navbar
topNavbar:
maxVisibleSections: 5
# Configure various features of this theme
features:
# Enable dark theme
darkMode:
enable: false
services:
darkreader:
defaultColorScheme: system # options are 'system', 'dark', 'light'
fixes:
invert: ['img[src$=".svg"]'] # inverts svg colors.
theme:
brightness: 100
contrast: 100
sepia: 0
# Enable and configure portfolio
portfolio:
enable: true
# Enable and configure blog posts
blog:
enable: true
# Share post on different social media
shareButtons:
facebook: true
twitter: true
linkedin: true
reddit: true
whatsapp: true
email: true
# tumblr: true
# pocket: true
# diaspora: true
# mastodon: true
# Enable & configure "Notes" features
notes:
enable: true
# Enable comment feature. There, should be only one of them.
comment:
enable: false
services:
disqus:
shortName: toha-example-site
# valine:
# appId: HTV6askWxVo3vOxlqjjaq2hd-MsYXbMMI
# appKey: pVrT3C85KGIuk27t07eh6bUC
# avatar: retro
# placeholder: Share your thought.
# lang: en
# recordIP: true
# enableQQ: true
# utteranc:
# repo: github.com/hugo-toha/hugo-toha.github.io
# issueTerm: title
# theme: github-light
# giscus:
# repo: your-repo/name
# repoID: your-repo-id
# category: your-category
# categoryID: your-category-id
# theme: light
# map: url
# reaction: 1
# metadata: 0
# inputPosition: bottom
# crossOrigin: anonymous
# commento:
# serverURL: cdn.commento.io
# autoInit: true
# hideDeleted: false
# Enable Analytics
analytics:
enabled: false
services:
# Google Analytics
google:
id: G-H4LBG7NDFZ
# # CounterDev
# counterDev:
# id: <your counterdev id>
# # GoatCounter
# goatCounter:
# code: <your goat counter code>
# # Matomo / Piwik
# matomo:
# instance: matomo.example.com
# siteId: 1 # Or any other number
# Enable Support
support:
enable: false
services:
kofi:
user: hossainemruz
text: Tip Me
textColor: '#f9fafc'
backgroundColor: '#248aaa'
# buymeacoffee:
# user: <your buymeacoffee.com user>
# text: Support me on Buy me a coffee!
# info: Buy me a coffee!
# color: '#FFDD00'
# specify whether you want to show Table of Contents in reading page
toc:
enable: true
# Show tags under the post title
tags:
enable: true
# Specify whether to show flag in the language selector. Default is true.
flags:
enable: true
# # If you want to use different country flag for a language, specify them here.
# flagOverwrites:
# - languageCode: en
# countryCode: us
# Enable this to use `embed-pdf` shortcode.
embedpdf:
enable: false
# Enable this to create flowcharts using shortcodes.
flowchart:
enable: false
services:
# Uncomment for `mermaid` shortcode.
mermaid:
# For config options, see: https://mermaid-js.github.io/mermaid/#/Setup?id=configuration
# theme: dark
# Enable this to create mathematic expressions using `$$` blocks
math:
enable: false
services:
# https://katex.org/docs/autorender.html#api for more configurations
katex:
delimiters:
- left: $$
right: $$
display: true
- left: \\[
right: \\]
display: true
- left: $
right: $
display: false
- left: \\(
right: \\)
display: false
# Enable to use custom syntax highlight
# Please note, Hugo comes with it's own html based syntax highlighter.
# Your code block will still be syntax highlighted by hugo.
# For more details: https://gohugo.io/content-management/syntax-highlighting/
# To disable Hugo's builtin syntax highlight,
# see: https://gohugo.io/getting-started/configuration-markup#highlight
# ```
# # config.yaml
# markup:
# # this disables hugo's syntax highlighting.
# codeFences: false
# ```
syntaxHighlight:
enable: true
services:
hljs:
# see: https://highlightjs.readthedocs.io/en/latest/api.html#configure
noHighlightRe: /^no-highlight$/i
# Enable to use `video-player` shortcode
videoPlayer:
enable: false
services:
# convert .js-player class into video player via https://plyr.io/
# Can play HTML5 Video, Audio, Youtube, Vimeo.
# For more info on setup: https://github.com/sampotts/plyr#quick-setup
plyr:
# options doc: https://github.com/sampotts/plyr#options
# fullscreen: true
# Provide footer configuration.
footer:
enable: true
# You can provide your custom footer template using this option.
# Put your template in "layouts/partials" folder of your repo.
template: footer.html
# Show/hide navigation in the footer. Default is "true".
navigation:
enable: true
# show custom menus in the footer
customMenus: true
# Show/hide "Contact Me" section in the footer. Default is "true".
contactMe:
enable: true
# Show/hide credentials section in the footer. Default is "true".
credentials:
enable: true
# Show/hide newsletter section in the footer. Default is "true".
# Currently, it supports "mailchimp".
newsletter:
enable: true
provider: mailchimp
mailchimpURL: https://github.us1.list-manage.com/subscribe/post?u=19de52a4603135aae97163fd8&amp;id=094a24c76e
# Show/hide disclaimer notice in the footer. Default is "false".
disclaimer:
enable: true
-7
View File
@@ -1,7 +0,0 @@
module github.com/hugo-toha/toha/exampleSite
go 1.19
require github.com/hugo-toha/hugo-toha.github.io v0.0.0-20221228191121-007f31838bd6 // indirect
replace github.com/hugo-toha/toha/v4 => ../../toha
-2
View File
@@ -1,2 +0,0 @@
github.com/hugo-toha/hugo-toha.github.io v0.0.0-20221228191121-007f31838bd6 h1:TPFhOZAnuH4wjLIdzimswCRa2qCcc1teKVTatADJU2g=
github.com/hugo-toha/hugo-toha.github.io v0.0.0-20221228191121-007f31838bd6/go.mod h1:OMMaP9Hh9NsKd41lVIazBQRPa0s6Z57AfJoY3DcCNNY=
+6 -2
View File
@@ -1,3 +1,7 @@
module github.com/hugo-toha/toha/v4 module github.com/hugo-toha/toha
go 1.19 go 1.12
// require(
// )
-126
View File
@@ -1,126 +0,0 @@
# More documentation here: https://github.com/nicksnyder/go-i18n
[home]
other = "Inici"
[posts]
other = "Publicacions"
[toc_heading]
other = "Taula de Continguts"
[tags]
other = "Etiquetes"
[categories]
other = "Categories"
[at]
other = "a"
[resume]
other = "El meu currículum"
[navigation]
other = "Navegació"
[contact_me]
other = "Contacta'm:"
[email]
other = "Correu electrònic"
[phone]
other = "Telèfon"
[newsletter_text]
other = "Subscriure's"
[newsletter_input_placeholder]
other = "Entra l'email"
[newsletter_warning]
other = "Al entrar la vostra direcció de correu electrònic, esteu acceptant rebre el butlletí d'aquest lloc web."
[submit]
other = "Enviar"
[hugoAttributionText]
other = "Impulsat per"
[prev]
other = "Anterior"
[next]
other = "Següent"
[share_on]
other = "Compartir a"
[improve_this_page]
other = "Millorar aquesta pàgina"
[out_of]
other = "de"
[publications]
other = "Publicacions"
[taken_courses]
other = "Cursos realitzats"
[course_name]
other = "Nom del curs"
[total_credit]
other = "Crèdits Totals"
[obtained_credit]
other = "Crèdits Obtinguts"
[extracurricular_activities]
other = "Activitats Extracurriculars"
[show_more]
other = "Mostra'n més"
[show_less]
other = "Mostra'n menys"
[responsibilities]
other = "Responsabilitats:"
[present]
other = "Actualitat"
[comments_javascript]
other = "Si us plau, activa Javascript per mostrar"
[comments_by]
other = "Comentaris per"
[read]
other = "Llegir"
[project_star]
other = "Preferit"
[project_details]
other = "Detalls"
[err_404]
other = "La pàgina que està cercant encara no existeix."
[more]
other = "Més"
[view_certificate]
other = "Mostrar Certificat"
[notes]
other = "Notes"
[disclaimer_text]
other = "Avís de Responsabilitat"
[search]
other = "Cerca"
+1 -1
View File
@@ -87,7 +87,7 @@ other = "En savoir plus"
other = "Montrer moins" other = "Montrer moins"
[responsibilities] [responsibilities]
other = "Responsabilités :" other = "Responsabilitiés :"
[present] [present]
other = "Aujourd'hui" other = "Aujourd'hui"
+2 -2
View File
@@ -6,7 +6,7 @@ other = "Anasayfa"
other = "Gönderiler" other = "Gönderiler"
[toc_heading] [toc_heading]
other = "İçerik Tablosu" other = "İçerik Tablous"
[tags] [tags]
other = "Etiketler" other = "Etiketler"
@@ -108,7 +108,7 @@ other = "Star"
other = "Detaylar" other = "Detaylar"
[err_404] [err_404]
other = "Aradığınız sayfa bulunamadı." other = "Aradığınız sayfa bulunmamakta."
[more] [more]
other = "Devamını Göster" other = "Devamını Göster"
@@ -1 +0,0 @@
<a href="{{ .Destination | safeURL }}"{{ with .Title}} title="{{ . }}"{{ end }}{{ if strings.HasPrefix .Destination "http" }} target="_blank" rel="noopener"{{ end }}>{{ .Text | safeHTML }}</a>
+1 -1
View File
@@ -1,5 +1,5 @@
{{- $.Scratch.Add "index" slice -}} {{- $.Scratch.Add "index" slice -}}
{{- range (where .Site.RegularPages "Layout" "!=" "search") -}} {{- range .Site.RegularPages -}}
{{- $.Scratch.Add "index" (dict "title" .Title "hero" (partial "helpers/get-hero.html" .) "date" (.Date.Format "January 2, 2006") "summary" .Summary "tags" .Params.tags "categories" .Params.categories "contents" .Plain "permalink" .Permalink) -}} {{- $.Scratch.Add "index" (dict "title" .Title "hero" (partial "helpers/get-hero.html" .) "date" (.Date.Format "January 2, 2006") "summary" .Summary "tags" .Params.tags "categories" .Params.categories "contents" .Plain "permalink" .Permalink) -}}
{{- end -}} {{- end -}}
{{- $.Scratch.Get "index" | jsonify -}} {{- $.Scratch.Get "index" | jsonify -}}
+4
View File
@@ -55,3 +55,7 @@
</div> </div>
</section> </section>
{{ end }} {{ end }}
{{ define "scripts" }}
<script src="{{ "/js/list.js" | relURL }}"></script>
{{ end }}
+6
View File
@@ -66,3 +66,9 @@
</div> </div>
</section> </section>
{{ end }} {{ end }}
{{ define "scripts" }}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/3.2.0/fuse.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/jquery.mark.min.js"></script>
<script src="{{ "/js/search.js" | absURL }}"></script>
{{ end }}
+17 -6
View File
@@ -24,7 +24,7 @@
</form> </form>
<div class="sidebar-tree"> <div class="sidebar-tree">
<ul class="tree" id="tree"> <ul class="tree" id="tree">
<li id="list-heading"><a href="{{ "/posts/" | relLangURL }}" data-filter="all">{{ i18n "posts" }}</a></li> <li id="list-heading"><a href="{{ "/posts" | relLangURL }}" data-filter="all">{{ i18n "posts" }}</a></li>
<div class="subtree"> <div class="subtree">
{{ partial "navigators/sidebar.html" (dict "menuName" "sidebar" "menuItems" site.Menus.sidebar "ctx" .) }} {{ partial "navigators/sidebar.html" (dict "menuName" "sidebar" "menuItems" site.Menus.sidebar "ctx" .) }}
</div> </div>
@@ -54,11 +54,11 @@
<div class="title"> <div class="title">
<h1>{{ .Page.Title }}</h1> <h1>{{ .Page.Title }}</h1>
</div> </div>
{{ if site.Params.features.tags.enable }} {{ if site.Params.enableTags }}
<div class="taxonomy-terms"> <div class="taxonomy-terms">
<ul style="padding-left: 0;"> <ul style="padding-left: 0;">
{{ range .Params.tags }} {{ range .Params.tags }}
{{ $url:= printf "tags/%s/" . }} {{ $url:= printf "tags/%s" . }}
<li class="rounded"><a href="{{ $url | urlize | relLangURL }}" class="btn, btn-sm">{{ . }}</a></li> <li class="rounded"><a href="{{ $url | urlize | relLangURL }}" class="btn, btn-sm">{{ . }}</a></li>
{{ end }} {{ end }}
</ul> </ul>
@@ -158,7 +158,7 @@
<!----- Add comment support -----> <!----- Add comment support ----->
{{ if site.Params.features.comment.enable }} {{ if site.Params.features.comment.enable }}
{{ partial "comments.html" site.Params.features.comment.services }} {{ partial "comments.html" site.Params.features.comment }}
{{ end }} {{ end }}
<!-- Keep backward compatibility with old config.yaml --> <!-- Keep backward compatibility with old config.yaml -->
@@ -179,7 +179,7 @@
{{ define "toc" }} {{ define "toc" }}
<section class="toc-section" id="toc-section"> <section class="toc-section" id="toc-section">
{{ if and site.Params.features.toc.enable ( .Params.enableTOC | default true ) }} {{ if and site.Params.enableTOC ( .Params.enableTOC | default true ) }}
<div class="toc-holder"> <div class="toc-holder">
<h5 class="text-center pl-3">{{ i18n "toc_heading" }}</h5> <h5 class="text-center pl-3">{{ i18n "toc_heading" }}</h5>
<hr> <hr>
@@ -192,9 +192,20 @@
{{ end }} {{ end }}
{{ define "scripts" }} {{ define "scripts" }}
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/highlight.min.js"></script>
<script src="{{ "/js/single.js" | relURL }}"></script>
<script>
hljs.initHighlightingOnLoad();
</script>
<!-------------- Enable Math support for this page ----------------> <!-------------- Enable Math support for this page ---------------->
{{ if site.Params.features.math.enable }} {{ if .Params.math }}
{{ partial "math.html" . }} {{ partial "math.html" . }}
{{ end }} {{ end }}
<!-------------- Enable mermaid support for this page ---------------->
{{ if .Params.mermaid }}
{{ partial "mermaid.html" . }}
{{ end }}
{{ end }} {{ end }}
+4
View File
@@ -56,3 +56,7 @@
</div> </div>
</section> </section>
{{ end }} {{ end }}
{{ define "scripts" }}
<script src="{{ "/js/list.js" | relURL }}"></script>
{{ end }}
+6
View File
@@ -75,6 +75,12 @@
<!--- ADD COMMON SCRIPTS ---------------> <!--- ADD COMMON SCRIPTS --------------->
{{ partial "scripts.html" . }} {{ partial "scripts.html" . }}
<!--- ADD INDEX PAGE SPECIFIC SCRIPTS -->
<script src="{{ "/js/itype.min.js" | relURL }}"></script>
<script src="{{ "/js/github-button.js" | relURL }}"></script>
<script src="{{ "/js/home.js" | relURL }}"></script>
<script src="{{ "/js/jquery.filterizr.min.js" | relURL }}"></script>
<!------ ADD SUPPORT LINKS --------> <!------ ADD SUPPORT LINKS -------->
{{- partial "misc/support.html" . -}} {{- partial "misc/support.html" . -}}
+7 -1
View File
@@ -57,7 +57,13 @@
{{ end }} {{ end }}
{{ define "scripts" }} {{ define "scripts" }}
{{ if site.Params.features.math.enable }} <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/highlight.min.js"></script>
<script src="{{ "/js/imagesloaded.pkgd.min.js" | relURL }}"></script>
<script src="{{ "/js/note.js" | relURL }}"></script>
<script>
hljs.initHighlightingOnLoad();
</script>
{{ if .Params.math }}
{{ partial "math.html" . }} {{ partial "math.html" . }}
{{ end }} {{ end }}
{{ end }} {{ end }}
+7 -1
View File
@@ -47,7 +47,13 @@
{{ end }} {{ end }}
{{ define "scripts" }} {{ define "scripts" }}
{{ if site.Params.features.math.enable }} <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/highlight.min.js"></script>
<script src="{{ "/js/imagesloaded.pkgd.min.js" | relURL }}"></script>
<script src="{{ "/js/note.js" | relURL }}"></script>
<script>
hljs.initHighlightingOnLoad();
</script>
{{ if .Params.math }}
{{ partial "math.html" . }} {{ partial "math.html" . }}
{{ end }} {{ end }}
{{ end }} {{ end }}
+1 -3
View File
@@ -1,7 +1,6 @@
<!-- Add Analytics if enabled in configuration --> <!-- Add Analytics if enabled in configuration -->
{{ with site.Params.features.analytics }} {{ with site.Params.features.analytics }}
{{ if .enabled }} {{ if .enabled }}
{{ with .services }}
<!-- Google Analytics --> <!-- Google Analytics -->
{{ with .google }} {{ with .google }}
{{ $privacyConfig:= dict (slice "Site" "Config" "Privacy" "GoogleAnalytics") $.Site.Config.Privacy.GoogleAnalytics }} {{ $privacyConfig:= dict (slice "Site" "Config" "Privacy" "GoogleAnalytics") $.Site.Config.Privacy.GoogleAnalytics }}
@@ -22,7 +21,7 @@
<script <script
data-goatcounter="https://{{ .code }}.goatcounter.com/count" data-goatcounter="https://{{ .code }}.goatcounter.com/count"
async async
src="//gc.zgo.at/count.js" src="/js/goat-counter.js"
></script> ></script>
{{ end }} {{ end }}
@@ -43,7 +42,6 @@
})(); })();
</script> </script>
{{ end }} {{ end }}
{{ end }}
{{ end }} {{ end }}
{{ end }} {{ end }}
+1 -2
View File
@@ -42,9 +42,8 @@
{{ end }} {{ end }}
<div class="project-btn-holder"> <div class="project-btn-holder">
{{ if .repo }} {{ if .repo }}
<!-- Place this tag where you want the button to render. -->
<a <a
class="github-button project-btn d-none" class="github-button-inactive project-btn"
href="{{ .repo }}" href="{{ .repo }}"
data-icon="octicon-standard" data-icon="octicon-standard"
data-show-count="true" data-show-count="true"
+2 -3
View File
@@ -1,6 +1,6 @@
{{ with .valine }} {{ with .valine }}
<div id="vcomments"></div> <div id="vcomments"></div>
<script src="//code.bdstatic.com/npm/leancloud-storage@4.12.0/dist/av-min.js"></script> <script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
<script src="//unpkg.com/valine/dist/Valine.min.js"></script> <script src="//unpkg.com/valine/dist/Valine.min.js"></script>
<script type="text/javascript"> <script type="text/javascript">
new Valine({ new Valine({
@@ -13,7 +13,6 @@
lang: "{{ .lang }}", lang: "{{ .lang }}",
recordIP: "{{ .recordIP }}", recordIP: "{{ .recordIP }}",
enableQQ: "{{ .enableQQ }}", enableQQ: "{{ .enableQQ }}",
serverURLs: "https://{{ .serverURLs }}.api.lncldglobal.com"
}); });
</script> </script>
{{ end }} {{ end }}
+1 -1
View File
@@ -169,7 +169,7 @@
<form method='post' action='https://blogtrottr.com'> <form method='post' action='https://blogtrottr.com'>
<div class="form-group"> <div class="form-group">
<input type='email' class="form-control" name='btr_email' placeholder="{{ i18n "newsletter_input_placeholder" }}"/><br /> <input type='email' class="form-control" name='btr_email' placeholder="{{ i18n "newsletter_input_placeholder" }}"/><br />
<input type='hidden' name='btr_url' value='{{ "" | absLangURL }}/index.xml' /> <input type='hidden' name='btr_url' value='{{ "" | absLangURL }}index.xml' />
<input type='hidden' name='schedule_type' value='1' /> <input type='hidden' name='schedule_type' value='1' />
<small id="emailHelp" class="form-text text-muted">{{ i18n "newsletter_warning" }}</small> <small id="emailHelp" class="form-text text-muted">{{ i18n "newsletter_warning" }}</small>
<button type="submit" class="btn btn-info"> {{ i18n "submit" }} </button> <button type="submit" class="btn btn-info"> {{ i18n "submit" }} </button>
+5 -2
View File
@@ -7,14 +7,17 @@
<link rel="stylesheet" href="{{ "/css/layouts/main.css" | relURL }}"/> <link rel="stylesheet" href="{{ "/css/layouts/main.css" | relURL }}"/>
<link rel="stylesheet" href="{{ "/css/navigators/navbar.css" | relURL }}"/> <link rel="stylesheet" href="{{ "/css/navigators/navbar.css" | relURL }}"/>
<link rel="stylesheet" href="{{ "/css/plyr.css" | relURL }}"/> <link rel="stylesheet" href="{{ "/css/plyr.css" | relURL }}"/>
{{ if ne site.Params.features.flags.enable false }} {{ if ne site.Params.showFlags false }}
<link rel="stylesheet" href="{{ "/css/flag-icon.min.css" | relURL }}"/> <link rel="stylesheet" href="{{ "/css/flag-icon.min.css" | relURL }}"/>
{{ end }} {{ end }}
<!--=================== fonts ==============================--> <!--=================== fonts ==============================-->
<link rel="stylesheet" href="{{ "/google-fonts/Mulish/mulish.css" | relURL }}"/> <link rel="stylesheet" href="{{ "/google-fonts/Mulish/mulish.css" | relURL }}"/>
<!--=================== icons ==============================-->
<link rel="stylesheet" href="{{ "/fontawesome/css/all.min.css" | relURL }}"/>
<!--=================== dark mode ==========================--> <!--=================== dark mode ==========================-->
{{ if site.Params.features.darkMode.enable }} {{ if site.Params.darkMode.enable }}
<link rel="stylesheet" href="{{ "/css/colortheme/colortheme.css" | relURL }}"/> <link rel="stylesheet" href="{{ "/css/colortheme/colortheme.css" | relURL }}"/>
{{ end }} {{ end }}
+1 -1
View File
@@ -14,7 +14,7 @@
{{/* if the user specify a country code for a language via "params.flagOverwrites" field, then use it. */}} {{/* if the user specify a country code for a language via "params.flagOverwrites" field, then use it. */}}
{{ range site.Params.features.flags.flagOverwrites }} {{ range site.Params.flagOverwrites }}
{{ if eq $languageCode .languageCode }} {{ if eq $languageCode .languageCode }}
{{ $countryCode = .countryCode }} {{ $countryCode = .countryCode }}
{{ end }} {{ end }}
@@ -1,209 +0,0 @@
{{/*
## Overview
This helper returns options dictionary used to configure ESBuild.
The following configurations are set:
* Enable JS minification.
* Enable source map if not building for production.
* Prepare `process.env.<ENVIRONMENT VARIABLE>` defines based on enabled features.
This allows ESBuild to optimize JS bundle size by removing code related
to unused features.
* Added `process-shim.js` so `process.env` is defined.
This way we don't have to explicitly specify every environment
variable via `defines` value.
* Prepare `params` for feature and service configs used in JS.
For more details on ESBuild configuration, see: https://gohugo.io/hugo-pipes/js/
## Detailed Concepts
### `feature` and `service`
Features configured in site wide `config.yml` file under `params.features` section.
A **feature** provides a certain functionality to the user via one or more services.
A feature be can enabled or disabled.
A **service** is a 3rd party service, or JS library that implements a feature.
For example, `analytics` is considered a feature.
There are many services that can provide this feature, to name a few:
* Google Analytics
* Counter.Dev
* GoatCounter
To maximize extendibility and therefore usefulness as an open source project,
it is important to define a standard interface that is easy to understand,
configure, and extend.
In this file, I took the liberty of standardizing this interface under `params.features`.
Please note that this breaks compatibility with previous versions of `config.yaml`.
I will provide sample `config.yaml` files with fully documented features, as well as
documentation on migrating the `config.yaml` file to the new standard.
Here is a sample config file for the new `params.features` section. Notice that each `service`
is a dictionary with `enable` and `services` key. `services` is a dictionary with each key
corresponding to a concrete service, and value as configuration / settings. In the case of
services that need no configuration, an empty dictionary is created.
```yml
params:
features:
# This is the `analytics` feature
analytics:
# This feature is enabled
enable: true
# List of services to enable
services:
# Google Analytics is enabled
google:
# settings for Google Analytics
id: G-xxxxx
# # Counter Dev is disabled
# counterDev:
# id: foo
# name: bar
# The `darkMode` feature
darkmode:
enable: true
services:
# darkmode is realized by using DarkReader library
darkreader:
# options are 'system', 'dark', 'light'
defaultColorScheme: system
# For all available options, see `interface DynamicThemeFix`:
# https://github.com/darkreader/darkreader/blob/main/index.d.ts#L125
fixes:
invert: ['img[src$=".svg"]'] # inverts svg colors.
# For all available options, see `interface Theme` in:
# https://github.com/darkreader/darkreader/blob/main/index.d.ts#L45
theme:
brightness: 100
contrast: 100
sepia: 0
```
This helper will convert the above config into the following env vars:
* `FEATURE_ANALYTICS=1`
* `FEATURE_ANALYTICS_GOOGLE=1`
* `FEATURE_DARKMODE=1`
* `FEATURE_DARKMODE_DARKREADER=1`
In JS, you can use it like this:
```js
import * as params from '@params';
if (process.env.FEATURE_ANALYTICS) {
// Do things to enable this feature here
if (process.env.FEATURE_ANALYTICS_GOOGLE) {
// Do things things to enable google analytics
}
}
```
You can also access service configs via params:
```js
import * as params from '@params';
console.log(params);
```
You will see console output like below. Note, each service configuration is
namespaced by their corresponding feature.
```json
{
"analytics": {
"google": {
"id": "G-xxxxx"
}
},
"darkmode": {
"darkreader": {
"defaultColorScheme": "system",
"fixes": {
"invert": "['img[src$=\".svg\"]']"
},
"theme": {
"brightness": 100,
"contrast": 100,
"sepia": 0
}
}
}
}
```
*/}}
{{/* Holds all the feature flag environment variables for `process.env.*` in JS land */}}
{{ $defines := dict }}
{{/* Holds all the feature configuration variables exposed to JS side */}}
{{ $params := dict }}
{{/* set NODE_ENV depending on if we are building for production use. */}}
{{ $defines = $defines | merge (dict
"process.env.NODE_ENV" (cond hugo.IsProduction `"production"` `"development"` )
)}}
{{/* Go through each feature defined in our config.yml/config.toml/config.json file. */}}
{{ range $feature, $featureDef := site.Params.features }}
{{/* Initialize a dictionary that will hold all service configs for this specific feature */}}
{{ $featureParams := dict }}
{{ with $featureDef }}
{{/* convert feature name to uppercase and remove '_', e.g. `darkMode` becomes `DARKMODE` */}}
{{ $featureName := replace $feature "_" "" | upper }}
{{/* The feature is enabled if the `enable` key is absent, or is set to `true` */}}
{{ $featureEnabled := or (not (isset . "enable")) .enable }}
{{/* Sets `FEATURE_<FEATURE_NAME>` env var to "1" or "0" depending on if the feature is enabled. */}}
{{ $defines = $defines | merge (dict
(printf "process.env.FEATURE_%s" $featureName) (cond $featureEnabled `'1'` `'0'`)
) }}
{{ if $featureEnabled }}
{{/* Loop through each service under this feature */}}
{{ range $service, $config := .services }}
{{/*
We assume all services are enabled. To disable a service,
simply comment it out from `config.yaml`.
*/}}
{{/* Convert name to all uppercase, removing underscore */}}
{{ $serviceName := replace $service "_" "" | upper }}
{{/* let JS side know this service is enabled */}}
{{ $defines = $defines | merge (dict
(printf "process.env.FEATURE_%s_%s" $featureName $serviceName) `'1'`
) }}
{{/* add service configuration to feature params */}}
{{ $featureParams = $featureParams | merge (dict $service $config) }}
{{ end }}
{{/* add feature params to top level params */}}
{{ $params = $params | merge (dict $feature $featureParams) }}
{{ end }}
{{ end }}
{{ end }}
{{
return dict
"defines" $defines
"params" $params
"minify" true
"sourceMap" (cond hugo.IsProduction "" "inline")
"inject" "scripts/process-shim.js"
}}
+1 -6
View File
@@ -3,12 +3,7 @@
{{/* if hero image is specified in the page front-matter, then use that */}} {{/* if hero image is specified in the page front-matter, then use that */}}
{{ if .Params.hero }} {{ if .Params.hero }}
{{/* try to read from the page bundle */}} {{ $heroImage = resources.Get .Params.hero }}
{{ $heroImage = .Resources.Get .Params.hero }}
{{/* if the image does not exist in the page bundle,try looking in the assets folder */}}
{{ if not $heroImage }}
{{ $heroImage = resources.Get .Params.hero }}
{{ end }}
{{ end }} {{ end }}
{{ .Scratch.Set "heroScratch" $heroImage }} {{ .Scratch.Set "heroScratch" $heroImage }}
@@ -1,5 +0,0 @@
{{- $options := partial "helpers/get-esbuild-options.html" -}}
{{- $options = $options | merge (dict "targetPath" "application.js") -}}
{{- $app := resources.Get "scripts/application.js" -}}
{{- $bundle := $app | js.Build $options | fingerprint -}}
<script src="{{ $bundle.RelPermalink }}" integrity="{{ $bundle.Data.Integrity }}" defer></script>
+14
View File
@@ -1 +1,15 @@
<link rel="stylesheet" href="{{ "/katex/katex.min.css" | relURL }}"> <link rel="stylesheet" href="{{ "/katex/katex.min.css" | relURL }}">
<script type="text/javascript" defer src="{{ "/katex/katex.min.js" | relURL }}"></script>
<script type="text/javascript" defer src="{{ "/katex/auto-render.min.js" | relURL }}" onload="renderMathInElement(document.body);">
renderMathInElement(
document.body,
{
delimiters: [
{left: "$$", right: "$$", display: true},
{left: "\\[", right: "\\]", display: true},
{left: "$", right: "$", display: false},
{left: "\\(", right: "\\)", display: false}
]
}
);
</script>
+6
View File
@@ -0,0 +1,6 @@
<script src="{{ "/js/mermaid-8.14.0.min.js" | relURL }}"></script>
<script>
mermaid.initialize({
startOnLoad:true
});
</script>
+1 -7
View File
@@ -1,6 +1,5 @@
{{ with site.Params.features.support }} {{ with site.Params.features.support }}
{{ if .enable }} {{ if .enabled }}
{{ with .services }}
<!-- Enable Ko-Fi floating button --> <!-- Enable Ko-Fi floating button -->
{{ with .kofi }} {{ with .kofi }}
<script src='https://storage.ko-fi.com/cdn/scripts/overlay-widget.js'></script> <script src='https://storage.ko-fi.com/cdn/scripts/overlay-widget.js'></script>
@@ -13,10 +12,5 @@
}); });
</script> </script>
{{ end }} {{ end }}
<!-- Enable Buy Me a Coffee (buymeacoffee.com) floating button -->
{{ with .buymeacoffee }}
<script data-name="BMC-Widget" data-cfasync="false" src="https://cdnjs.buymeacoffee.com/1.0.0/widget.prod.min.js" data-id="{{ .user }}" data-description="{{ .text }}" data-message="{{ .info }}" data-color="{{ .color }}" data-position="Right" data-x_margin="10" data-y_margin="18"></script>
{{ end }}
{{ end }}
{{ end }} {{ end }}
{{ end }} {{ end }}
@@ -5,7 +5,7 @@
<div class="dropdown languageSelector"> <div class="dropdown languageSelector">
<a class="btn dropdown-toggle" href="#" id="languageSelector" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <a class="btn dropdown-toggle" href="#" id="languageSelector" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{ if ne site.Params.features.flags.enable false }} {{ if ne site.Params.showFlags false }}
{{ $countryCode := partial "helpers/country-code.html" . }} {{ $countryCode := partial "helpers/country-code.html" . }}
<span class="flag-icon flag-icon-{{$countryCode}}"></span> <span class="flag-icon flag-icon-{{$countryCode}}"></span>
{{ end }} {{ end }}
@@ -14,7 +14,7 @@
<div class="dropdown-menu" aria-labelledby="languageSelector"> <div class="dropdown-menu" aria-labelledby="languageSelector">
{{ range .Translations }} {{ range .Translations }}
<a class="dropdown-item nav-link languages-item" href="{{ path.Join "/" (cond (eq .Language.Lang "en") "" .Language.Lang) $pageURL }}"> <a class="dropdown-item nav-link languages-item" href="{{ path.Join "/" (cond (eq .Language.Lang "en") "" .Language.Lang) $pageURL }}">
{{ if ne site.Params.features.flags.enable false }} {{ if ne site.Params.showFlags false }}
{{ $countryCode := partial "helpers/country-code.html" . }} {{ $countryCode := partial "helpers/country-code.html" . }}
<span class="flag-icon flag-icon-{{$countryCode}}"></span> <span class="flag-icon flag-icon-{{$countryCode}}"></span>
{{ end }} {{ end }}
@@ -5,7 +5,7 @@
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="languageSelector" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <a class="nav-link dropdown-toggle" href="#" id="languageSelector" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{ if ne site.Params.features.flags.enable false }} {{ if ne site.Params.showFlags false }}
{{ $countryCode := partial "helpers/country-code.html" . }} {{ $countryCode := partial "helpers/country-code.html" . }}
<span class="flag-icon flag-icon-{{$countryCode}}"></span> <span class="flag-icon flag-icon-{{$countryCode}}"></span>
{{ end }} {{ end }}
@@ -14,7 +14,7 @@
<div class="dropdown-menu" aria-labelledby="languageSelector"> <div class="dropdown-menu" aria-labelledby="languageSelector">
{{ range .Translations }} {{ range .Translations }}
<a class="dropdown-item nav-link languages-item" href="{{ path.Join "/" (cond (eq .Language.Lang "en") "" .Language.Lang) $pageURL }}"> <a class="dropdown-item nav-link languages-item" href="{{ path.Join "/" (cond (eq .Language.Lang "en") "" .Language.Lang) $pageURL }}">
{{ if ne site.Params.features.flags.enable false }} {{ if ne site.Params.showFlags false }}
{{ $countryCode := partial "helpers/country-code.html" . }} {{ $countryCode := partial "helpers/country-code.html" . }}
<span class="flag-icon flag-icon-{{$countryCode}}"></span> <span class="flag-icon flag-icon-{{$countryCode}}"></span>
{{ end }} {{ end }}
@@ -1,6 +1,6 @@
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="languageSelector" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <a class="nav-link dropdown-toggle" href="#" id="languageSelector" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{ if ne site.Params.features.flags.enable false }} {{ if ne site.Params.showFlags false }}
{{ $countryCode := partial "helpers/country-code.html" . }} {{ $countryCode := partial "helpers/country-code.html" . }}
<span class="flag-icon flag-icon-{{$countryCode}}"></span> <span class="flag-icon flag-icon-{{$countryCode}}"></span>
{{ end }} {{ end }}
@@ -9,7 +9,7 @@
<div class="dropdown-menu" aria-labelledby="languageSelector"> <div class="dropdown-menu" aria-labelledby="languageSelector">
{{ range site.Home.AllTranslations }} {{ range site.Home.AllTranslations }}
<a class="dropdown-item nav-link languages-item" href="{{ .RelPermalink }}"> <a class="dropdown-item nav-link languages-item" href="{{ .RelPermalink }}">
{{ if ne site.Params.features.flags.enable false }} {{ if ne site.Params.showFlags false }}
{{ $countryCode := partial "helpers/country-code.html" . }} {{ $countryCode := partial "helpers/country-code.html" . }}
<span class="flag-icon flag-icon-{{$countryCode}}"></span> <span class="flag-icon flag-icon-{{$countryCode}}"></span>
{{ end }} {{ end }}
+3 -3
View File
@@ -29,7 +29,7 @@
<nav class="navbar navbar-expand-xl top-navbar final-navbar shadow"> <nav class="navbar navbar-expand-xl top-navbar final-navbar shadow">
<div class="container"> <div class="container">
<button class="navbar-toggler navbar-light" id="sidebar-toggler" type="button"> <button class="navbar-toggler navbar-light" id="sidebar-toggler" type="button" onclick="toggleSidebar()">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
<a class="navbar-brand" href="{{ site.BaseURL | relLangURL }}"> <a class="navbar-brand" href="{{ site.BaseURL | relLangURL }}">
@@ -38,7 +38,7 @@
{{ end }} {{ end }}
{{- site.Title -}} {{- site.Title -}}
</a> </a>
<button class="navbar-toggler navbar-light" id="toc-toggler" type="button"> <button class="navbar-toggler navbar-light" id="toc-toggler" type="button" onclick="toggleTOC()">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
@@ -47,7 +47,7 @@
{{ if .IsTranslated }} {{ if .IsTranslated }}
{{ partial "navigators/lang-selector-2.html" . }} {{ partial "navigators/lang-selector-2.html" . }}
{{ end }} {{ end }}
{{ if site.Params.features.darkMode.enable }} {{ if site.Params.darkMode.enable }}
{{ partial "navigators/theme-selector.html" . }} {{ partial "navigators/theme-selector.html" . }}
{{ end }} {{ end }}
</ul> </ul>
+3 -3
View File
@@ -106,12 +106,12 @@
{{ end }} {{ end }}
{{ if $blogEnabled }} {{ if $blogEnabled }}
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" id="blog-link" href="{{ "/posts/" | relLangURL }}">{{ i18n "posts" }}</a> <a class="nav-link" id="blog-link" href="{{ "/posts" | relLangURL }}">{{ i18n "posts" }}</a>
</li> </li>
{{ end }} {{ end }}
{{ if $notesEnabled }} {{ if $notesEnabled }}
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" id="note-link" href="{{ "/notes/" | relLangURL }}">{{ i18n "notes" }}</a> <a class="nav-link" id="note-link" href="{{ "/notes" | relLangURL }}">{{ i18n "notes" }}</a>
</li> </li>
{{ end }} {{ end }}
{{ range $customMenus }} {{ range $customMenus }}
@@ -124,7 +124,7 @@
{{ if .IsTranslated }} {{ if .IsTranslated }}
{{ partial "navigators/lang-selector.html" . }} {{ partial "navigators/lang-selector.html" . }}
{{ end }} {{ end }}
{{ if site.Params.features.darkMode.enable }} {{ if site.Params.darkMode.enable }}
{{ partial "navigators/theme-selector.html" . }} {{ partial "navigators/theme-selector.html" . }}
{{ end }} {{ end }}
</ul> </ul>
+1 -1
View File
@@ -17,6 +17,6 @@
</li> </li>
{{ else }} {{ else }}
<!-- No sub-tree. So, only add current entry --> <!-- No sub-tree. So, only add current entry -->
<li><a class="{{$class}}" href="{{ .PageRef | default .URL }}" title="{{ .Name }}">{{.Name}}</a></li> <li><a class="{{$class}}" href="{{ .URL }}" title="{{ .Name }}">{{.Name}}</a></li>
{{ end }} {{ end }}
{{ end }} {{ end }}

Some files were not shown because too many files have changed in this diff Show More