├── .dictionary ├── .github └── settings.yml ├── .gitignore ├── .gitsv └── config.yml ├── .htmlvalidate.json ├── .jsbeautifyrc ├── .lighthouserc.yml ├── .lycheeignore ├── .markdownlint.yml ├── .npmrc ├── .nvmrc ├── .prettierignore ├── .prettierrc ├── .tarignore ├── .woodpecker ├── build-package.yml ├── docs.yml ├── notify.yml └── test.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── eslint.config.js ├── exampleSite ├── archetypes │ └── default.md ├── assets │ └── sprites │ │ └── regular.svg ├── config │ ├── _default │ │ ├── config.yaml │ │ └── params.yaml │ └── ci │ │ └── params.yaml ├── content │ ├── _includes │ │ └── include-page.md │ ├── about │ │ ├── images │ │ │ └── avatar.jpg │ │ └── index.md │ └── posts │ │ ├── advanced │ │ ├── includes.md │ │ ├── shortcodes.md │ │ └── toc.md │ │ ├── asciidoc │ │ ├── admonition-icons.adoc │ │ └── admonitions.adoc │ │ ├── avatar-images │ │ ├── images │ │ │ └── avatar.jpg │ │ └── index.md │ │ ├── features │ │ ├── authors.md │ │ ├── code-blocks.md │ │ ├── dark-mode │ │ │ ├── images │ │ │ │ └── geekblog-dark.png │ │ │ └── index.md │ │ ├── icon-sets.md │ │ ├── sticky.md │ │ └── theming │ │ │ ├── images │ │ │ └── theme-example.png │ │ │ └── index.md │ │ ├── markdown.md │ │ ├── post-short.md │ │ ├── post-with-images │ │ ├── images │ │ │ ├── feature.jpg │ │ │ ├── forest-1.jpg │ │ │ ├── forest-2.jpg │ │ │ ├── forest-3.jpg │ │ │ ├── forest-4.jpg │ │ │ ├── forest-5.jpg │ │ │ ├── forest-6.jpg │ │ │ ├── forest-7.jpg │ │ │ └── forest-8.svg │ │ └── index.md │ │ └── usage │ │ ├── configuration.md │ │ ├── getting-started.md │ │ └── menus.md ├── data │ ├── authors │ │ ├── Special User.yml │ │ ├── john-doe.yml │ │ └── richard-roe.yml │ ├── menu │ │ └── extra.yml │ └── properties │ │ ├── demo.yaml │ │ ├── shortcode-avatar.yaml │ │ ├── shortcode-boxes.yaml │ │ ├── shortcode-buttons.yaml │ │ ├── shortcode-columns.yaml │ │ ├── shortcode-hints.yaml │ │ ├── shortcode-images.yaml │ │ ├── shortcode-includes.yaml │ │ ├── shortcode-katex.yaml │ │ ├── shortcode-mermaid.yaml │ │ ├── shortcode-progress.yaml │ │ └── shortcode-propertylist.yaml ├── layouts │ └── shortcodes │ │ └── sprites.html └── static │ ├── _includes │ ├── example.html.part │ └── example.md.part │ ├── custom.css │ ├── custom.css.example │ ├── socialmedia.svg │ └── socialmedia2.png ├── images ├── readme.png ├── screenshot.png └── tn.png ├── layouts ├── 404.html ├── _default │ ├── _markup │ │ ├── render-codeblock-mermaid.html │ │ ├── render-heading.html │ │ ├── render-image.html │ │ └── render-link.html │ ├── baseof.html │ ├── list.atom.xml │ ├── list.html │ ├── list.json.json │ ├── single.html │ ├── sitemap.xml │ └── terms.html ├── partials │ ├── head │ │ ├── custom.html │ │ ├── favicons.html │ │ ├── meta.html │ │ ├── microformats.html │ │ ├── others.html │ │ └── rel-me.html │ ├── menu-extra.html │ ├── metadata.html │ ├── microformats │ │ ├── opengraph.html │ │ ├── schema.html │ │ └── twitter_cards.html │ ├── pagination.html │ ├── site-footer.html │ ├── site-header.html │ ├── svg-sprites.html │ └── utils │ │ ├── content.html │ │ ├── description.html │ │ ├── featured.html │ │ └── title.html ├── robots.txt └── shortcodes │ ├── avatar.html │ ├── box.html │ ├── boxes.html │ ├── button.html │ ├── columns.html │ ├── emojify.html │ ├── expand.html │ ├── hint.html │ ├── icon.html │ ├── img.html │ ├── include.html │ ├── katex.html │ ├── mermaid.html │ ├── progress.html │ ├── propertylist.html │ ├── tab.html │ ├── tabs.html │ └── toc.html ├── package-lock.json ├── package.json ├── renovate.json ├── src ├── icons │ ├── arrow_back.svg │ ├── arrow_left.svg │ ├── arrow_right.svg │ ├── bitbucket.svg │ ├── bookmark.svg │ ├── brightness_auto.svg │ ├── brightness_dark.svg │ ├── brightness_light.svg │ ├── check.svg │ ├── check_circle_outline.svg │ ├── clear.svg │ ├── cloud_off.svg │ ├── code.svg │ ├── contacts.svg │ ├── copy.svg │ ├── create.svg │ ├── dangerous.svg │ ├── date.svg │ ├── download.svg │ ├── email.svg │ ├── error_outline.svg │ ├── fire.svg │ ├── git.svg │ ├── gitea.svg │ ├── github.svg │ ├── gitlab.svg │ ├── heart.svg │ ├── info_outline.svg │ ├── keyboard_arrow_down.svg │ ├── keyboard_arrow_left.svg │ ├── keyboard_arrow_right.svg │ ├── keyboard_arrow_up.svg │ ├── link.svg │ ├── mastodon.svg │ ├── matrix.svg │ ├── menu.svg │ ├── notifications.svg │ ├── person.svg │ ├── pin.svg │ ├── rss_feed.svg │ ├── search.svg │ ├── security.svg │ ├── star.svg │ ├── tag.svg │ ├── timer.svg │ ├── tree.svg │ └── xmpp.svg ├── js │ ├── colorTheme.js │ ├── config.js │ ├── index.js │ ├── katex.js │ └── mermaid.js ├── sass │ ├── _asciidoc.scss │ ├── _base.scss │ ├── _chroma_base.scss │ ├── _chroma_dark.scss │ ├── _chroma_light.scss │ ├── _color_mode.scss │ ├── _defaults.scss │ ├── _fonts.scss │ ├── _markdown.scss │ ├── _mobile.scss │ ├── _normalize.css │ ├── _print.scss │ ├── _shortcodes.scss │ ├── _utils.scss │ ├── main.scss │ ├── mobile.scss │ └── print.scss └── static │ ├── brand.svg │ ├── custom.css │ ├── favicon │ └── favicon.svg │ └── fonts │ ├── LiberationMono.woff │ ├── LiberationMono.woff2 │ ├── LiberationSans-Bold.woff │ ├── LiberationSans-Bold.woff2 │ ├── LiberationSans-BoldItalic.woff │ ├── LiberationSans-BoldItalic.woff2 │ ├── LiberationSans-Italic.woff │ ├── LiberationSans-Italic.woff2 │ ├── LiberationSans.woff │ ├── LiberationSans.woff2 │ ├── Metropolis.woff │ └── Metropolis.woff2 ├── svgsprite.config.json ├── theme.toml ├── webpack.config.js └── webpack.plugins.js /.dictionary: -------------------------------------------------------------------------------- 1 | [G|g]eekblog 2 | hugo-book 3 | Kaussow 4 | DevOps 5 | glyphs 6 | Gopherfest 7 | (B|b)lockquote[s]? 8 | backticks 9 | (S|s)hortcode[s]? 10 | emojify 11 | img 12 | JSON 13 | SVG 14 | YAML 15 | pre-build 16 | submodule 17 | GPL 18 | IcoMoon 19 | FontAwesome 20 | macOS 21 | ok 22 | toc 23 | ToC 24 | relref 25 | href 26 | KaTeX 27 | katex 28 | Emojify 29 | Netlify 30 | Makefile 31 | prebuilt 32 | (S|s)ubdirector(ies|y) 33 | (M|m)inify 34 | whitespace 35 | Theming 36 | Favicon[s]? 37 | webpack 38 | pre-processor[s]? 39 | Asciidoc 40 | -------------------------------------------------------------------------------- /.github/settings.yml: -------------------------------------------------------------------------------- 1 | repository: 2 | name: hugo-geekblog 3 | description: Hugo theme made for blogs 4 | homepage: https://hugo-geekblog.geekdocs.de 5 | topics: hugo, theme, hugo-theme, blog 6 | 7 | private: false 8 | has_issues: true 9 | has_projects: false 10 | has_wiki: false 11 | has_downloads: true 12 | 13 | default_branch: main 14 | 15 | allow_squash_merge: true 16 | allow_merge_commit: true 17 | allow_rebase_merge: true 18 | 19 | labels: 20 | - name: bug 21 | color: d73a4a 22 | description: Something isn't working 23 | - name: documentation 24 | color: 0075ca 25 | description: Improvements or additions to documentation 26 | - name: duplicate 27 | color: cfd3d7 28 | description: This issue or pull request already exists 29 | - name: enhancement 30 | color: a2eeef 31 | description: New feature or request 32 | - name: good first issue 33 | color: 7057ff 34 | description: Good for newcomers 35 | - name: help wanted 36 | color: 008672 37 | description: Extra attention is needed 38 | - name: invalid 39 | color: e4e669 40 | description: This doesn't seem right 41 | - name: question 42 | color: d876e3 43 | description: Further information is requested 44 | - name: wontfix 45 | color: ffffff 46 | description: This will not be worked on 47 | 48 | branches: 49 | - name: main 50 | protection: 51 | required_pull_request_reviews: null 52 | required_status_checks: 53 | strict: false 54 | contexts: 55 | - ci/woodpecker/pr/test 56 | - ci/woodpecker/pr/build-package 57 | - ci/woodpecker/pr/docs 58 | enforce_admins: false 59 | required_linear_history: true 60 | restrictions: null 61 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # local environments 2 | .swp 3 | .env* 4 | /dist/ 5 | /build/ 6 | /node_modules/ 7 | /lhci_reports/ 8 | /exampleSite/themes/ 9 | /exampleSite/public/ 10 | CHANGELOG.md 11 | .hugo_build.lock 12 | 13 | # auto-generated files 14 | /data/ 15 | /static/ 16 | /assets/sprites/ 17 | /resources/ 18 | /exampleSite/resources/ 19 | /exampleSite/data/sprites/ 20 | VERSION 21 | 22 | # testing 23 | .lighthouseci/ 24 | -------------------------------------------------------------------------------- /.gitsv/config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: "1.1" 3 | 4 | versioning: 5 | update-major: [] 6 | update-minor: [feat] 7 | update-patch: [fix, perf, refactor, chore, test, ci, docs] 8 | 9 | tag: 10 | pattern: "v%d.%d.%d" 11 | 12 | release-notes: 13 | sections: 14 | - name: Features 15 | commit-types: [feat] 16 | section-type: commits 17 | - name: Bug Fixes 18 | commit-types: [fix] 19 | section-type: commits 20 | - name: Performance Improvements 21 | commit-types: [perf] 22 | section-type: commits 23 | - name: Code Refactoring 24 | commit-types: [refactor] 25 | section-type: commits 26 | - name: Others 27 | commit-types: [chore] 28 | section-type: commits 29 | - name: Testing 30 | commit-types: [test] 31 | section-type: commits 32 | - name: CI Pipeline 33 | commit-types: [ci] 34 | section-type: commits 35 | - name: Documentation 36 | commit-types: [docs] 37 | section-type: commits 38 | - name: BREAKING CHANGES 39 | section-type: breaking-changes 40 | 41 | commit-message: 42 | footer: 43 | issue: 44 | key: issue 45 | add-value-prefix: "#" 46 | issue: 47 | regex: "#?[0-9]+" 48 | -------------------------------------------------------------------------------- /.htmlvalidate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["html-validate:standard"], 3 | "rules": { 4 | "element-required-content": "off", 5 | "element-permitted-content": "off", 6 | "no-raw-characters": "off" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.jsbeautifyrc: -------------------------------------------------------------------------------- 1 | { 2 | "indent_size": 4, 3 | "indent_char": " ", 4 | "preserve_newlines": false, 5 | "unformatted" : ["svg"], 6 | "content_unformatted": ["pre"], 7 | "extra_liners": ["head", "body", "html", "main", "header", "footer", "section"] 8 | } 9 | -------------------------------------------------------------------------------- /.lighthouserc.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ci: 3 | collect: 4 | numberOfRuns: 3 5 | staticDistDir: exampleSite/public 6 | url: 7 | - http://localhost/ 8 | - http://localhost/404.html 9 | - http://localhost/posts/usage/getting-started/ 10 | settings: 11 | chromeFlags: "--no-sandbox --headless --disable-dev-shm-usage" 12 | onlyCategories: ["performance", "accessibility", "best-practices", "seo"] 13 | skipAudits: 14 | [ 15 | "color-contrast", 16 | "uses-long-cache-ttl", 17 | "csp-xss", 18 | "bf-cache", 19 | "is-crawlable", 20 | "image-size-responsive", 21 | "render-blocking-resources", 22 | "largest-contentful-paint" 23 | ] 24 | assert: 25 | preset: "lighthouse:no-pwa" 26 | assertions: 27 | color-contrast: off 28 | uses-long-cache-ttl: off 29 | csp-xss: off 30 | # FIXME: https://github.com/GoogleChrome/lighthouse/issues/14957 31 | bf-cache: off 32 | is-crawlable: off 33 | image-size-responsive: off 34 | render-blocking-resources: off 35 | largest-contentful-paint: off 36 | total-byte-weight: warn 37 | identical-links-same-purpose: warn 38 | tap-targets: warn 39 | unsized-images: warn 40 | # FIXME: https://github.com/GoogleChrome/lighthouse/issues/11460 41 | categories:performance: 42 | - warn 43 | - minScore: 0.95 44 | categories:accessibility: 45 | - error 46 | - minScore: 1 47 | categories:seo: 48 | - error 49 | - minScore: 0.95 50 | upload: 51 | target: filesystem 52 | outputDir: lhci_reports 53 | -------------------------------------------------------------------------------- /.lycheeignore: -------------------------------------------------------------------------------- 1 | https://github.com/thegeeklab/.+/edit/main/.* 2 | https://unsplash.com.* 3 | https://www.color-hex.com.* 4 | https://hugo-geekblog.geekdocs.de/ 5 | -------------------------------------------------------------------------------- /.markdownlint.yml: -------------------------------------------------------------------------------- 1 | --- 2 | default: True 3 | MD013: False 4 | MD041: False 5 | MD042: False 6 | MD004: 7 | style: dash 8 | MD010: 9 | code_blocks: False 10 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | loglevel=error 2 | fund=false 3 | engine-strict=true 4 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | lts/* 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | search*.js 2 | _normalize.css 3 | list.json.json 4 | /.lighthouseci/ 5 | /themes/ 6 | /static/js/ 7 | /src/favicon/ 8 | LICENSE 9 | **/*.html 10 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 99, 3 | "singleQuote": false, 4 | "semi": false, 5 | "trailingComma": "none" 6 | } 7 | -------------------------------------------------------------------------------- /.tarignore: -------------------------------------------------------------------------------- 1 | .envrc 2 | .npmrc 3 | .tarignore 4 | .dictionary* 5 | .git* 6 | .woodpecker* 7 | .lighthouse* 8 | .markdownlint* 9 | .jsbeautify* 10 | .prettier* 11 | .eslintrc* 12 | .htmlvalidate* 13 | .lycheeignore* 14 | example* 15 | webpack* 16 | svgsprite* 17 | package* 18 | node* 19 | local* 20 | dist 21 | src 22 | build 23 | renovate* 24 | resources 25 | CONTRIBUTING.md 26 | -------------------------------------------------------------------------------- /.woodpecker/build-package.yml: -------------------------------------------------------------------------------- 1 | --- 2 | when: 3 | - event: [pull_request, tag] 4 | - event: [push, manual] 5 | branch: 6 | - ${CI_REPO_DEFAULT_BRANCH} 7 | 8 | steps: 9 | - name: assets 10 | image: docker.io/library/node:lts 11 | commands: 12 | - npm install --quiet --no-progress 13 | - npm run build 14 | - cat VERSION 15 | environment: 16 | FORCE_COLOR: "true" 17 | 18 | - name: package 19 | image: docker.io/library/node:lts 20 | commands: 21 | - npm run pack 22 | environment: 23 | FORCE_COLOR: "true" 24 | 25 | - name: checksum 26 | image: quay.io/thegeeklab/alpine-tools 27 | commands: 28 | - cd dist/ && sha256sum * > ../sha256sum.txt 29 | 30 | - name: changelog 31 | image: quay.io/thegeeklab/git-sv 32 | commands: 33 | - git sv current-version 34 | - git sv release-notes -t ${CI_COMMIT_TAG:-next} -o CHANGELOG.md 35 | - cat CHANGELOG.md 36 | 37 | - name: publish-github 38 | image: docker.io/plugins/github-release 39 | settings: 40 | api_key: 41 | from_secret: github_token 42 | files: 43 | - dist/* 44 | - sha256sum.txt 45 | note: CHANGELOG.md 46 | overwrite: true 47 | title: ${CI_COMMIT_TAG} 48 | when: 49 | - event: [tag] 50 | 51 | depends_on: 52 | - test 53 | -------------------------------------------------------------------------------- /.woodpecker/docs.yml: -------------------------------------------------------------------------------- 1 | --- 2 | when: 3 | - event: [pull_request, tag] 4 | - event: [push, manual] 5 | branch: 6 | - ${CI_REPO_DEFAULT_BRANCH} 7 | 8 | steps: 9 | - name: markdownlint 10 | image: quay.io/thegeeklab/markdownlint-cli 11 | commands: 12 | - markdownlint 'exampleSite/content/**/*.md' 'README.md' 'CONTRIBUTING.md' 13 | 14 | - name: spellcheck 15 | image: quay.io/thegeeklab/alpine-tools 16 | commands: 17 | - spellchecker --files 'exampleSite/content/**/*.md' 'README.md' -d .dictionary -p spell indefinite-article syntax-urls frontmatter --frontmatter-keys title 18 | environment: 19 | FORCE_COLOR: "true" 20 | 21 | - name: assets 22 | image: docker.io/library/node:lts 23 | commands: 24 | - npm install --quiet --no-progress 25 | - npm run svg-sprite-list 26 | - mkdir -p exampleSite/themes/${CI_REPO_NAME} 27 | - curl -sSL https://github.com/${CI_REPO}/releases/latest/download/${CI_REPO_NAME}.tar.gz | tar -xz -C exampleSite/themes/${CI_REPO_NAME}/ --strip-components=1 28 | when: 29 | - event: [tag] 30 | - event: [push, manual] 31 | branch: 32 | - ${CI_REPO_DEFAULT_BRANCH} 33 | 34 | - name: assets-main 35 | image: docker.io/library/node:lts 36 | commands: 37 | - npm install --quiet --no-progress 38 | - npm run build 39 | - npm run svg-sprite-list 40 | - mkdir -p exampleSite/themes/ && ln -s $(pwd)/ exampleSite/themes/${CI_REPO_NAME} 41 | environment: 42 | FORCE_COLOR: "true" 43 | when: 44 | - event: [pull_request] 45 | 46 | - name: build 47 | image: quay.io/thegeeklab/hugo:0.147 48 | commands: 49 | - hugo --panicOnWarning -s exampleSite/ 50 | 51 | - name: beautify 52 | image: quay.io/thegeeklab/alpine-tools 53 | commands: 54 | - html-beautify -r -f 'exampleSite/public/**/*.html' 55 | environment: 56 | FORCE_COLOR: "true" 57 | 58 | - name: publish 59 | image: quay.io/thegeeklab/wp-s3-action 60 | settings: 61 | access_key: 62 | from_secret: s3_access_key 63 | bucket: geekdocs 64 | delete: true 65 | endpoint: 66 | from_secret: s3_endpoint 67 | path_style: true 68 | secret_key: 69 | from_secret: s3_secret_access_key 70 | source: exampleSite/public/ 71 | strip_prefix: exampleSite/public/ 72 | target: /${CI_REPO_NAME} 73 | when: 74 | - event: [tag] 75 | - event: [push, manual] 76 | branch: 77 | - ${CI_REPO_DEFAULT_BRANCH} 78 | status: [success, failure] 79 | 80 | depends_on: 81 | - build-package 82 | -------------------------------------------------------------------------------- /.woodpecker/notify.yml: -------------------------------------------------------------------------------- 1 | --- 2 | when: 3 | - event: [tag] 4 | - event: [push, manual] 5 | branch: 6 | - ${CI_REPO_DEFAULT_BRANCH} 7 | 8 | runs_on: [success, failure] 9 | 10 | steps: 11 | - name: matrix 12 | image: quay.io/thegeeklab/wp-matrix 13 | settings: 14 | homeserver: 15 | from_secret: matrix_homeserver 16 | room_id: 17 | from_secret: matrix_room_id 18 | user_id: 19 | from_secret: matrix_user_id 20 | access_token: 21 | from_secret: matrix_access_token 22 | when: 23 | - status: [success, failure] 24 | 25 | depends_on: 26 | - docs 27 | -------------------------------------------------------------------------------- /.woodpecker/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | when: 3 | - event: [pull_request, tag] 4 | - event: [push, manual] 5 | branch: 6 | - ${CI_REPO_DEFAULT_BRANCH} 7 | 8 | steps: 9 | - name: eslint 10 | image: docker.io/library/node:lts 11 | commands: 12 | - npm install --quiet --no-progress 13 | - npm run lint:js 14 | environment: 15 | FORCE_COLOR: "true" 16 | 17 | - name: assets 18 | image: docker.io/library/node:lts 19 | depends_on: [eslint] 20 | commands: 21 | - npm install --quiet --no-progress 22 | - npm run build 23 | environment: 24 | FORCE_COLOR: "true" 25 | 26 | - name: testbuild 27 | image: quay.io/thegeeklab/hugo:0.147 28 | depends_on: [assets] 29 | commands: 30 | - mkdir -p exampleSite/themes/ && ln -s $(pwd)/ exampleSite/themes/${CI_REPO_NAME} 31 | - hugo --panicOnWarning -s exampleSite/ -b http://localhost:8000/ 32 | 33 | - name: html-validation 34 | image: docker.io/library/node:lts 35 | depends_on: [testbuild] 36 | commands: 37 | - npm install --quiet --no-progress 38 | - npm run lint:html 39 | environment: 40 | FORCE_COLOR: "true" 41 | 42 | - name: link-validation 43 | image: docker.io/lycheeverse/lychee 44 | depends_on: [testbuild] 45 | commands: 46 | - lychee --no-progress --format detailed exampleSite/content/ README.md 47 | environment: 48 | GITHUB_TOKEN: 49 | from_secret: github_token_ro 50 | 51 | - name: page-validation 52 | image: quay.io/thegeeklab/lhci:0.14 53 | depends_on: [testbuild] 54 | commands: 55 | - lhci autorun 56 | environment: 57 | LHCI_SERVER_URL: https://ci-artifact.rknet.org/${CI_REPO_NAME}/ 58 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ## Security 4 | 5 | If you think you have found a **security issue**, please do not mention it in this repository. 6 | Instead, send an email to `security@thegeeklab.de` with as many details as possible so it can be handled confidential. 7 | 8 | ## Bug Reports and Feature Requests 9 | 10 | If you have found a **bug** or have a **feature request** please use the search first in case a similar issue already exists. 11 | If not, please create an issue in this repository 12 | 13 | ## Code 14 | 15 | If you would like to fix a bug or implement a feature, please fork the repository and create a Pull Request. 16 | 17 | Before you start any Pull Request, it is recommended that you create an issue to discuss first if you have any 18 | doubts about requirement or implementation. That way you can be sure that the maintainer(s) agree on what to change and how, 19 | and you can hopefully get a quick merge afterwards. 20 | 21 | Pull Requests can only be merged once all status checks are green. 22 | 23 | ## Do not force push to your Pull Request branch 24 | 25 | Please do not force push to your Pull Requests branch after you have created your Pull Request, as doing so makes it harder for us to review your work. 26 | Pull Requests will always be squashed by us when we merge your work. Commit as many times as you need in your Pull Request branch. 27 | 28 | ## Re-requesting a review 29 | 30 | Please do not ping your reviewer(s) by mentioning them in a new comment. Instead, use the re-request review functionality. 31 | Read more about this in the [GitHub docs, Re-requesting a review](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/incorporating-feedback-in-your-pull-request#re-requesting-a-review). 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Robert Kaussow 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is furnished 10 | to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice (including the next 13 | paragraph) shall be included in all copies or substantial portions of the 14 | Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS 19 | OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 21 | OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Geekblog 2 | 3 | [![Build Status](https://ci.thegeeklab.de/api/badges/thegeeklab/hugo-geekblog/status.svg)](https://ci.thegeeklab.de/repos/thegeeklab/hugo-geekblog) 4 | [![Hugo Version](https://img.shields.io/badge/hugo-0.128-blue.svg)](https://gohugo.io) 5 | [![GitHub release](https://img.shields.io/github/v/release/thegeeklab/hugo-geekblog)](https://github.com/thegeeklab/hugo-geekblog/releases/latest) 6 | [![GitHub contributors](https://img.shields.io/github/contributors/thegeeklab/hugo-geekblog)](https://github.com/thegeeklab/hugo-geekblog/graphs/contributors) 7 | [![License: MIT](https://img.shields.io/github/license/thegeeklab/hugo-geekblog)](https://github.com/thegeeklab/hugo-geekblog/blob/main/LICENSE) 8 | 9 | Geekblog is a simple Hugo theme for personal blogs. It is intentionally designed as a fast and lean theme and may not fit the requirements of complex projects. If a more feature-complete theme is required there are a lot of got alternatives out there. You can find a demo and the full documentation at [https://hugo-geekblog.geekdocs.de](https://hugo-geekblog.geekdocs.de). 10 | 11 | ![Desktop and mobile preview](https://github.com/thegeeklab/hugo-geekblog/blob/main/images/readme.png) 12 | 13 | ## Build and release process 14 | 15 | This theme is subject to a CI driven build and release process common for software development. During the release build, all necessary assets are automatically built by [webpack](https://webpack.js.org/) and bundled in a release tarball. You can download the latest release from the GitHub [release page](https://github.com/thegeeklab/hugo-geekblog/releases). 16 | 17 | Due to the fact that `webpack` and `npm scripts` are used as pre-processors, the theme cannot be used from the main branch by default. If you want to use the theme from a cloned branch instead of a release tarball you'll need to install `webpack` locally and run the build script once to create all required assets. 18 | 19 | ```shell 20 | # install required packages from package.json 21 | npm install 22 | 23 | # run the build script to build required assets 24 | npm run build 25 | 26 | # build release tarball 27 | npm run pack 28 | ``` 29 | 30 | See the [Getting Started Guide](https://hugo-geekblog.geekdocs.de/posts/usage/getting-started/) for details about the different setup options. 31 | 32 | ## Contributors 33 | 34 | Special thanks to all [contributors](https://github.com/thegeeklab/hugo-geekblog/graphs/contributors). If you would like to contribute, please see the [instructions](https://github.com/thegeeklab/hugo-geekblog/blob/main/CONTRIBUTING.md). 35 | 36 | ## License 37 | 38 | This project is licensed under the MIT License - see the [LICENSE](https://github.com/thegeeklab/hugo-geekblog/blob/main/LICENSE) file for details. 39 | 40 | The used SVG icons and generated icon fonts are licensed under the license of the respective icon pack: 41 | 42 | - Font Awesome: [CC BY 4.0 License](https://github.com/FortAwesome/Font-Awesome#license) 43 | - IcoMoon Free Pack: [GPL/CC BY 4.0](https://icomoon.io/#icons-icomoon) 44 | - Material Icons: [Apache License 2.0](https://github.com/google/material-design-icons/blob/main/LICENSE) 45 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import eslint from "@eslint/js"; 2 | import globals from "globals"; 3 | import babelParser from "@babel/eslint-parser"; 4 | import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended"; 5 | 6 | export default [ 7 | eslint.configs.recommended, 8 | { 9 | languageOptions: { 10 | globals: { 11 | ...globals.browser, 12 | }, 13 | parser: babelParser, 14 | ecmaVersion: 2022, 15 | sourceType: "module", 16 | parserOptions: { 17 | requireConfigFile: false, 18 | }, 19 | }, 20 | }, 21 | eslintPluginPrettierRecommended, 22 | ]; 23 | -------------------------------------------------------------------------------- /exampleSite/archetypes/default.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "{{ replace .Name "-" " " | title }}" 3 | date: {{ .Date }} 4 | draft: true 5 | --- 6 | -------------------------------------------------------------------------------- /exampleSite/config/_default/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | baseURL: https://hugo-geekblog.geekdocs.de/ 3 | title: Geekblog 4 | theme: hugo-geekblog 5 | pygmentsUseClasses: true 6 | pygmentsCodeFences: true 7 | enableGitInfo: true 8 | timeout: 180000 9 | pluralizeListTitles: false 10 | 11 | pagination: 12 | pagerSize: 5 13 | 14 | markup: 15 | goldmark: 16 | renderer: 17 | unsafe: true 18 | tableOfContents: 19 | startLevel: 1 20 | endLevel: 9 21 | 22 | taxonomies: 23 | author: authors 24 | tag: tags 25 | 26 | mediaTypes: 27 | "application/atom+xml": 28 | suffixes: 29 | - "xml" 30 | 31 | outputFormats: 32 | Atom: 33 | # https://validator.w3.org/feed/docs/atom.html#whatIsAtom 34 | name: "Atom" 35 | mediaType: "application/atom+xml" 36 | # generated file: . = atom.xml 37 | baseName: "feed" 38 | isPlainText: false 39 | rel: "alternate" 40 | isHTML: false 41 | noUgly: true 42 | permalinkable: false 43 | Json: 44 | # https://www.jsonfeed.org/2020/08/07/json-feed-version.html 45 | name: "Json" 46 | mediaType: "application/json" 47 | # generated file: . = feed.json 48 | baseName: "feed" 49 | isPlainText: false 50 | rel: "alternate" 51 | isHTML: false 52 | noUgly: true 53 | permalinkable: false 54 | 55 | outputs: 56 | home: 57 | - HTML 58 | - ATOM 59 | - JSON 60 | page: 61 | - HTML 62 | section: 63 | - HTML 64 | taxonomy: 65 | - HTML 66 | term: 67 | - HTML 68 | - ATOM 69 | - JSON 70 | 71 | enableRobotsTXT: true 72 | 73 | security: 74 | exec: 75 | allow: 76 | - "^git$" 77 | - "^asciidoctor$" 78 | -------------------------------------------------------------------------------- /exampleSite/config/_default/params.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | subtitle: Subtitle to describe your blog 3 | description: > 4 | hugo-geekblog is a simple Hugo theme for personal blogs. This page is theme documentation 5 | and powered by the latest version of hugo-geekblog itself. 6 | images: 7 | - "socialmedia2.png" 8 | 9 | geekblogToC: 3 10 | geekblogAuthor: john-doe 11 | 12 | geekblogLegalNotice: https://thegeeklab.de/legal-notice/#contact-information 13 | geekblogPrivacyPolicy: https://thegeeklab.de/legal-notice/#privacy-policy 14 | 15 | geekblogImageLazyLoading: true 16 | geekblogDarkModeDim: true 17 | geekblogTagsToMenu: true 18 | -------------------------------------------------------------------------------- /exampleSite/config/ci/params.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | geekblogSeoIgnore: 3 | - "taxonomy" 4 | - "term" 5 | -------------------------------------------------------------------------------- /exampleSite/content/_includes/include-page.md: -------------------------------------------------------------------------------- 1 | _**Example page include**_ 2 | 3 | {{< hint type=note >}} 4 | **Example Shortcode**\ 5 | Shortcode used in an include page. 6 | {{< /hint >}} 7 | 8 | | Head 1 | Head 2 | Head 3 | 9 | | ------ | ------ | ------ | 10 | | 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /exampleSite/content/about/images/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/exampleSite/content/about/images/avatar.jpg -------------------------------------------------------------------------------- /exampleSite/content/about/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: About Me 3 | resources: 4 | - name: avatar 5 | src: "images/avatar.jpg" 6 | params: 7 | credits: "[Angelina Litvin](https://unsplash.com/@linalitvina) on [Unsplash](https://unsplash.com/s/photos/writing)" 8 | --- 9 | 10 | 11 | 12 | {{< columns size=small >}} 13 | 14 | {{< avatar name=avatar size=tiny >}} 15 | 16 | <---> 17 | 18 | Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. In pro quints consequent, denim fastidious copious quo ad. Stet probates in duo. 19 | {{< /columns >}} 20 | 21 | --- 22 | 23 | ## Experience 24 | 25 | {{< columns size=small >}} 26 | 27 | **Dream Corp**\ 28 | Principle Developer\ 29 | Jan 2018 - Sep 2019 30 | 31 | <---> 32 | 33 | Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. 34 | {{< /columns >}} 35 | 36 | {{< columns size=small >}} 37 | 38 | **Boring Company Lt**\ 39 | Developer\ 40 | Apr 2015 - Jan 2018 41 | 42 | <---> 43 | 44 | Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Dolor sit. Denim fastidious copious quo ad. Stet probates in duo. Sumo unique argument um no. 45 | {{< /columns >}} 46 | 47 | --- 48 | 49 | ## Education 50 | 51 | Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. In pro quints consequent, denim fastidious copious quo ad. Stet probates in duo. 52 | 53 | --- 54 | 55 |
56 | 57 | ## Skills 58 | 59 | 60 | 61 | {{% progress title=Hacking value=95 icon=gblog_search %}} 62 | {{% progress title=Cyber-Things value=80 icon=gblog_cloud_off %}} 63 | {{% progress title=Coding value=65 icon=gblog_code %}} 64 | {{% progress title=Eating value=85 icon=gblog_heart %}} 65 | 66 | 67 | 68 |
69 | 70 | --- 71 | 72 |
73 | 74 | ## Contact 75 | 76 | 77 | 78 | 79 | 80 | {{< boxes "contact" >}} 81 | {{< box size=large title=E-Mail icon=gblog_email >}}mail [ett] example.com{{< /box >}} 82 | {{< box size=large title=Matrix icon=gblog_matrix >}}@john:example.com{{< /box >}} 83 | {{< box size=large title=XMPP icon=gblog_xmpp >}}john@example.com{{< /box >}} 84 | {{< /boxes >}} 85 | 86 | 87 | 88 | 89 |
90 | -------------------------------------------------------------------------------- /exampleSite/content/posts/advanced/includes.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Includes 3 | date: 2021-05-23T20:00:00+01:00 4 | authors: 5 | - john-doe 6 | tags: 7 | - Documentation 8 | - Shortcodes 9 | --- 10 | 11 | Include shortcode can include files of different types. By specifying a language, the included file will have syntax highlighting. 12 | 13 | 14 | 15 | {{< toc >}} 16 | 17 | ## Usage 18 | 19 | 20 | ```tpl 21 | {{}} 22 | ``` 23 | 24 | 25 | ## Attributes 26 | 27 | 28 | 29 | {{< propertylist name=shortcode-includes sort=name order=asc >}} 30 | 31 | 32 | 33 | ## Examples 34 | 35 | ### Markdown files (default) 36 | 37 | If no other options are specified, files will be rendered as Markdown using the `RenderString` [function](https://gohugo.io/functions/renderstring/). 38 | 39 | {{< hint type=important >}} 40 | **Location of markdown files**\ 41 | If you include markdown files that should not get a menu entry, place them outside the content folder or exclude them otherwise. 42 | {{< /hint >}} 43 | 44 | 45 | ```tpl 46 | {{}} 47 | ``` 48 | 49 | 50 | 51 | {{< include file="/static/_includes/example.md.part" >}} 52 | 53 | 54 | 55 | ### Language files 56 | 57 | This method can be used to include source code files and keep them automatically up to date. 58 | 59 | 60 | ```tpl 61 | {{}} 62 | ``` 63 | 64 | Result: 65 | 66 | 67 | 68 | {{< include file="config/_default/config.yaml" language="yaml" options="linenos=table,hl_lines=5-6,linenostart=100" >}} 69 | 70 | 71 | 72 | ## Special include types 73 | 74 | ### HTML 75 | 76 | HTML content will be filtered by the `safeHTML` filter and added to the rendered page output. 77 | 78 | 79 | ```tpl 80 | {{}} 81 | ``` 82 | 83 | {{< include file="/static/_includes/example.html.part" type="html" >}} 84 | 85 | ### Pages 86 | 87 | In some situations, it can be helpful to include Markdown files that also contain shortcodes. While the [default method](#markdown-files-default) works fine to render plain Markdown, shortcodes are not parsed. The only way to get this to work is to use Hugo pages. There are several ways to structure these include pages, so whatever you do, keep in mind that Hugo needs to be able to render and serve these files as regular pages! How it works: 88 | 89 | 1. First you need to create a directory **within** your content directory. For this example site `_includes` is used. 90 | 2. Place your Markdown files within the `_includes` folder e.g. `/_includes/include-page.md`. Make sure to name it `*.md`. 91 | 3. Include the page using `{{}}`. 92 | 93 | Resulting structure should look like this: 94 | 95 | ```shell 96 | _includes/ 97 | ├── include-page.md 98 | └── _index.md 99 | ``` 100 | 101 | {{< include file="/_includes/include-page.md" type="page" >}} 102 | -------------------------------------------------------------------------------- /exampleSite/content/posts/advanced/toc.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Table of Content 3 | date: 2021-05-23T20:00:00+01:00 4 | authors: 5 | - john-doe 6 | tags: 7 | - Documentation 8 | - Shortcodes 9 | --- 10 | 11 | Simple wrapper to generate a page Table of Content from a shortcode. 12 | 13 | 14 | 15 | 16 | ```tpl 17 | {{}} 18 | ``` 19 | 20 | {{< toc >}} 21 | 22 | ## Level 1 23 | 24 | Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. In pro quints consequent, denim fastidious copious quo ad. Stet probates in duo. 25 | 26 | ## Level 2 27 | 28 | Amalia id per in minimum facility, quid facet modifier ea ma. Ill um select ma ad, en ferric patine sentient vim. Per expendable foreordained interpretations cu, maxim sole pertinacity in ram. 29 | 30 | ### Level 2.1 31 | 32 | Amalia id per in minimum facility, quid facet modifier ea ma. Ill um select ma ad, en ferric patine sentient vim. Per expendable foreordained interpretations cu, maxim sole pertinacity in ram. 33 | 34 | #### Level 2.1.1 35 | 36 | Amalia id per in minimum facility, quid facet modifier ea ma. Ill um select ma ad, en ferric patine sentient vim. 37 | 38 | ##### Level 2.1.1.1 39 | 40 | In pro quints consequent, denim fastidious copious quo ad. 41 | 42 | ###### Level 2.1.1.1.1 43 | 44 | In pro quints consequent, denim fastidious copious quo ad. 45 | 46 | ### Level 2.2 47 | 48 | Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. 49 | 50 | Amalia id per in minimum facility, quid facet modifier ea ma. Ill um select ma ad, en ferric patine sentient vim. Per expendable foreordained interpretations cu, maxim sole pertinacity in ram. 51 | -------------------------------------------------------------------------------- /exampleSite/content/posts/asciidoc/admonition-icons.adoc: -------------------------------------------------------------------------------- 1 | +++ 2 | title = "Admonition Icons" 3 | date = 2020-06-22T20:00:00+02:00 4 | +++ 5 | 6 | :icons: font 7 | 8 | By default, the admonition is rendered with a plain text label. To enable font icons the document attribute `:icons: font` need to be set. 9 | 10 | 11 | 12 | == Example 13 | 14 | [NOTE] 15 | Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. 16 | Ornateness bland it ex enc, est yeti am bongo detract re. 17 | 18 | [TIP] 19 | Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. 20 | Ornateness bland it ex enc, est yeti am bongo detract re. 21 | 22 | [IMPORTANT] 23 | Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. 24 | Ornateness bland it ex enc, est yeti am bongo detract re. 25 | 26 | [CAUTION] 27 | Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. 28 | Ornateness bland it ex enc, est yeti am bongo detract re. 29 | 30 | [WARNING] 31 | Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. 32 | Ornateness bland it ex enc, est yeti am bongo detract re. 33 | -------------------------------------------------------------------------------- /exampleSite/content/posts/asciidoc/admonitions.adoc: -------------------------------------------------------------------------------- 1 | +++ 2 | title = "Admonitions" 3 | date = 2020-06-22T20:00:00+02:00 4 | +++ 5 | 6 | :toc: 7 | :toclevels: 2 8 | 9 | AsciiDoc admonitions are special callout blocks that highlight important information in documentation using distinct visual styles and icons. 10 | 11 | 12 | 13 | {{< toc >}} 14 | 15 | == Admonition types 16 | 17 | There are certain statements you may want to draw attention to by taking them out of the content's flow and labeling them with a priority. These are called admonitions. 18 | 19 | ```tpl 20 | [NOTE|TIP|IMPORTANT|CAUTION|WARNING] 21 | Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. 22 | Ornateness bland it ex enc, est yeti am bongo detract re. 23 | ``` 24 | 25 | === Example 26 | 27 | [NOTE] 28 | Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. 29 | Ornateness bland it ex enc, est yeti am bongo detract re. 30 | 31 | [TIP] 32 | Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. 33 | Ornateness bland it ex enc, est yeti am bongo detract re. 34 | 35 | [IMPORTANT] 36 | Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. 37 | Ornateness bland it ex enc, est yeti am bongo detract re. 38 | 39 | [CAUTION] 40 | Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. 41 | Ornateness bland it ex enc, est yeti am bongo detract re. 42 | 43 | [WARNING] 44 | ==== 45 | Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. 46 | Ornateness bland it ex enc, est yeti am bongo detract re. 47 | 48 | Romanesque acclimates investiture. 49 | ==== 50 | 51 | == Admonition icons 52 | 53 | Icons can be added by setting a unicode glyph or a character reference to the `tip-caption` attribute: 54 | 55 | ```text 56 | :tip-caption: 💡 57 | 58 | [TIP] 59 | It's possible to use Unicode glyphs as admonition icons. 60 | ``` 61 | 62 | ```text 63 | :tip-caption: pass:[🔥] 64 | 65 | [TIP] 66 | It's possible to use Unicode glyphs as admonition icons. 67 | ``` 68 | 69 | === Example 70 | 71 | :tip-caption: 💡 72 | 73 | [TIP] 74 | It's possible to use Unicode glyphs as admonition icons. 75 | 76 | 77 | :tip-caption: pass:[🔥] 78 | 79 | [TIP] 80 | It's possible to use Unicode glyphs as admonition icons. 81 | -------------------------------------------------------------------------------- /exampleSite/content/posts/avatar-images/images/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/exampleSite/content/posts/avatar-images/images/avatar.jpg -------------------------------------------------------------------------------- /exampleSite/content/posts/avatar-images/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Avatar Images 3 | date: 2024-04-27T21:00:00+02:00 4 | authors: 5 | - john-doe 6 | tags: 7 | - Documentation 8 | - Shortcodes 9 | resources: 10 | - name: avatar 11 | src: "images/avatar.jpg" 12 | title: "Avatar" 13 | --- 14 | 15 | The avatar shortcode is another custom image shortcode. 16 | 17 | 18 | 19 | ## Usage 20 | 21 | Define a resource in the page front matter. 22 | 23 | 24 | 25 | ```md 26 | --- 27 | resources: 28 | - name: avatar 29 | src: "images/avatar.jpg" 30 | title: "Avatar" 31 | --- 32 | 33 | {{}} 34 | ``` 35 | 36 | 37 | 38 | ## Attributes 39 | 40 | 41 | 42 | {{< propertylist name=shortcode-avatar sort=name order=asc >}} 43 | 44 | 45 | 46 | ## Example 47 | 48 | 49 | 50 | {{< avatar name=avatar size="small" >}} 51 | 52 | 53 | -------------------------------------------------------------------------------- /exampleSite/content/posts/features/authors.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Authors 3 | date: 2021-05-23T20:00:00+01:00 4 | authors: 5 | - john-doe 6 | tags: 7 | - Documentation 8 | - Features 9 | --- 10 | 11 | The theme supports multiple authors. The required information for each author need to be stored in a single [Hugo data template](https://gohugo.io/templates/data-templates/) per author.These files need to be stored in the `data/authors/` directory in your projects root. 12 | 13 | 14 | 15 | ```shell 16 | data/ 17 | └── authors 18 | ├── john-doe.yml 19 | ├── richard-roe.yml 20 | └── Special User.yml 21 | ``` 22 | 23 | The name of the file will be used as the reference later, so if you prefer some kind of naming convention this need to covered by the file names. Example authors file: 24 | 25 | ```yaml 26 | name: John Doe 27 | email: john@example.com 28 | ``` 29 | 30 | With the defined files, you can add as many authors as you want to the front matter of your posts: 31 | 32 | ```markdown 33 | --- 34 | title: Demo Posts 35 | authors: 36 | - john-doe 37 | - Special User 38 | --- 39 | 40 | My first demo post. 41 | ``` 42 | -------------------------------------------------------------------------------- /exampleSite/content/posts/features/code-blocks.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Code Blocks 3 | date: 2021-11-21T15:00:00+01:00 4 | authors: 5 | - john-doe 6 | tags: 7 | - Documentation 8 | - Features 9 | --- 10 | 11 | There are several ways to add code blocks. Most of them work out of the box, only the Hugo short code `` needs to be configured to work properly. The theme also provides some additional features like a copy button and an option to set the maximum length of code blocks. Both of these functions and the dependent formatting rely on the `.highlight` CSS class. You must ensure that you always assign a language to your code blocks if you want to use these functions. If you do not want to apply syntax highlighting, you can also specify `plain` or `text` as the language. 12 | 13 | {{< toc >}} 14 | 15 | ## Inline code 16 | 17 | To display an inline shortcode use single quotes: 18 | 19 | ```plain 20 | `some code` 21 | ``` 22 | 23 | **Example:** `some code` with a [`link`](#) 24 | 25 | ## Code blocks 26 | 27 | Code blocks can be uses without language specification: 28 | 29 | ````markdown 30 | ```plain 31 | some code 32 | ``` 33 | ```` 34 | 35 | **Example:** 36 | 37 | ```plain 38 | some code 39 | ``` 40 | 41 | ... or if you need language specific syntax highlighting: 42 | 43 | ````markdown 44 | ```shell 45 | # some code 46 | echo "Hello world" 47 | ``` 48 | ```` 49 | 50 | **Example:** 51 | 52 | ```shell 53 | # some code 54 | echo "Hello World" 55 | ``` 56 | 57 | ## Highlight shortcode 58 | 59 | Hugo has a build-in shortcode for syntax highlighting. To work properly with this theme, you have to set following options in your site configuration: 60 | 61 | {{< tabs "uniqueid" >}} 62 | {{< tab "TOML" >}} 63 | 64 | ```toml 65 | pygmentsUseClasses=true 66 | pygmentsCodeFences=true 67 | ``` 68 | 69 | {{< /tab >}} 70 | {{< tab "YAML" >}} 71 | 72 | ```yaml 73 | pygmentsUseClasses: true 74 | pygmentsCodeFences: true 75 | ``` 76 | 77 | {{< /tab >}} 78 | {{< /tabs >}} 79 | 80 | You can use it like every other shortcode: 81 | 82 | 83 | ```markdown 84 | {{}} 85 | # some code 86 | echo "Hello World" 87 | {{}} 88 | ``` 89 | 90 | **Example:** 91 | 92 | 93 | 94 | 95 | {{< highlight Shell "linenos=table" >}} 96 | # some code 97 | echo "Hello World" 98 | {{< /highlight >}} 99 | 100 | 101 | -------------------------------------------------------------------------------- /exampleSite/content/posts/features/dark-mode/images/geekblog-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/exampleSite/content/posts/features/dark-mode/images/geekblog-dark.png -------------------------------------------------------------------------------- /exampleSite/content/posts/features/dark-mode/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Dark Mode 3 | date: 2021-11-21T15:00:00+01:00 4 | authors: 5 | - john-doe 6 | tags: 7 | - Documentation 8 | - Features 9 | --- 10 | 11 | Say hello to the dark mode of the Geekblog theme! 12 | 13 | [![Geekblog in dark mode](images/geekblog-dark.png)](images/geekblog-dark.png) 14 | 15 | The dark mode can be used in two different ways. If you have JavaScript disabled in your browser, the dark mode automatically detects the preferred system settings via the `prefers-color-scheme` parameter. Depending on the value, the theme will automatically switch between dark and light mode if this feature is supported by your operating system and browser. 16 | 17 | The second mode requires JavaScript and is controlled by a dark mode switch in the upper right corner. You can switch between three modes: Auto, Dark and Light. Auto mode works the same as the first method mentioned above and automatically detects the system setting. Dark and Light modes allow you to force one of them for your Geekblog page only, regardless of the system setting. This works even if your browser or operating system does not support the system setting. The current selection is stored locally via the Web Storage API. 18 | 19 | To avoid very bright spots often caused by images while using the dark mode we have added an optional auto-dim feature that can be enabled with the site parameter `geekblogDarkModeDim` (see [Configuration](/posts/usage/configuration/)). As this may have an impact on the quality of the images it is disabled by default. 20 | -------------------------------------------------------------------------------- /exampleSite/content/posts/features/icon-sets.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Icon Sets 3 | date: 2021-05-23T20:00:00+01:00 4 | authors: 5 | - john-doe 6 | tags: 7 | - Documentation 8 | - Features 9 | --- 10 | 11 | Learn how about build-in icons and how to extend it. 12 | 13 | 14 | 15 | {{< toc >}} 16 | 17 | ## Custom icons 18 | 19 | The only supported source for custom icons are SVG sprites. Some icon frameworks provides ready to use sprites e.g. FontAwesome. If the framework don't provide sprites, you can create your own from raw SVG icons. There are a lot of tools available to create sprites, please choose one that fits your need. One solution could be [svgsprit.es](https://svgsprit.es/). 20 | 21 | Regardless of which tool (or existing sprite) you choose, there are a few requirements that must be met: 22 | 23 | 1. The sprite must be a valid **SVG** file. 24 | 2. You have to ensure to **hide the sprite**. Apply the predefined class `svg-sprite` or `hidden` to the root element of your sprite or add a small piece of inline CSS e.g. `style="display: none;"`. 25 | 3. Save the sprite to the folder `assets/sprites` right beside your `content` folder. 26 | 27 | The result of a valid minimal SVG sprite file could look like this: 28 | 29 | ```xml 30 | 31 | 32 | 33 | 34 | 35 | ``` 36 | 37 | **Example:** 38 | 39 | FontAwesome provides three pre-build sprites included in the regular Web download pack, `sprites/brands.svg`, `sprites/regular.svg` and `sprites/solid.svg`. Choose your sprite to use and copy it to your projects root directory into `assets/sprites`, right beside your `content` folder. The result should look like this: 40 | 41 | ```bash 42 | my_projcet/ 43 | ├── assets 44 | │ └── sprites 45 | │ └── regular.svg 46 | ├── config.yaml 47 | ├── content 48 | │ ├── _index.md 49 | │ ├── ... 50 | ``` 51 | 52 | That's it! The theme will auto-load all available SVG sprites provided in the assets folder. To use the icons, you need to lookup the id of the icon. An example would be `thumbs-up` {{< icon "thumbs-up" >}}. There is also a [shortcode](/posts/advanced/shortcodes/#icon) available 53 | 54 | ## Build-in icons 55 | 56 | The theme bundles just a small set of hand crafted icons. 57 | 58 | {{< sprites >}} 59 | -------------------------------------------------------------------------------- /exampleSite/content/posts/features/sticky.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Simple sticky posts 3 | date: 2020-06-13T00:06:00+02:00 4 | authors: 5 | - john-doe 6 | tags: 7 | - Documentation 8 | - Features 9 | weight: 1 10 | --- 11 | 12 | Sticky (or pinned) posts can be used to permanently pin important posts to the top of the post list. The implementation is pretty simple and handled by `weight: 1` in a post front matter. As there is no other logic to identify sticky posts you should not use negative values for weight as this will result in posts listed earlier. 13 | 14 | 15 | 16 | **Example:** 17 | 18 | ```yaml 19 | --- 20 | title: Simple sticky posts 21 | weight: 1 22 | date: 2020-06-13T00:06:00+02:00 23 | authors: 24 | - john-doe 25 | --- 26 | ``` 27 | -------------------------------------------------------------------------------- /exampleSite/content/posts/features/theming/images/theme-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/exampleSite/content/posts/features/theming/images/theme-example.png -------------------------------------------------------------------------------- /exampleSite/content/posts/features/theming/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Theming 3 | date: 2021-05-23T20:00:00+01:00 4 | authors: 5 | - john-doe 6 | tags: 7 | - Documentation 8 | - Features 9 | --- 10 | 11 | {{< toc >}} 12 | 13 | ## Color Scheme 14 | 15 | If you want to customize the theme's color scheme to give it your individual touch, you are only a few lines of CSS away. Generally, you need to override the default settings. The easiest way to do this is to create a file named `static/custom.css` right at the root of your site. 16 | 17 | All the necessary CSS customization properties are listed below. If you want to customize elements that don't use these properties, you can always look up the class name and override it directly. For inspiration, you can also take a look at [https://www.color-hex.com](https://www.color-hex.com/color-palettes/). In this simple example, we'll use the [_Beach_](https://www.color-hex.com/color-palette/895) color palette. 18 | 19 | [![Beach Color Palette](images/theme-example.png)](images/theme-example.png) 20 | 21 | **Custom CSS:** 22 | 23 | 24 | 25 | {{< include file="/static/custom.css.example" language="CSS" options="linenos=table" >}} 26 | 27 | 28 | 29 | ## Favicons 30 | 31 | The Theme is shipped with a set of default Favicons in various formats generated by the [Favicon Generator](https://realfavicongenerator.net/). All files can be found in the `static/favicon` folder of the release tarball. To make the replacement of the default Favicons as simple as possible, the theme loads only a very small subset of the Favicon formats. 32 | 33 | 34 | ```tpl 35 | 36 | 37 | 38 | ``` 39 | 40 | ### Simple replacement 41 | 42 | The minimal steps to load a custom Favicon is to overwrite the three default Favicon files. Therefor place these files into your projects root folder: 43 | 44 | - `static/favicon/favicon.svg` 45 | - `static/favicon/favicon-32x32.png` 46 | - `static/favicon/favicon-16x16.png` 47 | 48 | ### Full replacement 49 | 50 | If you want to add more Favicon formats you have to [overwrite](https://gohugo.io/templates/partials/#partial-template-lookup-order) the default partial that is used to load the files. In the next step you have to place the required files in the `static` folder of your project as well. 51 | 52 | **Example:** 53 | 54 | 55 | ```tpl 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | ``` 66 | 67 | ## Fonts 68 | 69 | To use a custom font, it needs to be specified first. While there are many ways to do this, we recommend to use `@font-face` as it supports local as well as remote fonts. If you want to serve the fonts from your own server, you have to place them in the `static/fonts` folder of your project. 70 | 71 | The font registration is done in the `custom.css` file. There are also a few custom CSS properties available to simplify the usage of custom fonts. 72 | 73 | **Example:** 74 | 75 | 76 | ```css 77 | @font-face { 78 | font-family: "DancingScript"; 79 | src: 80 | url("fonts/DancingScript.woff2") format("woff2"), 81 | url("fonts/DancingScript.woff") format("woff"); 82 | font-weight: normal; 83 | font-style: normal; 84 | font-display: swap; 85 | } 86 | 87 | :root { 88 | --code-max-height: 60rem; 89 | 90 | --header-font-family: "DancingScript"; 91 | --body-font-family: "DancingScript"; 92 | --code-font-family: "DancingScript"; 93 | } 94 | ``` 95 | 96 | Happy customizing! 97 | -------------------------------------------------------------------------------- /exampleSite/content/posts/post-short.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Short post 3 | date: 2020-06-22T20:00:00+02:00 4 | authors: 5 | - john-doe 6 | tags: 7 | - Development 8 | weight: 10 9 | --- 10 | 11 | Dolor sit, sumo unique argument um no. Gracie nominal id xiv. Romanesque acclimates investiture. Ornateness bland it ex enc, est yeti am bongo detract re. Pro ad prompts feud gait, quid exercise emeritus bis e. In pro quints consequent, denim fastidious copious quo ad. Stet probates in duo. 12 | -------------------------------------------------------------------------------- /exampleSite/content/posts/post-with-images/images/feature.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/exampleSite/content/posts/post-with-images/images/feature.jpg -------------------------------------------------------------------------------- /exampleSite/content/posts/post-with-images/images/forest-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/exampleSite/content/posts/post-with-images/images/forest-1.jpg -------------------------------------------------------------------------------- /exampleSite/content/posts/post-with-images/images/forest-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/exampleSite/content/posts/post-with-images/images/forest-2.jpg -------------------------------------------------------------------------------- /exampleSite/content/posts/post-with-images/images/forest-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/exampleSite/content/posts/post-with-images/images/forest-3.jpg -------------------------------------------------------------------------------- /exampleSite/content/posts/post-with-images/images/forest-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/exampleSite/content/posts/post-with-images/images/forest-4.jpg -------------------------------------------------------------------------------- /exampleSite/content/posts/post-with-images/images/forest-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/exampleSite/content/posts/post-with-images/images/forest-5.jpg -------------------------------------------------------------------------------- /exampleSite/content/posts/post-with-images/images/forest-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/exampleSite/content/posts/post-with-images/images/forest-6.jpg -------------------------------------------------------------------------------- /exampleSite/content/posts/post-with-images/images/forest-7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/exampleSite/content/posts/post-with-images/images/forest-7.jpg -------------------------------------------------------------------------------- /exampleSite/content/posts/usage/menus.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Menus 3 | date: 2021-05-23T20:00:00+01:00 4 | authors: 5 | - john-doe 6 | tags: 7 | - Documentation 8 | - Usage 9 | --- 10 | 11 | The theme supports different kinds of menus. 12 | 13 | 14 | 15 | ### Extra menu 16 | 17 | If you want to customize the menus (header and footer), this can be achieved by a data file. This file needs to be written in YAML and placed at data/menu/extra.yml. 18 | 19 | **Example:** 20 | 21 | ```yaml 22 | --- 23 | header: 24 | - name: Github Profile 25 | icon: gblog_github 26 | ref: "https://github.com/xoxys" 27 | external: true 28 | 29 | footer: 30 | - name: About 31 | icon: gblog_email 32 | ref: "/about" 33 | ``` 34 | -------------------------------------------------------------------------------- /exampleSite/data/authors/Special User.yml: -------------------------------------------------------------------------------- 1 | name: Sven Special 2 | email: sven@example.com 3 | -------------------------------------------------------------------------------- /exampleSite/data/authors/john-doe.yml: -------------------------------------------------------------------------------- 1 | name: John Doe 2 | email: john@example.com 3 | -------------------------------------------------------------------------------- /exampleSite/data/authors/richard-roe.yml: -------------------------------------------------------------------------------- 1 | name: Richard Roe 2 | email: richard@example.com 3 | -------------------------------------------------------------------------------- /exampleSite/data/menu/extra.yml: -------------------------------------------------------------------------------- 1 | --- 2 | header: 3 | - name: Github Profile 4 | icon: gblog_github 5 | ref: "https://github.com/xoxys" 6 | external: true 7 | 8 | footer: 9 | - name: About 10 | icon: gblog_email 11 | ref: "/about" 12 | -------------------------------------------------------------------------------- /exampleSite/data/properties/demo.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | properties: 3 | - name: prop1 4 | type: string 5 | description: Dummy description of the prop1 string property. 6 | required: true 7 | 8 | - name: prop2 9 | type: int 10 | defaultValue: 10 11 | description: Another description for the integer property called prop2. 12 | required: false 13 | tags: 14 | - tag1 15 | - tag2 16 | 17 | - name: prop3 18 | type: bool 19 | defaultValue: false 20 | description: | 21 | A `bool` property with a complex multiline description and embedded Markdown: 22 | 23 | - List item 1 24 | - List item 2 25 | 26 | More description how to use this property. 27 | required: false 28 | 29 | - name: a-prop 30 | type: string 31 | description: Property to demonstrate sorting. 32 | required: true 33 | -------------------------------------------------------------------------------- /exampleSite/data/properties/shortcode-avatar.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | properties: 3 | - name: name 4 | type: string 5 | description: Name of the image resource defined in page front matter. 6 | required: true 7 | - name: alt 8 | type: string 9 | description: Description text for the image. 10 | required: false 11 | - name: size 12 | type: string 13 | description: Thumbnail size. Supported values are `origin|tiny|small|medium|large`. 14 | required: false 15 | - name: anchor 16 | type: string 17 | description: "[Anchor](https://gohugo.io/content-management/image-processing/#anchor) to determine the placement of the crop box." 18 | required: false 19 | -------------------------------------------------------------------------------- /exampleSite/data/properties/shortcode-boxes.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | properties: 3 | - name: size 4 | type: string 5 | description: Size of each box. Supported values are `regular|large`. 6 | required: false 7 | devaultValue: regular 8 | - name: icon 9 | type: string 10 | description: Icon to use. The value need to be an icon from an [SVG sprite](/features/icon-sets/). 11 | required: false 12 | - name: title 13 | type: string 14 | description: Title text of the hint. 15 | required: false 16 | -------------------------------------------------------------------------------- /exampleSite/data/properties/shortcode-buttons.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | properties: 3 | - name: href 4 | type: string 5 | description: The URL to use as target of the button. 6 | required: false 7 | - name: relref 8 | type: string 9 | description: Executes the [relref](https://gohugo.io/functions/urls/relref/) Hugo function to resolve the relative permalink of the specified page. The result is set as the target of the button. 10 | required: false 11 | - name: class 12 | type: list 13 | description: List of space-separated CSS class names to apply. 14 | required: false 15 | - name: size 16 | type: string 17 | description: Preset of different button sizes. Supported values are `regular|large`. 18 | required: false 19 | devaultValue: regular 20 | -------------------------------------------------------------------------------- /exampleSite/data/properties/shortcode-columns.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | properties: 3 | - name: size 4 | type: string 5 | description: Preset of different sizes for the _first_ column. Supported values are `small|regular|large`. 6 | required: false 7 | defaultValue: regular 8 | -------------------------------------------------------------------------------- /exampleSite/data/properties/shortcode-hints.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | properties: 3 | - name: type 4 | type: string 5 | description: Type of the hint. Supported values are `note|tip|important|caution|warning`. 6 | required: false 7 | defaultValue: note 8 | - name: icon 9 | type: string 10 | description: Icon to use. The value need to be an icon from an [SVG sprite](/features/icon-sets/). 11 | required: false 12 | - name: title 13 | type: string 14 | description: Title text of the hint. 15 | required: false 16 | -------------------------------------------------------------------------------- /exampleSite/data/properties/shortcode-images.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | properties: 3 | - name: name 4 | type: string 5 | description: Name of the image resource defined in page front matter. 6 | required: true 7 | - name: alt 8 | type: string 9 | description: Description text for the image. 10 | required: false 11 | - name: size 12 | type: string 13 | description: Thumbnail size. Supported values are `origin|tiny|small|medium|large`. 14 | required: false 15 | - name: lazy 16 | type: bool 17 | description: Enable/disable lazy loading for the image. 18 | required: false 19 | defaultValue: true 20 | -------------------------------------------------------------------------------- /exampleSite/data/properties/shortcode-includes.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | properties: 3 | - name: file 4 | type: string 5 | description: Path of the file (relative to the Hugo root) to include. 6 | required: true 7 | - name: language 8 | type: string 9 | description: Language for [syntax highlighting](https://gohugo.io/content-management/syntax-highlighting/#list-of-chroma-highlighting-languages). 10 | required: false 11 | - name: type 12 | type: string 13 | description: Special include type. Supported values are `html|page`. If not set the included file is rendered as markdown. 14 | required: false 15 | - name: options 16 | type: bool 17 | description: highlighting [options](https://gohugo.io/content-management/syntax-highlighting/#highlight-shortcode). 18 | required: false 19 | defaultValue: linenos=table 20 | -------------------------------------------------------------------------------- /exampleSite/data/properties/shortcode-katex.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | properties: 3 | - name: class 4 | type: list 5 | description: List of space-separated CSS class names to apply. 6 | required: false 7 | -------------------------------------------------------------------------------- /exampleSite/data/properties/shortcode-mermaid.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | properties: 3 | - name: class 4 | type: list 5 | description: List of space-separated CSS class names to apply. 6 | required: false 7 | -------------------------------------------------------------------------------- /exampleSite/data/properties/shortcode-progress.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | properties: 3 | - name: value 4 | type: integer 5 | description: Progress value. 6 | required: false 7 | defaultValue: 0 8 | - name: icon 9 | type: string 10 | description: Icon to use. The value need to be an icon from an [SVG sprite](/features/icon-sets/). 11 | required: false 12 | - name: title 13 | type: string 14 | description: Title text of the progress bar. 15 | required: false 16 | -------------------------------------------------------------------------------- /exampleSite/data/properties/shortcode-propertylist.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | properties: 3 | - name: name 4 | type: string 5 | description: Name of the file from the `data/properties/` directory. 6 | required: true 7 | - name: sort 8 | type: string 9 | description: Field name to use for sorting. 10 | required: false 11 | - name: order 12 | type: string 13 | description: Sort order, only applied if `sort` is set. Supported values are `asc|desc`. 14 | required: false 15 | defaultValue: asc 16 | -------------------------------------------------------------------------------- /exampleSite/layouts/shortcodes/sprites.html: -------------------------------------------------------------------------------- 1 |
2 | {{ range $key, $value := .Site.Data.sprites.geekblog }} 3 |
4 |
5 | 6 |
7 |
8 | #{{ (replace $key "_" "_") | safeHTML }} 9 |
10 |
11 | {{ end }} 12 |
13 | -------------------------------------------------------------------------------- /exampleSite/static/_includes/example.html.part: -------------------------------------------------------------------------------- 1 |

2 | Example HTML include 3 |

4 | 5 |

This is heading 4

6 |
This is heading 5
7 |
This is heading 6
8 | -------------------------------------------------------------------------------- /exampleSite/static/_includes/example.md.part: -------------------------------------------------------------------------------- 1 | _**Example Mardown include**_ 2 | 3 | File including a simple Markdown table. 4 | 5 | | Head 1 | Head 2 | Head 3 | 6 | | ------ | ------ | ------ | 7 | | 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /exampleSite/static/custom.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --code-max-height: 60rem; 3 | } 4 | 5 | .icon-grid { 6 | width: 8rem; 7 | height: 8rem; 8 | margin: 0.2em; 9 | text-align: center; 10 | padding: 0.3em; 11 | } 12 | 13 | .icon-grid__line { 14 | height: 4rem; 15 | } 16 | 17 | .icon-grid__line svg.gblog-icon { 18 | font-size: 3em; 19 | } 20 | 21 | .icon-grid__line--text { 22 | font-size: 0.8em; 23 | } 24 | -------------------------------------------------------------------------------- /exampleSite/static/custom.css.example: -------------------------------------------------------------------------------- 1 | /* Global customization */ 2 | 3 | :root { 4 | --code-max-height: 60rem; 5 | 6 | 7 | --header-font-family: "DancingScript"; 8 | --body-font-family: "DancingScript"; 9 | --code-font-family: "DancingScript"; 10 | } 11 | 12 | /* Light mode theming */ 13 | :root, 14 | :root[color-theme="light"] { 15 | --header-background: #4ec58a; 16 | --header-font-color: #ffffff; 17 | 18 | --body-background: #ffffff; 19 | --body-font-color: #343a40; 20 | 21 | --mark-color: #ffab00; 22 | 23 | --button-background: #62cb97; 24 | --button-border-color: #4ec58a; 25 | 26 | --link-color: #518169; 27 | --link-color-visited: #c54e8a; 28 | 29 | --code-background: #f5f6f8; 30 | --code-accent-color: #e3e7eb; 31 | --code-accent-color-lite: #eff1f3; 32 | --code-font-color: #5f5f5f; 33 | 34 | --code-copy-background: #f8f9fa; 35 | --code-copy-font-color: #6b7784; 36 | --code-copy-border-color: #adb4bc; 37 | --code-copy-success-color: #00c853; 38 | 39 | --accent-color-dark: #868e96; 40 | --accent-color: #e9ecef; 41 | --accent-color-lite: #f8f9fa; 42 | 43 | --control-icons: #b2bac1; 44 | 45 | --footer-background: #112b3c; 46 | --footer-font-color: #ffffff; 47 | --footer-link-color: #ffcc5c; 48 | --footer-link-color-visited: #ffcc5c; 49 | } 50 | @media (prefers-color-scheme: light) { 51 | :root { 52 | --header-background: #4ec58a; 53 | --header-font-color: #ffffff; 54 | 55 | --body-background: #ffffff; 56 | --body-font-color: #343a40; 57 | 58 | --mark-color: #ffab00; 59 | 60 | --button-background: #62cb97; 61 | --button-border-color: #4ec58a; 62 | 63 | --link-color: #518169; 64 | --link-color-visited: #c54e8a; 65 | 66 | --code-background: #f5f6f8; 67 | --code-accent-color: #e3e7eb; 68 | --code-accent-color-lite: #eff1f3; 69 | --code-font-color: #5f5f5f; 70 | 71 | --code-copy-background: #f8f9fa; 72 | --code-copy-font-color: #6b7784; 73 | --code-copy-border-color: #adb4bc; 74 | --code-copy-success-color: #00c853; 75 | 76 | --accent-color-dark: #868e96; 77 | --accent-color: #e9ecef; 78 | --accent-color-lite: #f8f9fa; 79 | 80 | --control-icons: #b2bac1; 81 | 82 | --footer-background: #112b3c; 83 | --footer-font-color: #ffffff; 84 | --footer-link-color: #ffcc5c; 85 | --footer-link-color-visited: #ffcc5c; 86 | } 87 | } 88 | 89 | /* Dark mode theming */ 90 | :root[color-theme="dark"] { 91 | --header-background: #4ec58a; 92 | --header-font-color: #ffffff; 93 | 94 | --body-background: #343a40; 95 | --body-font-color: #ced3d8; 96 | 97 | --mark-color: #ffab00; 98 | 99 | --button-background: #62cb97; 100 | --button-border-color: #4ec58a; 101 | 102 | --link-color: #7ac29e; 103 | --link-color-visited: #c27a9e; 104 | 105 | --code-background: #f5f6f8; 106 | --code-accent-color: #262b2f; 107 | --code-accent-color-lite: #2b3035; 108 | --code-font-color: #b9b9b9; 109 | 110 | --code-copy-background: #343a40; 111 | --code-copy-font-color: #6b7784; 112 | --code-copy-border-color: #6b7784; 113 | --code-copy-success-color: #37905c; 114 | 115 | --accent-color-dark: #222629; 116 | --accent-color: #2b3035; 117 | --accent-color-lite: #2f353a; 118 | 119 | --control-icons: #b2bac1; 120 | 121 | --footer-background: #112b3c; 122 | --footer-font-color: #ffffff; 123 | --footer-link-color: #ffcc5c; 124 | --footer-link-color-visited: #ffcc5c; 125 | } 126 | @media (prefers-color-scheme: dark) { 127 | :root { 128 | --header-background: #4ec58a; 129 | --header-font-color: #ffffff; 130 | 131 | --body-background: #343a40; 132 | --body-font-color: #ced3d8; 133 | 134 | --mark-color: #ffab00; 135 | 136 | --button-background: #62cb97; 137 | --button-border-color: #4ec58a; 138 | 139 | --link-color: #7ac29e; 140 | --link-color-visited: #c27a9e; 141 | 142 | --code-background: #f5f6f8; 143 | --code-accent-color: #262b2f; 144 | --code-accent-color-lite: #2b3035; 145 | --code-font-color: #b9b9b9; 146 | 147 | --code-copy-background: #343a40; 148 | --code-copy-font-color: #6b7784; 149 | --code-copy-border-color: #6b7784; 150 | --code-copy-success-color: #37905c; 151 | 152 | --accent-color-dark: #222629; 153 | --accent-color: #2b3035; 154 | --accent-color-lite: #2f353a; 155 | 156 | --control-icons: #b2bac1; 157 | 158 | --footer-background: #112b3c; 159 | --footer-font-color: #ffffff; 160 | --footer-link-color: #ffcc5c; 161 | --footer-link-color-visited: #ffcc5c; 162 | } 163 | } 164 | 165 | 166 | @font-face { 167 | font-family: "DancingScript"; 168 | src: 169 | url("fonts/DancingScript.woff2") format("woff2"), 170 | url("fonts/DancingScript.woff") format("woff"); 171 | font-weight: normal; 172 | font-style: normal; 173 | font-display: swap; 174 | } 175 | -------------------------------------------------------------------------------- /exampleSite/static/socialmedia2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/exampleSite/static/socialmedia2.png -------------------------------------------------------------------------------- /images/readme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/images/readme.png -------------------------------------------------------------------------------- /images/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/images/screenshot.png -------------------------------------------------------------------------------- /images/tn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/images/tn.png -------------------------------------------------------------------------------- /layouts/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ partial "head/meta" . }} 5 | Lost? Don't worry 6 | {{ partial "head/favicons" . }} 7 | {{ partial "head/others" . }} 8 | 9 | 10 | 11 | {{ partial "svg-sprites" . }} 12 |
13 | {{ partial "site-header" . }} 14 |
15 |
16 |
17 | 18 |
19 |
20 |
Lost?
21 |
Error 404
22 |
23 | Seems like what you are looking for can't be found. Don't worry we can bring you back 24 | to the homepage. 25 |
26 |
27 |
28 |
29 | {{ partial "site-footer" . }} 30 |
31 | 32 | 33 | -------------------------------------------------------------------------------- /layouts/_default/_markup/render-codeblock-mermaid.html: -------------------------------------------------------------------------------- 1 | 2 | {{ if not (.Page.Scratch.Get "mermaid") }} 3 | 4 | 5 | {{ .Page.Scratch.Set "mermaid" true }} 6 | {{ end }} 7 | 8 | 9 |
10 |   {{- .Inner -}}
11 | 
12 | -------------------------------------------------------------------------------- /layouts/_default/_markup/render-heading.html: -------------------------------------------------------------------------------- 1 | {{- $showAnchor := (and (default true .Page.Params.geekblogAnchor) (default true .Page.Site.Params.geekblogAnchor)) -}} 2 | 3 | 4 | 5 | {{- if $showAnchor -}} 6 |
7 | 11 | {{ .Text | safeHTML }} 12 | 13 | 14 | 15 | 16 |
17 | {{- else -}} 18 |
19 | 23 | {{ .Text | safeHTML }} 24 | 25 |
26 | {{- end -}} 27 | 28 | -------------------------------------------------------------------------------- /layouts/_default/_markup/render-image.html: -------------------------------------------------------------------------------- 1 | {{ .Text }} 6 | {{- /* Drop trailing newlines */ -}} 7 | -------------------------------------------------------------------------------- /layouts/_default/_markup/render-link.html: -------------------------------------------------------------------------------- 1 | {{- $raw := or (hasPrefix .Text " 12 | {{- .Text | safeHTML -}} 13 | 14 | {{- /* Drop trailing newlines */ -}} 15 | -------------------------------------------------------------------------------- /layouts/_default/baseof.html: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | {{ partial "head/meta" . }} 11 | 12 | {{- if eq .Kind "home" -}} 13 | {{ .Site.Title }} 14 | {{- else -}} 15 | {{ printf "%s | %s" (partial "utils/title" .) .Site.Title }} 16 | {{- end -}} 17 | 18 | 19 | {{ partial "head/favicons" . }} 20 | {{ partial "head/rel-me" . }} 21 | {{ partial "head/microformats" . }} 22 | {{ partial "head/others" . }} 23 | {{ partial "head/custom" . }} 24 | 25 | 26 | 27 | {{ partial "svg-sprites" . }} 28 | 29 | 30 |
33 | {{ partial "site-header" . }} 34 | 35 | 36 |
37 | {{ template "main" . }} 38 |
39 | 40 | {{ partial "site-footer" . }} 41 |
42 | 43 | 44 | -------------------------------------------------------------------------------- /layouts/_default/list.atom.xml: -------------------------------------------------------------------------------- 1 | {{ printf `` | safeHTML }} 2 | 3 | Hugo 4 | {{- $title := .Site.Title -}} 5 | {{- if not (eq .Kind "home") }} 6 | {{- $title = printf `%s on %s` (partial "utils/title" .) $title -}} 7 | {{- end }} 8 | {{ $title }} 9 | {{- with .Site.Params.subtitle }} 10 | {{ . }} 11 | {{- end }} 12 | {{- $output_formats := .OutputFormats -}} 13 | {{- range $output_formats -}} 14 | {{- $rel := (or (and (eq "atom" (.Name | lower)) "self") "alternate") -}} 15 | {{- with $output_formats.Get .Name }} 16 | {{ printf `` .Permalink $rel .MediaType.Type .Name | safeHTML }} 17 | {{- end }} 18 | {{- end }} 19 | {{ now.Format "2006-01-02T15:04:05-07:00" | safeHTML }} 20 | {{- with .Site.Params.geekblogAuthor -}} 21 | {{- with index $.Site.Data.authors . }} 22 | 23 | {{ .name }} 24 | {{- with .email }} 25 | {{ . }} 26 | {{- end }} 27 | 28 | {{- end }} 29 | {{- end }} 30 | {{ .Permalink }} 31 | {{- $pages := where .RegularPages "Type" "in" .Site.Params.mainSections -}} 32 | {{- if (eq .Kind "home") -}} 33 | {{- $pages = where .Site.RegularPages "Type" "in" .Site.Params.mainSections -}} 34 | {{- end -}} 35 | {{- range $page := $pages }} 36 | 37 | {{ partial "utils/title" . }} 38 | 39 | {{ .Permalink }} 40 | {{- with .Params.authors }} 41 | {{- range sort . }} 42 | {{- $author := index $.Site.Data.authors . }} 43 | 44 | {{ $author.name }} 45 | 46 | {{- end }} 47 | {{- end }} 48 | {{ .Date.Format "2006-01-02T15:04:05-07:00" | safeHTML }} 49 | {{ .Lastmod.Format "2006-01-02T15:04:05-07:00" | safeHTML }} 50 | {{- $img := "" -}} 51 | {{- with ($page.Resources.ByType "image").GetMatch "{*feature*,*cover*,*thumbnail*}" }} 52 | {{- $featured := .Fill (printf "910x280 %s" (default "Smart" .Params.anchor)) -}} 53 | {{- $img = printf `%s
` $featured.Permalink $featured.Width $featured.Height (default (partial "utils/title" $page) .Params.description) -}} 54 | {{- end }} 55 | 56 | {{ printf "%s%s" $img .Content | htmlEscape | safeHTML }} 57 | 58 | {{- with .Site.Taxonomies }} 59 | {{- range $taxo,$_ := . }} 60 | {{- with $page.Param $taxo }} 61 | {{- $taxo_list := . -}} 62 | {{- with $.Site.GetPage (printf "/%s" $taxo) }} 63 | {{- $taxonomy_page := . -}} 64 | {{- range $taxo_list }} 65 | 66 | {{- end }} 67 | {{- end }} 68 | {{- end }} 69 | {{- end }} 70 | {{- end }} 71 |
72 | {{- end }} 73 |
74 | -------------------------------------------------------------------------------- /layouts/_default/list.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 | {{ $pages := where .RegularPages "Type" "in" .Site.Params.mainSections }} 3 | {{ if (eq .Kind "home") }} 4 | {{ $pages = where .Site.RegularPages "Type" "in" .Site.Params.mainSections }} 5 | {{ end }} 6 | 7 | {{ $paginator := .Paginate $pages }} 8 | {{ range $paginator.Pages }} 9 | 38 | {{ end }} 39 | {{ partial "pagination.html" . }} 40 | {{ end }} 41 | -------------------------------------------------------------------------------- /layouts/_default/list.json.json: -------------------------------------------------------------------------------- 1 | {{- $title := .Site.Title -}} 2 | {{- if not (eq .Kind "home") -}} 3 | {{- $title = printf `%s on %s` (partial "utils/title" .) $title -}} 4 | {{- end -}} 5 | { 6 | "version": "https://jsonfeed.org/version/1.1", 7 | "title": {{ $title | jsonify }}, 8 | {{- with .Site.Params.subtitle }} 9 | "description": {{ . | jsonify }}, 10 | {{- end }} 11 | "home_page_url" : "{{ .Site.Home.Permalink }}", 12 | {{- with .OutputFormats.Get "json" }} 13 | "feed_url" : "{{ .Permalink }}", 14 | {{- end }} 15 | {{- with .Site.Params.geekblogAuthor -}} 16 | {{ with index $.Site.Data.authors . }} 17 | "authors" : [ 18 | { 19 | "name" : "{{ .name }}"{{ with .url }}, 20 | "url": "{{ . }}"{{ end }}{{ with .avatar }}, 21 | "avatar": "{{ . }}"{{ end }} 22 | } 23 | ], 24 | {{- end }} 25 | {{- end }} 26 | "items" : [ 27 | {{- $pages := where .RegularPages "Type" "in" .Site.Params.mainSections -}} 28 | {{- if (eq .Kind "home") -}} 29 | {{- $pages = where .Site.RegularPages "Type" "in" .Site.Params.mainSections -}} 30 | {{- end -}} 31 | {{- $len := (len $pages) }} 32 | {{- range $i, $page := $pages }} 33 | { 34 | "title" : {{ (partial "utils/title" .) | jsonify }}, 35 | "date_published" : {{ (.Date.Format "2006-01-02T15:04:05Z07:00") | jsonify }}, 36 | "date_modified" : {{ (.Lastmod.Format "2006-01-02T15:04:05Z07:00") | jsonify }}, 37 | "id" : "{{ .Permalink }}", 38 | "url" : "{{ .Permalink }}", 39 | {{- with ($page.Resources.ByType "image").GetMatch "{*feature*,*cover*,*thumbnail*}" }} 40 | {{- $featured := .Fill (printf "910x280 %s" (default "Smart" .Params.anchor)) -}} 41 | "image" : "{{ $featured.Permalink }}", 42 | {{- end }} 43 | {{- with .Params.authors -}} 44 | "authors" : [ 45 | {{- $authors := (sort .) }} 46 | {{- $authors_len := (len $authors) }} 47 | {{- range $i, $element := $authors -}} 48 | {{- $author := index $.Site.Data.authors $element }} 49 | { 50 | "name" : "{{ $author.name }}" 51 | }{{ if ne (add $i 1) $authors_len }},{{ end }} 52 | {{- end }} 53 | ], 54 | {{- end }} 55 | "content_html" : {{ .Content | jsonify }} 56 | }{{ if ne (add $i 1) $len }},{{ end }} 57 | {{- end }} 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /layouts/_default/single.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
3 |
4 | {{ $source := ($.Resources.ByType "image").GetMatch "{*feature*,*cover*,*thumbnail*}" }} 5 | {{ with $source }} 6 |
7 | 8 | {{ $featured := .Fill (printf "910x280 %s" (default "Smart" .Params.anchor)) }} 9 | 10 | {{ default (partial 14 | 15 | {{ with $source.Params.credits }} 16 | Credits: {{ . | $.Page.RenderString | safeHTML }} 17 | {{ end }} 18 |
19 | {{ end }} 20 | 21 | 22 |

{{ partial "utils/title" . }}

23 | 24 | {{ if or (eq .Type (default "posts" .Site.Params.geekblogContentSection)) (eq .Type "post") }} 25 | 28 | {{ end }} 29 |
30 |
31 | {{ partial "utils/content" . }} 32 |
33 |
34 | {{ end }} 35 | -------------------------------------------------------------------------------- /layouts/_default/sitemap.xml: -------------------------------------------------------------------------------- 1 | {{ printf "" | safeHTML }} 2 | 4 | {{- $seoIgnore := default (slice "taxonomy" "section" "term" "404") .Site.Params.geekblogSeoIgnore -}} 5 | {{- range .Data.Pages }} 6 | {{- if and .Permalink (not (in $seoIgnore .Kind)) }} 7 | 8 | {{ .Permalink }} 9 | {{- if not .Lastmod.IsZero }} 10 | {{ safeHTML ( .Lastmod.Format "2006-01-02T15:04:05-07:00" ) }} 11 | {{- end }} 12 | {{- with .Sitemap.ChangeFreq }} 13 | {{ . }}{{ end }} 14 | {{- if ge .Sitemap.Priority 0.0 }} 15 | {{ .Sitemap.Priority }} 16 | {{- end }} 17 | {{- if .IsTranslated }} 18 | {{- range .Translations }} 19 | 24 | {{- end }} 25 | 30 | {{- end }} 31 | 32 | {{- end -}} 33 | {{ end }} 34 | 35 | -------------------------------------------------------------------------------- /layouts/_default/terms.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 | {{ $paginator := .Paginate .Paginator.Pages }} 3 | {{ range $paginator.Pages.ByTitle }} 4 |
5 |
6 |

7 | {{ partial "utils/title" . }} 8 |

9 |
10 | 11 |
12 | 13 | {{ $pageCount := len .Pages }} 14 | 15 | 19 | 20 | 21 | 22 | 23 | 24 | {{ $latet := index .Pages.ByDate 0 }} 25 | {{ with $latet }} 26 | {{ partial "utils/title" . }} 27 | {{ end }} 28 | by 29 | {{ $ac := 0 }} 30 | {{ with $latet.Params.authors }} 31 | {{ range sort . }} 32 | {{ $author := index $.Site.Data.authors . }} 33 | {{ with $.Site.GetPage (printf "/authors/%s" . | urlize) }} 34 | {{ if eq $ac 0 }} 35 | {{ template "post-author" dict "name" $author.name "page" . }} 36 | {{ else }} 37 | {{ template "post-author" dict "name" $author.name "page" . }} 38 | {{ end }} 39 | {{ end }} 40 | {{ $ac = (add $ac 1) }} 41 | {{ end }} 42 | {{ end }} 43 | 44 | 45 |
46 |
47 | {{ end }} 48 | {{ partial "pagination.html" . }} 49 | {{ end }} 50 | -------------------------------------------------------------------------------- /layouts/partials/head/custom.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /layouts/partials/head/favicons.html: -------------------------------------------------------------------------------- 1 | 2 | 8 | 14 | -------------------------------------------------------------------------------- /layouts/partials/head/meta.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ hugo.Generator }} 5 | 6 | {{- $keywords := default .Site.Params.Keywords .Keywords -}} 7 | {{- $authors := default (slice .Site.Params.geekblogAuthor) .Params.authors -}} 8 | {{- $seoIgnore := default (slice "taxonomy" "section" "term" "404") .Site.Params.geekblogSeoIgnore -}} 9 | 10 | {{- if not (in $seoIgnore .Kind) }} 11 | 12 | {{- else }} 13 | 14 | {{- end }} 15 | {{- with partial "utils/description" . }} 16 | 17 | {{- end }} 18 | {{- with $keywords }} 19 | 20 | {{- end }} 21 | {{- with $authors }} 22 | {{- $list := slice -}} 23 | {{- range sort . }} 24 | {{- with . }} 25 | {{- $author := index $.Site.Data.authors . -}} 26 | {{- $list = $list | append $author.name -}} 27 | {{- end }} 28 | {{- end }} 29 | {{- with $list }} 30 | 31 | {{- end }} 32 | {{- end }} 33 | -------------------------------------------------------------------------------- /layouts/partials/head/microformats.html: -------------------------------------------------------------------------------- 1 | {{ partial "microformats/opengraph.html" . }} 2 | {{ partial "microformats/twitter_cards.html" . }} 3 | {{ partial "microformats/schema.html" . }} 4 | -------------------------------------------------------------------------------- /layouts/partials/head/others.html: -------------------------------------------------------------------------------- 1 | {{- if default true .Site.Params.geekblogDarkModeToggle }} 2 | 3 | {{- end }} 4 | 5 | 6 | 13 | 20 | 27 | 28 | 33 | 38 | 39 | 44 | 49 | 50 | 55 | 60 | 61 | 66 | 71 | {{- with .OutputFormats.Get "html" }} 72 | {{ printf `` .Permalink .Rel .MediaType.Type | safeHTML }} 73 | {{- end }} 74 | {{- $output_formats := (.Site.GetPage "home").OutputFormats }} 75 | {{- range $format := (.Site.GetPage "home").OutputFormats }} 76 | {{- if not (eq $format.Rel "canonical") }} 77 | {{ printf `` $format.Permalink $format.Rel $format.MediaType.Type $.Site.Title $format.Name | safeHTML }} 78 | {{- end }} 79 | {{- end }} 80 | 81 | {{- if (default false $.Site.Params.geekblogOverwriteHTMLBase) }} 82 | 83 | {{- end }} 84 | 85 | {{ printf "" "Made with Geekblog theme https://github.com/thegeeklab/hugo-geekblog" | safeHTML }} 86 | -------------------------------------------------------------------------------- /layouts/partials/head/rel-me.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /layouts/partials/menu-extra.html: -------------------------------------------------------------------------------- 1 | {{ $current := .current }} 2 | {{ template "menu-file" dict "sect" .source "current" $current "site" $current.Site "target" .target }} 3 | 4 | 5 | 6 | {{ define "menu-file" }} 7 | {{ $current := .current }} 8 | {{ $site := .site }} 9 | {{ $target := .target }} 10 | 11 | {{ range sort (default (seq 0) .sect) "weight" }} 12 | {{ if isset . "ref" }} 13 | {{ $this := $site.GetPage .ref }} 14 | {{ $isCurrent := eq $current $this }} 15 | {{ $icon := default false .icon }} 16 | 17 | {{ if eq $target "footer" }} 18 | 19 | {{ if $icon }} 20 | 21 | {{ end }} 22 | 30 | {{ .name }} 31 | 32 | 33 | {{ else if eq $target "header" }} 34 |
  • 35 | 43 | 44 | {{ if $icon }} 45 | 46 | {{ end }} 47 | 48 | {{ .name }} 49 | 50 | 51 | 52 |
  • 53 | {{ end }} 54 | {{ end }} 55 | {{ end }} 56 | {{ end }} 57 | -------------------------------------------------------------------------------- /layouts/partials/metadata.html: -------------------------------------------------------------------------------- 1 | 12 | 13 | 17 | 18 | {{ if eq .Params.weight 1 }} 19 | 23 | {{ end }} 24 | 25 | {{ $ac := 0 }} 26 | {{ with .Params.authors }} 27 | {{ range sort . }} 28 | {{ $author := index $.Site.Data.authors . }} 29 | {{ with $.Site.GetPage (printf "/authors/%s" . | urlize) }} 30 | {{ if eq $ac 0 }} 31 | 35 | {{ else }} 36 | 39 | {{ end }} 40 | {{ end }} 41 | {{ $ac = (add $ac 1) }} 42 | {{ end }} 43 | {{ end }} 44 | 45 | {{ $tc := 0 }} 46 | {{ with .Params.tags }} 47 | {{ range sort . }} 48 | {{ $name := . }} 49 | {{ with $.Site.GetPage (printf "/tags/%s" $name | urlize) }} 50 | {{ if eq $tc 0 }} 51 | 55 | {{ else }} 56 | 59 | {{ end }} 60 | {{ end }} 61 | {{ $tc = (add $tc 1) }} 62 | {{ end }} 63 | {{ end }} 64 | 65 | {{ define "post-tag" }} 66 | 75 | {{ end }} 76 | 77 | {{ define "post-author" }} 78 | 83 | {{ end }} 84 | -------------------------------------------------------------------------------- /layouts/partials/microformats/opengraph.html: -------------------------------------------------------------------------------- 1 | {{- if not (eq .Kind "home") }} 2 | 6 | {{- end }} 7 | {{- with .Site.Title }} 8 | 9 | {{- end }} 10 | {{- with partial "utils/featured" . }} 11 | 12 | {{- end }} 13 | {{- with partial "utils/description" . }} 14 | 15 | {{- end }} 16 | 17 | 18 | {{- with .Params.audio }} 19 | 20 | {{- end }} 21 | {{- with .Params.locale }} 22 | 23 | {{- end }} 24 | {{- with .Params.videos }} 25 | {{- range . }} 26 | 27 | {{- end }} 28 | {{- end }} 29 | 30 | {{- /* If it is part of a series, link to related articles */}} 31 | {{- if .Site.Taxonomies.series }} 32 | {{- $permalink := .Permalink -}} 33 | {{- $siteSeries := .Site.Taxonomies.series -}} 34 | {{- with .Params.series }} 35 | {{- range $name := . }} 36 | {{- $series := index $siteSeries ($name | urlize) }} 37 | {{- range $page := first 6 $series.Pages }} 38 | {{- if ne $page.Permalink $permalink }} 39 | 40 | {{- end }} 41 | {{- end }} 42 | {{- end }} 43 | {{- end }} 44 | {{- end }} 45 | 46 | {{ if .IsPage -}} 47 | {{- $iso8601 := "2006-01-02T15:04:05-07:00" -}} 48 | 49 | {{- with .PublishDate }} 50 | 54 | {{- end }} 55 | {{- with .Lastmod }} 56 | 60 | {{- end }} 61 | {{- end }} 62 | 63 | {{- /* Facebook Page Admin ID for Domain Insights */}} 64 | {{- with .Site.Params.facebook_admin }} 65 | 66 | {{- end }} 67 | -------------------------------------------------------------------------------- /layouts/partials/microformats/schema.html: -------------------------------------------------------------------------------- 1 | {{- if eq .Kind "home" }} 2 | 23 | {{- else if .IsPage }} 24 | {{- $authors := default (slice .Site.Params.geekblogAuthor) .Params.authors -}} 25 | {{- $ac := 0 -}} 26 | {{- $ac_max := default 0 (len $authors) -}} 27 | 28 | 90 | {{- end }} 91 | -------------------------------------------------------------------------------- /layouts/partials/microformats/twitter_cards.html: -------------------------------------------------------------------------------- 1 | {{- with partial "utils/featured" . }} 2 | 3 | {{- else }} 4 | 5 | {{- end }} 6 | 7 | {{- with partial "utils/featured" . }} 8 | 9 | {{- end }} 10 | {{- with partial "utils/description" . }} 11 | 12 | {{- end }} 13 | {{- with .Site.Params.twitter -}} 14 | 15 | {{- end }} 16 | -------------------------------------------------------------------------------- /layouts/partials/pagination.html: -------------------------------------------------------------------------------- 1 | {{ $pag := $.Paginator }} 2 | 3 | 4 | 23 | -------------------------------------------------------------------------------- /layouts/partials/site-footer.html: -------------------------------------------------------------------------------- 1 |
    2 | 60 |
    61 | -------------------------------------------------------------------------------- /layouts/partials/site-header.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 | 19 |
    20 | 21 | 22 | {{ i18n "button_toggle_dark" }} 23 | 24 | 25 | 26 | {{ i18n "button_toggle_dark" }} 27 | 28 | 29 | 30 | {{ i18n "button_toggle_dark" }} 31 | 32 | 33 | 34 |
    35 |
    36 |
    37 | 69 | -------------------------------------------------------------------------------- /layouts/partials/svg-sprites.html: -------------------------------------------------------------------------------- 1 | {{ range resources.Match "sprites/*.svg" }} 2 | {{ printf "" . | safeHTML }} 3 | {{ .Content | safeHTML }} 4 | {{ end }} 5 | -------------------------------------------------------------------------------- /layouts/partials/utils/content.html: -------------------------------------------------------------------------------- 1 | {{ $html := .Content }} 2 | 3 | {{ $html = $html | replaceRE `` `` | safeHTML }} 4 | {{ $html = $html | replaceRE `((?:.|\n)+?
    )` `
    ${1}
    ` | safeHTML }} 5 | 6 | {{ return $html }} 7 | -------------------------------------------------------------------------------- /layouts/partials/utils/description.html: -------------------------------------------------------------------------------- 1 | {{ $description := "" }} 2 | 3 | {{ if .Description }} 4 | {{ $description = .Description }} 5 | {{ else }} 6 | {{ if .IsPage }} 7 | {{ $description = .Summary }} 8 | {{ else if .Site.Params.description }} 9 | {{ $description = .Site.Params.description }} 10 | {{ end }} 11 | {{ end }} 12 | 13 | {{ return $description }} 14 | -------------------------------------------------------------------------------- /layouts/partials/utils/featured.html: -------------------------------------------------------------------------------- 1 | {{ $img := "" }} 2 | 3 | {{ with $source := ($.Resources.ByType "image").GetMatch "{*feature*,*cover*,*thumbnail*}" }} 4 | {{ $featured := .Fill (printf "1200x630 %s" (default "Smart" .Params.anchor)) }} 5 | {{ $img = $featured.Permalink }} 6 | {{ else }} 7 | {{ with default $.Site.Params.images $.Params.images }} 8 | {{ $img = index . 0 | absURL }} 9 | {{ end }} 10 | {{ end }} 11 | 12 | {{ return $img }} 13 | -------------------------------------------------------------------------------- /layouts/partials/utils/title.html: -------------------------------------------------------------------------------- 1 | {{ $title := "" }} 2 | 3 | {{ if .Title }} 4 | {{ $title = .Title }} 5 | {{ else if and .IsSection .File }} 6 | {{ $title = path.Base .File.Dir | humanize | title }} 7 | {{ else if and .IsPage .File }} 8 | {{ $title = .File.BaseFileName | humanize | title }} 9 | {{ end }} 10 | 11 | {{ if eq .Kind "term" }} 12 | {{ $title = $title | humanize | title }} 13 | {{ end }} 14 | 15 | {{ return $title }} 16 | -------------------------------------------------------------------------------- /layouts/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: /categories/* 3 | Disallow: /tags/* 4 | Sitemap: {{ "sitemap.xml" | absURL }} 5 | -------------------------------------------------------------------------------- /layouts/shortcodes/avatar.html: -------------------------------------------------------------------------------- 1 | {{- $source := ($.Page.Resources.ByType "image").GetMatch (printf "%s" (.Get "name")) }} 2 | {{- $customAlt := .Get "alt" }} 3 | {{- $customSize := .Get "size" | lower }} 4 | {{- $customAnchor := default "smart" (.Get "anchor") | title }} 5 | {{- $data := newScratch }} 6 | 7 | {{- with $source }} 8 | {{- $caption := default .Title $customAlt }} 9 | {{- $isSVG := (eq .MediaType.SubType "svg") }} 10 | {{- $origin := . -}} 11 | 12 | {{- if $isSVG }} 13 | {{- $data.SetInMap "size" "tiny" "160" }} 14 | {{- $data.SetInMap "size" "small" "300" }} 15 | {{- $data.SetInMap "size" "medium" "600" }} 16 | {{- $data.SetInMap "size" "large" "900" }} 17 | {{- else }} 18 | {{- $data.SetInMap "size" "tiny" (printf "160x160 %s" $customAnchor) }} 19 | {{- $data.SetInMap "size" "small" (printf "300x300 %s" $customAnchor) }} 20 | {{- $data.SetInMap "size" "medium" (printf "600x600 %s" $customAnchor) }} 21 | {{- $data.SetInMap "size" "large" (printf "900x900 %s" $customAnchor) }} 22 | {{- end -}} 23 | 24 | 57 | {{- end }} 58 | -------------------------------------------------------------------------------- /layouts/shortcodes/box.html: -------------------------------------------------------------------------------- 1 | {{ if .Parent }} 2 | {{- $group := printf "grid-%s" (.Parent.Get 0) }} 3 | {{- $class := default "" (.Get "class") }} 4 | {{- $size := default "regular" (.Get "size" | lower) }} 5 | {{- $icon := default "" (.Get "icon") }} 6 | {{- $title := default "" (.Get "title") }} 7 | 8 | {{- if not (in (slice "regular" "large") $size) }} 9 | {{- $size = "regular" }} 10 | {{- end }} 11 | 12 | {{ if not (.Parent.Scratch.Get $group) }} 13 | {{ .Parent.Scratch.Set $group slice }} 14 | {{ end }} 15 | 16 | {{ .Parent.Scratch.Add $group (dict "Class" $class "Size" $size "Icon" $icon "Title" $title "Content" .Inner) }} 17 | {{ else }} 18 | {{ errorf "%q: 'box' shortcode must be inside 'boxes' shortcode" .Page.Path }} 19 | {{ end }} 20 | -------------------------------------------------------------------------------- /layouts/shortcodes/boxes.html: -------------------------------------------------------------------------------- 1 | {{- if .Inner }}{{ end }} 2 | {{- $id := .Get 0 }} 3 | {{- $group := printf "grid-%s" $id }} 4 | 5 | 6 |
    7 | {{- range $index, $box := .Scratch.Get $group }} 8 |
    12 | {{ if or $box.Title $box.Icon }} 13 |
    14 | {{- with $box.Icon }} 15 | 16 | {{- end }} 17 | {{ with $box.Title }}{{ . }}{{ end }} 18 |
    19 | {{ end }} 20 |
    21 | {{ .Content | $.Page.RenderString }} 22 |
    23 |
    24 | {{- end }} 25 |
    26 | -------------------------------------------------------------------------------- /layouts/shortcodes/button.html: -------------------------------------------------------------------------------- 1 | {{- $ref := "" }} 2 | {{- $class := "" }} 3 | {{- $size := default "regular" (.Get "size" | lower) }} 4 | 5 | {{- if not (in (slice "regular" "large") $size) }} 6 | {{- $size = "regular" }} 7 | {{- end }} 8 | 9 | {{- with .Get "href" }} 10 | {{- $ref = . }} 11 | {{- end }} 12 | 13 | {{- with .Get "relref" }} 14 | {{- $ref = relref $ . }} 15 | {{- end }} 16 | 17 | {{- with .Get "class" }} 18 | {{- $class = . }} 19 | {{- end }} 20 | 21 | 22 | 23 | 27 | {{ $.Inner }} 28 | 29 | 30 | -------------------------------------------------------------------------------- /layouts/shortcodes/columns.html: -------------------------------------------------------------------------------- 1 | {{- $size := default "regular" (.Get "size" | lower) }} 2 | 3 | {{- if not (in (slice "regular" "large" "small") $size) }} 4 | {{- $size = "regular" }} 5 | {{- end }} 6 | 7 | 8 |
    9 | {{- range split .Inner "<--->" }} 10 |
    11 | {{ . | $.Page.RenderString -}} 12 |
    13 | {{- end }} 14 |
    15 | -------------------------------------------------------------------------------- /layouts/shortcodes/emojify.html: -------------------------------------------------------------------------------- 1 | {{ .Get 0 | emojify }} 2 | -------------------------------------------------------------------------------- /layouts/shortcodes/expand.html: -------------------------------------------------------------------------------- 1 | {{ $id := substr (sha1 .Inner) 0 8 }} 2 |
    3 | 7 | 8 |
    9 | {{ .Inner | $.Page.RenderString }} 10 |
    11 |
    12 | -------------------------------------------------------------------------------- /layouts/shortcodes/hint.html: -------------------------------------------------------------------------------- 1 | {{- $type := default "note" (.Get "type") -}} 2 | {{- $icon := .Get "icon" -}} 3 | {{- $title := default ($type | title) (.Get "title") }} 4 | 5 | 6 |
    7 |
    8 | {{- with $icon -}} 9 | 10 | {{ $title }} 11 | {{- else -}} 12 | 13 | {{- end -}} 14 |
    15 |
    {{ .Inner | $.Page.RenderString }}
    16 |
    17 | -------------------------------------------------------------------------------- /layouts/shortcodes/icon.html: -------------------------------------------------------------------------------- 1 | {{ $id := .Get 0 }} 2 | 3 | {{- with $id -}} 4 | 5 | {{- end -}} 6 | -------------------------------------------------------------------------------- /layouts/shortcodes/img.html: -------------------------------------------------------------------------------- 1 | {{- $source := ($.Page.Resources.ByType "image").GetMatch (printf "%s" (.Get "name")) }} 2 | {{- $customAlt := .Get "alt" }} 3 | {{- $customSize := .Get "size" | lower }} 4 | {{- $lazyLoad := default (default true $.Site.Params.geekblogImageLazyLoading) (.Get "lazy") }} 5 | {{- $data := newScratch }} 6 | 7 | {{- with $source }} 8 | {{- $caption := default .Title $customAlt }} 9 | {{- $isSVG := (eq .MediaType.SubType "svg") }} 10 | {{- $origin := . }} 11 | 12 | {{- if $isSVG }} 13 | {{- $data.SetInMap "size" "tiny" "320" }} 14 | {{- $data.SetInMap "size" "small" "600" }} 15 | {{- $data.SetInMap "size" "medium" "1200" }} 16 | {{- $data.SetInMap "size" "large" "1800" }} 17 | {{- else }} 18 | {{- $data.SetInMap "size" "tiny" "320x"}} 19 | {{- $data.SetInMap "size" "small" "600x" }} 20 | {{- $data.SetInMap "size" "medium" "1200x" }} 21 | {{- $data.SetInMap "size" "large" "1800x" }} 22 | {{- end -}} 23 | 24 |
    25 |
    26 | 27 | 28 | {{- $size := $data.Get "size" }} 29 | {{- if not $isSVG }} 30 | {{- if ne $customSize "origin" }} 31 | 38 | {{- end }} 39 | {{- end }} 40 | {{ $caption }} 53 | 54 | 55 | {{- with $caption }} 56 |
    57 | {{ . }} 58 | {{- with $source.Params.credits }} 59 | {{ printf " (%s)" . | $.Page.RenderString }} 60 | {{- end }} 61 |
    62 | {{- end }} 63 |
    64 |
    65 | {{- end }} 66 | -------------------------------------------------------------------------------- /layouts/shortcodes/include.html: -------------------------------------------------------------------------------- 1 | {{ $file := .Get "file" }} 2 | {{ $page := .Site.GetPage $file }} 3 | {{ $type := .Get "type" }} 4 | {{ $language := .Get "language" }} 5 | {{ $options :=.Get "options" }} 6 | 7 | 8 |
    9 | {{- if (.Get "language") -}} 10 | {{- highlight ($file | readFile) $language (default "linenos=table" $options) -}} 11 | {{- else if eq $type "html" -}} 12 | {{- $file | readFile | safeHTML -}} 13 | {{- else if eq $type "page" -}} 14 | {{- with $page }}{{ .Content }}{{ end -}} 15 | {{- else -}} 16 | {{- $file | readFile | $.Page.RenderString -}} 17 | {{- end -}} 18 |
    19 | -------------------------------------------------------------------------------- /layouts/shortcodes/katex.html: -------------------------------------------------------------------------------- 1 | 2 | {{ if not (.Page.Scratch.Get "katex") }} 3 | 4 | 8 | 9 | {{ .Page.Scratch.Set "katex" true }} 10 | {{ end }} 11 | 12 | 13 | 14 | {{ cond (in .Params "display") "\\[" "\\(" -}} 15 | {{- trim .Inner "\n" -}} 16 | {{- cond (in .Params "display") "\\]" "\\)" -}} 17 | 18 | {{- /* Drop trailing newlines */ -}} 19 | -------------------------------------------------------------------------------- /layouts/shortcodes/mermaid.html: -------------------------------------------------------------------------------- 1 | 2 | {{ if not (.Page.Scratch.Get "mermaid") }} 3 | 4 | 5 | {{ .Page.Scratch.Set "mermaid" true }} 6 | {{ end }} 7 | 8 | 9 |
    10 |   {{- .Inner -}}
    11 | 
    12 | -------------------------------------------------------------------------------- /layouts/shortcodes/progress.html: -------------------------------------------------------------------------------- 1 | {{- $value := default 0 (.Get "value") -}} 2 | {{- $label := default (printf "%v %%" $value) (.Get "label") -}} 3 | {{- $title := .Get "title" -}} 4 | {{- $icon := .Get "icon" -}} 5 | 6 | 7 |
    8 |
    9 |
    10 | {{ with $icon -}} 11 | 12 | {{- end }} 13 | {{ with $title }}{{ . }}{{ end }} 14 |
    15 |
    {{ $label }}
    16 |
    17 |
    18 |
    23 |
    24 |
    25 | -------------------------------------------------------------------------------- /layouts/shortcodes/propertylist.html: -------------------------------------------------------------------------------- 1 | {{- $name := .Get "name" -}} 2 | {{- $sort := .Get "sort" -}} 3 | {{- $order := default "asc" (.Get "order") -}} 4 | {{- $showAnchor := (and (default true .Page.Params.geekblogAnchor) (default true .Page.Site.Params.geekblogAnchor)) -}} 5 | 6 | {{- if .Site.Data.properties }} 7 |
    8 | {{- with (index .Site.Data.properties (split $name ".")) }} 9 | {{- $properties := .properties }} 10 | {{- with $sort }} 11 | {{- $properties = (sort $properties . $order) }} 12 | {{- end }} 13 | {{- range $properties }} 14 | {{- $uniqueAnchor := anchorize (printf "%s-%s" $name .name) | safeHTML }} 15 |
    16 | {{ .name }} 17 | {{- if .required }} 18 | required 19 | {{- else }} 20 | optional 21 | {{- end }} 22 | {{- with .type }} 23 | {{ . }} 24 | {{- end }} 25 | 26 | {{- with .tags }} 27 | {{- range . }} 28 | {{ . }} 29 | {{- end }} 30 | {{- end }} 31 | {{- if $showAnchor }} 32 | 33 | 34 | 35 | {{- end }} 36 |
    37 |
    38 |
    39 | {{- with .description }} 40 | {{ . | $.Page.RenderString }} 41 | {{- end }} 42 |
    43 |
    44 | {{- with default "none" (.defaultValue | string) }} 45 | Default: 46 | {{ . }} 47 | {{- end }} 48 |
    49 |
    50 | {{- end }} 51 | {{- end }} 52 |
    53 | {{- end }} 54 | -------------------------------------------------------------------------------- /layouts/shortcodes/tab.html: -------------------------------------------------------------------------------- 1 | {{- if .Parent }} 2 | {{- $name := .Get 0 }} 3 | {{- $group := printf "tabs-%s" (.Parent.Get 0) }} 4 | 5 | {{- if not (.Parent.Scratch.Get $group) }} 6 | {{- .Parent.Scratch.Set $group slice }} 7 | {{- end }} 8 | 9 | {{- .Parent.Scratch.Add $group (dict "Name" $name "Content" .Inner) }} 10 | {{- else }} 11 | {{ errorf "%q: 'tab' shortcode must be inside 'tabs' shortcode" .Page.Path }} 12 | {{- end }} 13 | -------------------------------------------------------------------------------- /layouts/shortcodes/tabs.html: -------------------------------------------------------------------------------- 1 | {{- if .Inner }}{{ end }} 2 | {{- $id := .Get 0 }} 3 | {{- $group := printf "tabs-%s" $id }} 4 | 5 | 6 |
    7 | {{- range $index, $tab := .Scratch.Get $group }} 8 | 15 | 18 |
    19 | {{ .Content | $.Page.RenderString }} 20 |
    21 | {{- end }} 22 |
    23 | -------------------------------------------------------------------------------- /layouts/shortcodes/toc.html: -------------------------------------------------------------------------------- 1 | {{ $tocLevels := default (default 6 .Site.Params.geekblogToC) .Page.Params.geekblogToC }} 2 | 3 | {{ if and $tocLevels .Page.TableOfContents }} 4 |
    5 | {{ .Page.TableOfContents }} 6 |
    7 |
    8 | {{ end }} 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "geekblog", 3 | "version": "1.0.0", 4 | "description": "Hugo theme made for blogs", 5 | "main": "index.js", 6 | "type": "module", 7 | "scripts": { 8 | "build": "run-s prep:clean prep:make svg build:webpack", 9 | "build:webpack": "webpack --mode=production", 10 | "build:webpack-devel": "webpack --mode=development", 11 | "pack": "tar -zcvf dist/hugo-geekblog.tar.gz -X .tarignore .", 12 | "start": "run-s prep:clean prep:make svg build:webpack-devel ; run-p start:webpack start:hugo", 13 | "start:webpack": "webpack --mode=development --watch", 14 | "start:build": "webpack --mode=development", 15 | "start:hugo": "hugo server -D -F -s exampleSite/", 16 | "svg": "run-s svg:*", 17 | "svg:sprite": "svg-sprite -C svgsprite.config.json 'src/icons/*.svg'", 18 | "svg:font": "svgtofont --sources build/icons/ --output build/fonts/", 19 | "prep:clean": "shx rm -rf build/ static/", 20 | "prep:clean-all": "shx rm -rf VERSION .lighthouseci/ lhci_reports/ build/ dist/ static/ data/ assets/sprites/ exampleSite/data/sprites/ exampleSite/public/ exampleSite/resources/ exampleSite/.hugo_build.lock", 21 | "prep:make": "shx mkdir -p build/icons/ build/fonts/ dist/", 22 | "svg-sprite-list": "run-s prep:make svg ; shx mkdir -p exampleSite/data/sprites/ ; shx cp build/fonts/GeekblogIcons.json exampleSite/data/sprites/geekblog.json", 23 | "lint": "run-p lint:js lint:html", 24 | "lint:js": "eslint src/js/ --color", 25 | "lint:html": "html-validate exampleSite/public" 26 | }, 27 | "repository": { 28 | "type": "git", 29 | "url": "https://github.com/thegeeklab/hugo-geekblog" 30 | }, 31 | "author": "Robert Kaussow", 32 | "license": "MIT", 33 | "engines": { 34 | "node": ">=18 <=22" 35 | }, 36 | "dependencies": { 37 | "clipboard": "2.0.11", 38 | "katex": "0.16.22", 39 | "mermaid": "11.6.0", 40 | "store2": "2.14.4" 41 | }, 42 | "devDependencies": { 43 | "@babel/eslint-parser": "7.27.1", 44 | "@eloquent/git-version-webpack-plugin": "5.0.1", 45 | "autoprefixer": "10.4.21", 46 | "copy-webpack-plugin": "13.0.0", 47 | "css-loader": "7.1.2", 48 | "eslint": "9.28.0", 49 | "eslint-config-prettier": "10.1.5", 50 | "eslint-plugin-prettier": "5.4.1", 51 | "favicons": "7.2.0", 52 | "favicons-webpack-plugin": "6.0.1", 53 | "globals": "16.2.0", 54 | "html-validate": "9.5.5", 55 | "npm-run-all2": "8.0.4", 56 | "postcss-loader": "8.1.1", 57 | "prettier": "3.5.3", 58 | "sass": "1.89.1", 59 | "sass-loader": "16.0.5", 60 | "shx": "0.4.0", 61 | "svg-sprite": "2.0.4", 62 | "svgtofont": "6.3.2", 63 | "uuid": "11.1.0", 64 | "webpack": "5.99.9", 65 | "webpack-cli": "6.0.1", 66 | "webpack-manifest-plugin": "5.0.1", 67 | "webpack-remove-empty-scripts": "1.1.1" 68 | }, 69 | "overrides": { 70 | "colors": "1.4.0" 71 | }, 72 | "browserslist": [ 73 | "last 2 version", 74 | "> 5%", 75 | "not dead", 76 | "Firefox ESR" 77 | ], 78 | "svgtofont": { 79 | "fontName": "GeekblogIcons", 80 | "css": false, 81 | "html": false, 82 | "emptyDist": true, 83 | "useNameAsUnicode": true, 84 | "svgicons2svgfont": { 85 | "fontHeight": 1001, 86 | "normalize": true, 87 | "centerHorizontally": true, 88 | "centerVertically": true 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": ["github>thegeeklab/renovate-presets"] 4 | } 5 | -------------------------------------------------------------------------------- /src/icons/arrow_back.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | arrow_back 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/arrow_left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | arrow_left 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/arrow_right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | arrow_right 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/bitbucket.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | bitbucket 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/bookmark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | bookmark 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/brightness_auto.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | brightness_auto 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/brightness_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | brightness_dark 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/brightness_light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | brightness_light 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/check.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | check 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/check_circle_outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | check_circle_outline 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/clear.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | clear 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/cloud_off.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | cloud_off 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/code.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | code 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/contacts.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | contacts 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/copy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | copy 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/create.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | create 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/dangerous.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | dangerous 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/date.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | date 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/download.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | download 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/email.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | email 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/error_outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | error_outline 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/fire.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | fire 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/git.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | git 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/gitea.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | gitea 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/github.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | github 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/gitlab.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | gitlab 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/heart.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | heart 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/info_outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | info_outline 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/keyboard_arrow_down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | keyboard_arrow_down 4 | 5 | -------------------------------------------------------------------------------- /src/icons/keyboard_arrow_left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | keyboard_arrow_left 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/keyboard_arrow_right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | keyboard_arrow_right 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/keyboard_arrow_up.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | keyboard_arrow_up 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | link 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/mastodon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | mastodon 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/matrix.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | matrix 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | menu 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/notifications.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | notifications 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/person.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | person 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/pin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | pin 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/rss_feed.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | rss_feed 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | search 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/security.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | security 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/star.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | star 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/tag.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tag 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/timer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | timer 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/tree.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | tree 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/icons/xmpp.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | xmpp 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/js/colorTheme.js: -------------------------------------------------------------------------------- 1 | import Storage from "store2" 2 | import { TOGGLE_COLOR_THEMES, THEME, COLOR_THEME_AUTO } from "./config.js" 3 | ;(() => { 4 | applyTheme() 5 | })() 6 | 7 | document.addEventListener("DOMContentLoaded", () => { 8 | const colorThemeToggle = document.getElementById("gblog-color-theme") 9 | 10 | colorThemeToggle.onclick = function () { 11 | let lstore = Storage.namespace(THEME) 12 | let currentColorTheme = lstore.get("color-theme") || COLOR_THEME_AUTO 13 | let nextColorTheme = toggle(TOGGLE_COLOR_THEMES, currentColorTheme) 14 | 15 | lstore.set("color-theme", TOGGLE_COLOR_THEMES[nextColorTheme]) 16 | applyTheme(false) 17 | } 18 | }) 19 | 20 | function applyTheme(init = true) { 21 | if (Storage.isFake()) return 22 | 23 | let lstore = Storage.namespace(THEME) 24 | let html = document.documentElement 25 | let currentColorTheme = TOGGLE_COLOR_THEMES.includes(lstore.get("color-theme")) 26 | ? lstore.get("color-theme") 27 | : COLOR_THEME_AUTO 28 | 29 | html.setAttribute("class", "color-toggle-" + currentColorTheme) 30 | 31 | if (currentColorTheme === COLOR_THEME_AUTO) { 32 | html.removeAttribute("color-theme") 33 | } else { 34 | html.setAttribute("color-theme", currentColorTheme) 35 | } 36 | 37 | if (!init) { 38 | // Reload required to re-initialise e.g. Mermaid with the new theme 39 | // and re-parse the Mermaid code blocks. 40 | location.reload() 41 | } 42 | } 43 | 44 | function toggle(list = [], value) { 45 | let current = list.indexOf(value) 46 | let max = list.length - 1 47 | let next = 0 48 | 49 | if (current < max) { 50 | next = current + 1 51 | } 52 | 53 | return next 54 | } 55 | -------------------------------------------------------------------------------- /src/js/config.js: -------------------------------------------------------------------------------- 1 | export const COLOR_THEME_DARK = "dark" 2 | export const COLOR_THEME_LIGHT = "light" 3 | export const COLOR_THEME_AUTO = "auto" 4 | export const THEME = "hugo-geekblog" 5 | export const TOGGLE_COLOR_THEMES = [COLOR_THEME_AUTO, COLOR_THEME_DARK, COLOR_THEME_LIGHT] 6 | -------------------------------------------------------------------------------- /src/js/index.js: -------------------------------------------------------------------------------- 1 | import Clipboard from "clipboard" 2 | 3 | document.addEventListener("DOMContentLoaded", function () { 4 | let clipboard = new Clipboard(".clip") 5 | 6 | clipboard.on("success", function (e) { 7 | const trigger = e.trigger 8 | 9 | if (trigger.hasAttribute("data-copy-feedback")) { 10 | trigger.classList.add("gblog-post__codecopy--success", "gblog-post__codecopy--out") 11 | trigger.querySelector(".gblog-icon.copy").classList.add("hidden") 12 | trigger.querySelector(".gblog-icon.check").classList.remove("hidden") 13 | 14 | setTimeout(function () { 15 | trigger.classList.remove("gblog-post__codecopy--success", "gblog-post__codecopy--out") 16 | trigger.querySelector(".gblog-icon.copy").classList.remove("hidden") 17 | trigger.querySelector(".gblog-icon.check").classList.add("hidden") 18 | }, 3000) 19 | } 20 | 21 | e.clearSelection() 22 | }) 23 | 24 | document.querySelectorAll(".highlight").forEach((highlightDiv) => createCopyButton(highlightDiv)) 25 | }) 26 | 27 | function createCopyButton(highlightDiv) { 28 | const button = document.createElement("span") 29 | 30 | let codeSelector = "pre > code" 31 | if (highlightDiv.querySelector(".lntable")) { 32 | codeSelector = ".lntable .lntd:last-child pre > code" 33 | } 34 | 35 | const codeContainer = highlightDiv.querySelector(codeSelector) 36 | if (codeContainer !== null) { 37 | const codeContent = codeContainer.innerText.trim() 38 | 39 | button.classList.add("flex", "align-center", "justify-center", "clip", "gblog-post__codecopy") 40 | button.type = "button" 41 | button.innerHTML = 42 | '' + 43 | '' 44 | button.setAttribute("data-clipboard-text", codeContent) 45 | button.setAttribute("data-copy-feedback", "Copied!") 46 | button.setAttribute("role", "button") 47 | button.setAttribute("aria-label", "Copy") 48 | 49 | highlightDiv.classList.add("gblog-post__codecontainer") 50 | highlightDiv.insertBefore(button, highlightDiv.firstChild) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/js/katex.js: -------------------------------------------------------------------------------- 1 | import renderMathInElement from "katex/dist/contrib/auto-render.mjs" 2 | 3 | renderMathInElement(document.body) 4 | -------------------------------------------------------------------------------- /src/js/mermaid.js: -------------------------------------------------------------------------------- 1 | import Storage from "store2" 2 | import { v4 as uuidv4 } from "uuid" 3 | import { COLOR_THEME_DARK, THEME, COLOR_THEME_AUTO } from "./config.js" 4 | 5 | import mermaid from "mermaid" 6 | 7 | document.addEventListener("DOMContentLoaded", function () { 8 | let lstore = Storage.namespace(THEME) 9 | let currentMode = lstore.get("color-theme") || COLOR_THEME_AUTO 10 | let darkModeQuery = window.matchMedia("(prefers-color-scheme: dark)") 11 | let darkMode = false 12 | let theme = "default" 13 | 14 | if ( 15 | currentMode === COLOR_THEME_DARK || 16 | (currentMode === COLOR_THEME_AUTO && darkModeQuery.matches) 17 | ) { 18 | darkMode = true 19 | theme = "dark" 20 | } 21 | 22 | mermaid.initialize({ 23 | startOnLoad: false, 24 | flowchart: { useMaxWidth: true }, 25 | theme: theme, 26 | themeVariables: { 27 | darkMode: darkMode 28 | } 29 | }) 30 | 31 | document.querySelectorAll(".mermaid").forEach(function (el) { 32 | let id = "graph-" + uuidv4() 33 | 34 | mermaid.render(id, el.innerText).then(({ svg, bindFunctions }) => { 35 | el.innerHTML = svg 36 | bindFunctions?.(el) 37 | }) 38 | }) 39 | }) 40 | -------------------------------------------------------------------------------- /src/sass/_asciidoc.scss: -------------------------------------------------------------------------------- 1 | .admonitionblock { 2 | @each $name, $color in $hint-colors { 3 | &.#{$name} { 4 | border-left-color: $color; 5 | background-color: color.scale($color, $lightness: 95%, $saturation: -30%); 6 | color: $body-font-color; 7 | } 8 | } 9 | 10 | & { 11 | margin: $padding-16 0; 12 | padding: 0; 13 | 14 | border-left: $border-4 solid var(--accent-color); 15 | border-radius: $border-radius; 16 | } 17 | 18 | table { 19 | margin: 0 !important; 20 | padding: 0 !important; 21 | 22 | tr { 23 | border: 0 !important; 24 | } 25 | 26 | td { 27 | display: block; 28 | padding: $padding-4 $padding-16 !important; 29 | 30 | &:first-child { 31 | background-color: color.scale($gray-600, $alpha: -95%); 32 | font-weight: bold; 33 | 34 | &.icon { 35 | .title { 36 | display: flex; 37 | align-items: center; 38 | } 39 | 40 | i.fa::after { 41 | content: attr(title); 42 | font-style: normal; 43 | padding-left: $padding-24; 44 | } 45 | 46 | i.fa { 47 | color: $black; 48 | background-size: auto 90%; 49 | background-repeat: no-repeat; 50 | filter: invert(30%); 51 | margin-left: -5px; 52 | } 53 | 54 | @each $name, $icon in $hint-icons { 55 | i.fa.icon-#{$name} { 56 | background-image: url(img/geekblog-stack.svg##{$icon}); 57 | } 58 | } 59 | } 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/sass/_chroma_base.scss: -------------------------------------------------------------------------------- 1 | @mixin chroma_base { 2 | .chroma { 3 | color: var(--code-font-color); 4 | } 5 | .chroma .lntable td:nth-child(2) code .hl { 6 | width: auto; 7 | margin-left: -0.5em; 8 | padding: 0 0.5em; 9 | } 10 | 11 | .highlight { 12 | pre.chroma { 13 | width: 100%; 14 | overflow: auto; 15 | max-height: var(--code-max-height); 16 | } 17 | } 18 | 19 | /* LineTable */ 20 | .chroma .lntable { 21 | border: $border-1 solid var(--code-accent-color); 22 | border-radius: $border-radius; 23 | border-spacing: 0; 24 | padding: 0; 25 | margin: 0; 26 | width: 100%; 27 | display: block; 28 | max-height: var(--code-max-height); 29 | overflow: auto; 30 | 31 | pre.chroma { 32 | max-height: none; 33 | border-radius: 0; 34 | margin: 0; 35 | } 36 | } 37 | .chroma .lntable td:first-child { 38 | code { 39 | background-color: var(--code-accent-color-lite); 40 | border-right: $border-1 solid var(--code-accent-color); 41 | padding-left: 0; 42 | padding-right: 0; 43 | border-radius: 0; 44 | } 45 | } 46 | .chroma .lntable td:nth-child(2) { 47 | width: 100%; 48 | margin-left: $padding-32; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/sass/_color_mode.scss: -------------------------------------------------------------------------------- 1 | @mixin color_theme_light { 2 | --header-background: #{$main-color}; 3 | --header-font-color: #{$white}; 4 | 5 | --body-background: #{$body-background}; 6 | --body-font-color: #{$body-font-color}; 7 | 8 | --mark-color: #{$mark-color}; 9 | 10 | --button-background: #{color.scale($main-color, $lightness: 15%)}; 11 | --button-border-color: #{$main-color}; 12 | 13 | --link-color: #{$link-color}; 14 | --link-color-visited: #{$link-color-visited}; 15 | 16 | --hint-link-color: #{$link-color}; 17 | --hint-link-color-visited: #{$link-color-visited}; 18 | 19 | --accent-color-dark: #{$gray-400}; 20 | --accent-color: #{$gray-200}; 21 | --accent-color-lite: #{$gray-100}; 22 | 23 | --control-icons: #{color.scale($body-font-color, $lightness: 40%)}; 24 | 25 | --footer-background: #{$second-color}; 26 | --footer-font-color: #{$white}; 27 | --footer-link-color: #{$link-color-footer}; 28 | --footer-link-color-visited: #{$link-color-footer}; 29 | 30 | .dark-mode-dim .gblog-markdown { 31 | img { 32 | filter: none; 33 | } 34 | } 35 | 36 | .gblog-markdown { 37 | .gblog-hint { 38 | filter: none; 39 | } 40 | } 41 | } 42 | 43 | @mixin color_theme_dark { 44 | --header-background: #{$main-color}; 45 | --header-font-color: #{$white}; 46 | 47 | --body-background: #{$body-background-dark}; 48 | --body-font-color: #{color.scale($body-background-dark, $lightness: 70%)}; 49 | 50 | --mark-color: #{$mark-color}; 51 | 52 | --button-background: #{color.scale($main-color, $lightness: 15%)}; 53 | --button-border-color: #{$main-color}; 54 | 55 | --link-color: #{$link-color-dark}; 56 | --link-color-visited: #{$link-color-visited-dark}; 57 | 58 | --hint-link-color: #{$link-color}; 59 | --hint-link-color-visited: #{$link-color-visited}; 60 | 61 | --accent-color-dark: #{color.scale($body-background-dark, $lightness: -60%)}; 62 | --accent-color: #{color.scale($body-background-dark, $lightness: -30%)}; 63 | --accent-color-lite: #{color.scale($body-background-dark, $lightness: -15%)}; 64 | 65 | --control-icons: #{color.scale($body-font-color, $lightness: 40%)}; 66 | 67 | --footer-background: #{$second-color}; 68 | --footer-font-color: #{$white}; 69 | --footer-link-color: #{$link-color-footer}; 70 | --footer-link-color-visited: #{$link-color-footer}; 71 | 72 | .dark-mode-dim { 73 | .gblog-post__feature picture, 74 | .gblog-markdown img { 75 | filter: brightness(0.75) grayscale(0.2); 76 | } 77 | } 78 | 79 | .gblog-markdown { 80 | .gblog-hint, 81 | .admonitionblock { 82 | filter: saturate(2.5) brightness(0.85); 83 | 84 | a { 85 | color: var(--hint-link-color); 86 | 87 | &:hover { 88 | background: var(--hint-link-color); 89 | color: $gray-100; 90 | } 91 | 92 | &:visited { 93 | color: var(--hint-link-color-visited); 94 | 95 | &:hover { 96 | background: var(--hint-link-color-visited); 97 | color: $gray-100; 98 | } 99 | } 100 | } 101 | } 102 | 103 | .gblog-hint__title, 104 | .admonitionblock table td:first-child { 105 | background-color: color.scale($gray-600, $alpha: -85%); 106 | } 107 | } 108 | } 109 | 110 | @mixin code_theme_dark { 111 | @include chroma_dark; 112 | 113 | & { 114 | --code-background: #{$code-background-dark}; 115 | --code-accent-color: #{color.scale($code-background-dark, $lightness: -30%)}; 116 | --code-accent-color-lite: #{color.scale($code-background-dark, $lightness: -15%)}; 117 | --code-font-color: #{$code-font-color-dark}; 118 | 119 | --code-copy-background: #{$code-background-dark}; 120 | --code-copy-font-color: #{color.scale($code-font-color-dark, $lightness: -15%)}; 121 | --code-copy-border-color: #{color.scale($code-font-color-dark, $lightness: -20%)}; 122 | --code-copy-success-color: #{color.scale(map.get($hint-colors, "ok"), $alpha: -55%)}; 123 | } 124 | } 125 | 126 | @mixin code_theme_light { 127 | @include chroma_github; 128 | 129 | & { 130 | --code-background: #{$code-background}; 131 | --code-accent-color: #{color.scale($code-background, $lightness: -45%)}; 132 | --code-accent-color-lite: #{color.scale($code-background, $lightness: -15%)}; 133 | --code-font-color: #{$code-font-color}; 134 | 135 | --code-copy-background: #{$code-background}; 136 | --code-copy-font-color: #{color.scale($code-font-color, $lightness: 20%)}; 137 | --code-copy-border-color: #{color.scale($code-font-color, $lightness: 40%)}; 138 | --code-copy-success-color: #{map.get($hint-colors, "ok")}; 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/sass/_defaults.scss: -------------------------------------------------------------------------------- 1 | @use "sass:color"; 2 | 3 | // Used in layout 4 | $padding-2: 0.125rem !default; 5 | $padding-4: 0.25rem !default; 6 | $padding-8: 0.5rem !default; 7 | $padding-12: 0.75rem !default; 8 | $padding-16: 1rem !default; 9 | $padding-20: 1.25rem !default; 10 | $padding-24: 1.5rem !default; 11 | $padding-32: 2rem !default; 12 | $padding-64: 4rem !default; 13 | $padding-96: 6rem !default; 14 | 15 | $font-size-base: 16px !default; 16 | $font-size-12: 0.75rem !default; 17 | $font-size-14: 0.875rem !default; 18 | $font-size-16: 1rem !default; 19 | $font-size-20: 1.25rem !default; 20 | $font-size-24: 1.5rem !default; 21 | $font-size-32: 2rem !default; 22 | $font-size-64: 4rem !default; 23 | $font-size-96: 6rem !default; 24 | $font-size-128: 8rem !default; 25 | 26 | $border-1: 1px !default; 27 | $border-2: 1.5px !default; 28 | $border-4: 3px !default; 29 | 30 | $border-radius: 0.15rem !default; 31 | 32 | // Grayscale 33 | $white: rgba(255, 255, 255, 1) !default; 34 | $gray-100: rgba(248, 249, 250, 1) !default; 35 | $gray-200: rgba(233, 236, 239, 1) !default; 36 | $gray-300: rgba(222, 226, 230, 1) !default; 37 | $gray-400: rgba(206, 212, 218, 1) !default; 38 | $gray-500: rgba(173, 181, 189, 1) !default; 39 | $gray-600: rgba(134, 142, 150, 1) !default; 40 | $gray-700: rgba(73, 80, 87, 1) !default; 41 | $gray-800: rgba(52, 58, 64, 1) !default; 42 | $gray-900: rgba(33, 37, 41, 1) !default; 43 | $black: rgba(0, 0, 0, 1) !default; 44 | 45 | $link-color: rgba(10, 83, 154, 1) !default; 46 | $link-color-visited: rgba(119, 73, 191, 1) !default; 47 | $link-color-footer: rgba(246, 107, 14, 1) !default; 48 | 49 | $body-background: white !default; 50 | $body-font-family: "Liberation Sans", sans-serif !default; 51 | $body-font-color: $gray-800 !default; 52 | $body-font-weight: normal !default; 53 | $body-min-width: 20rem !default; 54 | 55 | $code-font-family: "Liberation Mono", monospace !default; 56 | $code-font-color: rgba(95, 95, 95, 1) !default; 57 | $code-font-color-dark: rgba(185, 185, 185, 1) !default; 58 | 59 | $container-max-width: 60rem !default; 60 | 61 | $main-color: rgba(32, 83, 117, 1) !default; 62 | $second-color: rgba(17, 43, 60, 1) !default; 63 | $mark-color: rgba(255, 171, 0, 1) !default; 64 | 65 | $body-background-dark: mix(invert($body-background, 75%), $second-color) !default; 66 | $body-font-color-dark: $gray-100 !default; 67 | 68 | $link-color-dark: rgba(110, 168, 212, 1) !default; 69 | $link-color-visited-dark: rgba(186, 142, 240) !default; 70 | 71 | $code-background: $gray-100 !default; 72 | $code-background-dark: color.scale($body-background-dark, $lightness: -15%) !default; 73 | 74 | $header-font-family: "Metropolis", sans-serif !default; 75 | $header-height: 3.5rem !default; 76 | $menu-width: 16rem !default; 77 | 78 | $sm-breakpoint: $menu-width + $body-min-width + 3rem !default; 79 | 80 | // Panel colors 81 | $hint-colors: ( 82 | info: rgba(0, 145, 234, 1), 83 | note: rgba(0, 145, 234, 1), 84 | ok: rgba(0, 200, 83, 1), 85 | tip: rgba(0, 200, 83, 1), 86 | important: rgba(255, 171, 0, 1), 87 | caution: rgba(115, 0, 211, 1), 88 | danger: rgba(213, 0, 0, 1), 89 | warning: rgba(213, 0, 0, 1) 90 | ) !default; 91 | 92 | // Panel colors 93 | $hint-icons: ( 94 | info: "gblog_info_outline", 95 | note: "gblog_info_outline", 96 | ok: "gblog_check_circle_outline", 97 | tip: "gblog_check_circle_outline", 98 | important: "gblog_error_outline", 99 | caution: "gblog_dangerous", 100 | danger: "gblog_fire", 101 | warning: "gblog_fire" 102 | ) !default; 103 | -------------------------------------------------------------------------------- /src/sass/_fonts.scss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "Liberation Sans"; 3 | src: 4 | url("fonts/LiberationSans-Bold.woff2") format("woff2"), 5 | url("fonts/LiberationSans-Bold.woff") format("woff"); 6 | font-weight: bold; 7 | font-style: normal; 8 | font-display: swap; 9 | } 10 | 11 | @font-face { 12 | font-family: "Liberation Sans"; 13 | src: 14 | url("fonts/LiberationSans-BoldItalic.woff2") format("woff2"), 15 | url("fonts/LiberationSans-BoldItalic.woff") format("woff"); 16 | font-weight: bold; 17 | font-style: italic; 18 | font-display: swap; 19 | } 20 | 21 | @font-face { 22 | font-family: "Liberation Sans"; 23 | src: 24 | url("fonts/LiberationSans-Italic.woff2") format("woff2"), 25 | url("fonts/LiberationSans-Italic.woff") format("woff"); 26 | font-weight: normal; 27 | font-style: italic; 28 | font-display: swap; 29 | } 30 | 31 | @font-face { 32 | font-family: "Liberation Sans"; 33 | src: 34 | url("fonts/LiberationSans.woff2") format("woff2"), 35 | url("fonts/LiberationSans.woff") format("woff"); 36 | font-weight: normal; 37 | font-style: normal; 38 | font-display: swap; 39 | } 40 | 41 | @font-face { 42 | font-family: "Liberation Mono"; 43 | src: 44 | url("fonts/LiberationMono.woff2") format("woff2"), 45 | url("fonts/LiberationMono.woff") format("woff"); 46 | font-weight: normal; 47 | font-style: normal; 48 | font-display: swap; 49 | } 50 | 51 | @font-face { 52 | font-family: "Metropolis"; 53 | src: 54 | url("fonts/Metropolis.woff2") format("woff2"), 55 | url("fonts/Metropolis.woff") format("woff"); 56 | font-weight: normal; 57 | font-style: normal; 58 | font-display: swap; 59 | } 60 | 61 | @font-face { 62 | font-family: "GeekblogIcons"; 63 | src: 64 | url("fonts/GeekblogIcons.woff2") format("woff2"), 65 | url("fonts/GeekblogIcons.woff") format("woff"); 66 | font-weight: normal; 67 | font-style: normal; 68 | font-display: swap; 69 | } 70 | 71 | body { 72 | font-family: var(--body-font-family); 73 | } 74 | 75 | code, 76 | .gblog-error__title { 77 | font-family: var(--code-font-family); 78 | } 79 | 80 | .gblog-header { 81 | font-family: var(--header-font-family); 82 | } 83 | -------------------------------------------------------------------------------- /src/sass/_markdown.scss: -------------------------------------------------------------------------------- 1 | .gblog-markdown { 2 | line-height: 1.6rem; 3 | 4 | h1, 5 | h2, 6 | h3, 7 | h4, 8 | h5, 9 | h6 { 10 | font-weight: 600; 11 | 12 | > code { 13 | border-top: $border-4 solid var(--accent-color); 14 | font-size: $font-size-12 !important; 15 | } 16 | } 17 | 18 | h4, 19 | h5, 20 | h6 { 21 | > code { 22 | font-size: $font-size-14 !important; 23 | } 24 | } 25 | 26 | b, 27 | optgroup, 28 | strong { 29 | font-weight: bolder; 30 | } 31 | 32 | &__link--raw { 33 | text-decoration: none !important; 34 | color: $body-font-color !important; 35 | 36 | &:hover { 37 | background: none !important; 38 | color: $body-font-color !important; 39 | text-decoration: none !important; 40 | } 41 | 42 | &:visited { 43 | color: $body-font-color !important; 44 | } 45 | } 46 | 47 | &__link--code { 48 | text-decoration: none; 49 | code { 50 | color: inherit !important; 51 | } 52 | 53 | &:hover { 54 | background: none; 55 | color: var(--link-color) !important; 56 | text-decoration: underline; 57 | } 58 | 59 | &:visited, 60 | &:visited:hover { 61 | color: var(--link-color-visited) !important; 62 | } 63 | } 64 | 65 | img { 66 | max-width: 100%; 67 | border-radius: $border-radius; 68 | } 69 | 70 | blockquote { 71 | margin: $padding-16 0; 72 | padding: $padding-8 $padding-16 $padding-8 ($padding-16 - $padding-4); //to keep total left space 16dp 73 | 74 | border-left: $border-4 solid var(--accent-color); 75 | border-radius: $border-radius; 76 | } 77 | 78 | table:not(.lntable) { 79 | display: table; 80 | border-spacing: 0; 81 | border-collapse: collapse; 82 | margin: $padding-16 0; 83 | width: 100%; 84 | text-align: left; 85 | 86 | thead { 87 | border-bottom: $border-4 solid var(--accent-color); 88 | } 89 | 90 | tr th, 91 | tr td { 92 | padding: $padding-8 $padding-16; 93 | } 94 | 95 | tr { 96 | border-bottom: $border-2 solid var(--accent-color); 97 | } 98 | 99 | tr:nth-child(2n) { 100 | background: var(--accent-color-lite); 101 | } 102 | } 103 | 104 | hr { 105 | height: $border-2; 106 | border: none; 107 | background: var(--accent-color); 108 | } 109 | 110 | ul, 111 | ol { 112 | padding-left: $padding-32; 113 | } 114 | 115 | dl { 116 | dt { 117 | font-weight: bolder; 118 | margin-top: $padding-16; 119 | } 120 | 121 | dd { 122 | margin-left: $padding-32; 123 | } 124 | } 125 | 126 | code { 127 | padding: $padding-4 $padding-8; 128 | } 129 | 130 | pre, 131 | code { 132 | background-color: var(--code-background); 133 | border-radius: $border-radius; 134 | color: var(--code-font-color); 135 | font-size: $font-size-14; 136 | line-height: $padding-16; 137 | } 138 | 139 | pre code { 140 | display: block; 141 | padding: $padding-16; 142 | width: 100%; 143 | } 144 | 145 | mark { 146 | background-color: var(--mark-color); 147 | } 148 | 149 | section.footnotes { 150 | margin-top: $padding-32; 151 | color: var(--body-font-color); 152 | font-size: $font-size-14; 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/sass/_mobile.scss: -------------------------------------------------------------------------------- 1 | @media screen and (max-width: $sm-breakpoint) { 2 | .gblog-header__col-2.justify-center, 3 | .gblog-header__col-2 .justify-center { 4 | justify-content: flex-start; 5 | } 6 | 7 | .gblog-brand { 8 | font-size: $font-size-32; 9 | 10 | &__subtitle { 11 | font-size: $font-size-20; 12 | } 13 | 14 | &__img { 15 | width: 40px; 16 | height: 40px; 17 | } 18 | } 19 | 20 | .gblog-nav { 21 | .container { 22 | padding: 0; 23 | } 24 | 25 | &__list { 26 | background: color.scale($second-color, $lightness: 10%); 27 | flex-direction: column; 28 | justify-content: center; 29 | max-height: 0; 30 | visibility: hidden; 31 | overflow: hidden; 32 | } 33 | 34 | &__entry { 35 | padding: $padding-16 0; 36 | border: 0; 37 | border-radius: 0; 38 | display: block; 39 | margin: 0; 40 | text-align: center; 41 | 42 | &:hover, 43 | &:visited:hover, 44 | &.is-active { 45 | background: color.scale($second-color, $lightness: 5%); 46 | } 47 | } 48 | 49 | &__control { 50 | display: block; 51 | text-align: center; 52 | user-select: none; 53 | 54 | label { 55 | padding: $padding-16 0; 56 | } 57 | } 58 | } 59 | 60 | .gblog-error { 61 | padding: $padding-96 $padding-16; 62 | 63 | svg.gblog-icon { 64 | font-size: $font-size-96; 65 | } 66 | 67 | &__message { 68 | padding-left: $padding-32; 69 | } 70 | 71 | &__line { 72 | padding: $padding-4 0; 73 | } 74 | 75 | &__title { 76 | font-size: $font-size-16 * 2; 77 | } 78 | } 79 | 80 | .flex-mobile-column { 81 | flex-direction: column; 82 | 83 | &.gblog-columns { 84 | margin: $padding-32 0; 85 | } 86 | 87 | .gblog-columns__content { 88 | min-width: auto; 89 | margin: 0; 90 | } 91 | } 92 | 93 | .gblog-footer { 94 | &__item { 95 | width: 100%; 96 | } 97 | } 98 | 99 | .hidden-mobile { 100 | display: none; 101 | } 102 | 103 | #menu-control:checked ~ .gblog-nav__list { 104 | max-height: 100%; 105 | visibility: visible; 106 | } 107 | 108 | #menu-control:checked ~ .gblog-nav__control { 109 | svg.gblog-icon.gblog_menu { 110 | display: none; 111 | } 112 | svg.gblog-icon.gblog_clear { 113 | display: inline-block; 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/sass/_print.scss: -------------------------------------------------------------------------------- 1 | @media print { 2 | .gblog-nav, 3 | .gblog-header, 4 | .gblog-footer, 5 | .gblog-paging, 6 | .gblog-post__readmore, 7 | .gblog-post__anchor, 8 | .gblog-post__codecopy, 9 | .gblog-post__meta--author, 10 | .gblog-post__meta--tag, 11 | .gblog-post__meta--pinned { 12 | display: none; 13 | } 14 | 15 | .gblog-post { 16 | padding: 0.5em 0; 17 | } 18 | 19 | .gblog-markdown pre { 20 | white-space: pre-wrap; 21 | overflow-wrap: break-word; 22 | } 23 | 24 | .chroma code { 25 | padding: $padding-8 !important; 26 | font-weight: normal !important; 27 | } 28 | 29 | .gblog-markdown code { 30 | font-weight: bold; 31 | } 32 | 33 | a, 34 | a:visited, 35 | a:visited { 36 | color: var(--link-color) !important; 37 | background: none !important; 38 | text-decoration: underline !important; 39 | } 40 | 41 | h2, 42 | h3, 43 | h4, 44 | .no-break-after { 45 | break-after: avoid; 46 | } 47 | 48 | pre, 49 | blockquote, 50 | .no-break-inside { 51 | break-inside: avoid; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/sass/_utils.scss: -------------------------------------------------------------------------------- 1 | .flex { 2 | display: flex; 3 | } 4 | 5 | .flex-inline { 6 | display: inline-flex; 7 | } 8 | 9 | .flex-auto { 10 | flex: 1 1 auto; 11 | } 12 | 13 | .flex-25 { 14 | flex: 1 1 25%; 15 | } 16 | 17 | .flex-even { 18 | flex: 1 1; 19 | } 20 | 21 | .flex-wrap { 22 | flex-wrap: wrap; 23 | } 24 | 25 | .flex-grid { 26 | flex-direction: column; 27 | border: $border-1 solid var(--accent-color); 28 | border-radius: $border-radius; 29 | background: var(--accent-color-lite); 30 | } 31 | 32 | .flex-gap { 33 | flex-wrap: wrap; 34 | gap: $padding-16; 35 | } 36 | 37 | .justify-start { 38 | justify-content: flex-start; 39 | } 40 | 41 | .justify-end { 42 | justify-content: flex-end; 43 | } 44 | 45 | .justify-center { 46 | justify-content: center; 47 | } 48 | 49 | .justify-between { 50 | justify-content: space-between; 51 | } 52 | 53 | .align-center { 54 | align-items: center; 55 | } 56 | 57 | .mx-auto { 58 | margin: 0 auto; 59 | } 60 | 61 | .text-center { 62 | text-align: center; 63 | } 64 | 65 | .text-right { 66 | text-align: right; 67 | } 68 | 69 | .no-wrap { 70 | white-space: nowrap; 71 | } 72 | 73 | .hidden { 74 | display: none !important; 75 | } 76 | 77 | .svg-sprite { 78 | position: absolute; 79 | width: 0; 80 | height: 0; 81 | overflow: hidden; 82 | } 83 | 84 | .table-wrap { 85 | overflow: auto; 86 | margin: $padding-16 0; 87 | 88 | > table { 89 | margin: 0 !important; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/sass/main.scss: -------------------------------------------------------------------------------- 1 | @use "sass:map"; 2 | @use "sass:meta"; 3 | @use "sass:color"; 4 | 5 | @import "_defaults"; 6 | @import "_color_mode"; 7 | @import "_chroma_base"; 8 | @import "_chroma_light"; 9 | @import "_chroma_dark"; 10 | 11 | @import "_normalize"; 12 | @import "_utils"; 13 | @import "_fonts"; 14 | @import "_base"; 15 | 16 | @import "_markdown"; 17 | @import "_asciidoc"; 18 | @import "_shortcodes"; 19 | -------------------------------------------------------------------------------- /src/sass/mobile.scss: -------------------------------------------------------------------------------- 1 | @use "sass:color"; 2 | 3 | @import "_defaults"; 4 | 5 | @import "_mobile"; 6 | -------------------------------------------------------------------------------- /src/sass/print.scss: -------------------------------------------------------------------------------- 1 | @use "sass:color"; 2 | 3 | @import "_defaults"; 4 | 5 | @import "_print"; 6 | -------------------------------------------------------------------------------- /src/static/brand.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 43 | 46 | 48 | 51 | 54 | 57 | 60 | 62 | 64 | 68 | 72 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/static/custom.css: -------------------------------------------------------------------------------- 1 | /* You can add custom styles here. */ 2 | -------------------------------------------------------------------------------- /src/static/favicon/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 43 | 46 | 48 | 51 | 54 | 57 | 60 | 62 | 66 | 70 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /src/static/fonts/LiberationMono.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/src/static/fonts/LiberationMono.woff -------------------------------------------------------------------------------- /src/static/fonts/LiberationMono.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/src/static/fonts/LiberationMono.woff2 -------------------------------------------------------------------------------- /src/static/fonts/LiberationSans-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/src/static/fonts/LiberationSans-Bold.woff -------------------------------------------------------------------------------- /src/static/fonts/LiberationSans-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/src/static/fonts/LiberationSans-Bold.woff2 -------------------------------------------------------------------------------- /src/static/fonts/LiberationSans-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/src/static/fonts/LiberationSans-BoldItalic.woff -------------------------------------------------------------------------------- /src/static/fonts/LiberationSans-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/src/static/fonts/LiberationSans-BoldItalic.woff2 -------------------------------------------------------------------------------- /src/static/fonts/LiberationSans-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/src/static/fonts/LiberationSans-Italic.woff -------------------------------------------------------------------------------- /src/static/fonts/LiberationSans-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/src/static/fonts/LiberationSans-Italic.woff2 -------------------------------------------------------------------------------- /src/static/fonts/LiberationSans.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/src/static/fonts/LiberationSans.woff -------------------------------------------------------------------------------- /src/static/fonts/LiberationSans.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/src/static/fonts/LiberationSans.woff2 -------------------------------------------------------------------------------- /src/static/fonts/Metropolis.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/src/static/fonts/Metropolis.woff -------------------------------------------------------------------------------- /src/static/fonts/Metropolis.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thegeeklab/hugo-geekblog/9c4e38455c15c45ad5a7110bc3d0f06ce05d39b3/src/static/fonts/Metropolis.woff2 -------------------------------------------------------------------------------- /svgsprite.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "shape": { 3 | "id": { 4 | "generator": "gblog_%s" 5 | }, 6 | "dimension": { 7 | "maxWidth": 22, 8 | "maxHeight": 22, 9 | "attributes": false 10 | }, 11 | "spacing": { 12 | "padding": 5, 13 | "box": "content" 14 | }, 15 | "dest": "build/icons" 16 | }, 17 | "svg": { 18 | "xmlDeclaration": false, 19 | "rootAttributes": { 20 | "class": "svg-sprite" 21 | } 22 | }, 23 | "mode": { 24 | "defs": { 25 | "dest": "build/sprites/", 26 | "sprite": "geekblog.svg", 27 | "bust": false 28 | }, 29 | "stack": { 30 | "dest": "build/img/", 31 | "sprite": "geekblog-stack.svg", 32 | "bust": false 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /theme.toml: -------------------------------------------------------------------------------- 1 | name = "Geekblog" 2 | license = "MIT" 3 | licenselink = "https://github.com/thegeeklab/hugo-geekblog/blob/main/LICENSE" 4 | description = "Hugo theme made for blogs" 5 | homepage = "https://hugo-geekblog.geekdocs.de/" 6 | demosite = "https://hugo-geekblog.geekdocs.de/" 7 | tags = ["blog", "responsive", "simple"] 8 | min_version = "0.128" 9 | 10 | [author] 11 | name = "Robert Kaussow" 12 | homepage = "https://thegeeklab.de/" 13 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | import path from "path" 2 | import { glob } from "glob" 3 | import { fileURLToPath } from 'url'; 4 | 5 | import { WebpackManifestPlugin } from "webpack-manifest-plugin" 6 | import GitVersionPlugin from "@eloquent/git-version-webpack-plugin" 7 | import FaviconsWebpackPlugin from "favicons-webpack-plugin" 8 | import RemoveEmptyScriptsPlugin from "webpack-remove-empty-scripts" 9 | import CopyPlugin from "copy-webpack-plugin" 10 | import SRIPlugin from "./webpack.plugins.js" 11 | 12 | const __filename = fileURLToPath(import.meta.url); 13 | const __dirname = path.dirname(__filename); 14 | const nodeModulesPath = path.resolve(__dirname, "node_modules") 15 | 16 | var config = { 17 | entry: { 18 | css: [ 19 | path.resolve("src", "sass", "main.scss"), 20 | path.resolve("src", "sass", "mobile.scss"), 21 | path.resolve("src", "sass", "print.scss") 22 | ], 23 | main: path.resolve("src", "js", "index.js"), 24 | colortheme: path.resolve("src", "js", "colorTheme.js"), 25 | mermaid: path.resolve("src", "js", "mermaid.js"), 26 | katex: [path.resolve("src", "js", "katex.js")].concat( 27 | glob.sync(path.join(nodeModulesPath, "katex", "dist", "fonts", "*.{woff,woff2}")) 28 | ) 29 | }, 30 | output: { 31 | filename: "js/[name]-[contenthash:8].bundle.min.js", 32 | chunkFilename: "js/[name]-[contenthash:8].chunk.min.js", 33 | path: path.join(__dirname, "static"), 34 | clean: true 35 | }, 36 | watchOptions: { 37 | ignored: ["/exampleSite/", "/node_modules/"] 38 | }, 39 | target: ["web", "es2017"], 40 | plugins: [ 41 | new CopyPlugin({ 42 | patterns: [ 43 | { 44 | from: "**/*", 45 | context: path.resolve(__dirname, "src", "static") 46 | }, 47 | { 48 | from: "fonts/*.{woff,woff2}", 49 | context: path.resolve(__dirname, "build") 50 | }, 51 | { 52 | from: "sprites/*.svg", 53 | to: path.resolve(__dirname, "assets"), 54 | context: path.resolve(__dirname, "build") 55 | }, 56 | { 57 | from: "img/*.svg", 58 | context: path.resolve(__dirname, "build") 59 | } 60 | ] 61 | }), 62 | 63 | new FaviconsWebpackPlugin({ 64 | logo: path.resolve("src", "static", "favicon", "favicon.svg"), 65 | prefix: "favicon/", 66 | inject: false, 67 | favicons: { 68 | background: "#efefef", 69 | theme_color: "#efefef", 70 | icons: { 71 | android: { offset: 10 }, 72 | appleIcon: { offset: 10 }, 73 | appleStartup: { offset: 10 }, 74 | favicons: true, 75 | windows: { offset: 10 }, 76 | yandex: false 77 | } 78 | } 79 | }), 80 | 81 | new RemoveEmptyScriptsPlugin(), 82 | 83 | new WebpackManifestPlugin({ 84 | fileName: "../data/assets.json", 85 | publicPath: "", 86 | writeToFileEmit: true, 87 | generate(seed, files) { 88 | let manifest = {} 89 | 90 | files.forEach(function (element, index) { 91 | if (element.name.endsWith("VERSION")) return 92 | if (element.name.endsWith(".svg")) return 93 | if (element.name.startsWith("fonts/")) return 94 | if (element.name.startsWith("/favicon")) return 95 | 96 | Object.assign(manifest, { 97 | [element.name]: { src: element.path } 98 | }) 99 | }) 100 | 101 | return manifest 102 | } 103 | }), 104 | 105 | new SRIPlugin({ 106 | sourceFile: "data/assets.json" 107 | }), 108 | 109 | new GitVersionPlugin({ 110 | path: "../VERSION" 111 | }) 112 | ] 113 | } 114 | 115 | export default (argv) => { 116 | if (argv.mode === "development") { 117 | config.devtool = "eval-cheap-source-map" 118 | } 119 | 120 | config.module = { 121 | rules: [ 122 | { 123 | test: /\.(woff|woff2|eot|ttf|otf)$/i, 124 | type: "asset/resource", 125 | generator: { 126 | filename: "fonts/[name][ext]" 127 | }, 128 | }, 129 | { 130 | test: /\.(sa|sc|c)ss$/i, 131 | type: "asset/resource", 132 | generator: { 133 | filename: "[name]-[contenthash:8].min.css" 134 | }, 135 | use: [ 136 | { 137 | loader: "postcss-loader", 138 | options: { 139 | postcssOptions: { 140 | plugins: ["autoprefixer"] 141 | } 142 | } 143 | }, 144 | { 145 | loader: "sass-loader", 146 | options: { 147 | sourceMap: argv.mode === "development" ? true : false, 148 | sassOptions: { 149 | outputStyle: argv.mode === "development" ? "expanded" : "compressed" 150 | } 151 | } 152 | } 153 | ] 154 | } 155 | ] 156 | } 157 | 158 | return config 159 | } 160 | -------------------------------------------------------------------------------- /webpack.plugins.js: -------------------------------------------------------------------------------- 1 | import fs from "fs" 2 | import crypto from "crypto" 3 | import path from "path" 4 | import { validate } from "schema-utils" 5 | 6 | export default class SRIPlugin { 7 | static defaultOptions = { 8 | algorithm: "sha512", 9 | sourceFile: "assets.json" 10 | } 11 | 12 | constructor(options = {}) { 13 | const schema = { 14 | type: "object", 15 | properties: { 16 | outputFile: { 17 | type: "string" 18 | }, 19 | algorithm: { 20 | type: "string" 21 | } 22 | } 23 | } 24 | 25 | this.options = { ...SRIPlugin.defaultOptions, ...options } 26 | 27 | validate(schema, options, { 28 | name: "SRI Plugin", 29 | baseDataPath: "options" 30 | }) 31 | } 32 | 33 | apply(compiler) { 34 | compiler.hooks.done.tap("SRIPlugin", (manifest) => { 35 | let data = JSON.parse(fs.readFileSync(this.options.sourceFile, "utf8")) 36 | let outputFile = this.options.outputFile ? this.options.outputFile : this.options.sourceFile 37 | 38 | const checksum = (str, algorithm = this.options.algorithm, encoding = "base64") => 39 | crypto.createHash(algorithm).update(str, "utf8").digest(encoding) 40 | const fileSum = (file, algorithm) => checksum(fs.readFileSync(file), algorithm) 41 | const calculateSRI = (file, algorithm = this.options.algorithm) => 42 | `${algorithm}-${fileSum(path.join(".", "static", file), algorithm)}` 43 | 44 | Object.keys(data).forEach((key) => { 45 | let element = data[key] 46 | element.integrity = calculateSRI(element.src) 47 | }) 48 | 49 | fs.writeFileSync(outputFile, JSON.stringify(data, null, 2), { 50 | encoding: "utf8", 51 | flag: "w" 52 | }) 53 | }) 54 | } 55 | } 56 | --------------------------------------------------------------------------------