Compare commits
10 Commits
604f3aaa4c
...
e78c1db248
Author | SHA1 | Date | |
---|---|---|---|
|
e78c1db248 | ||
|
fdc27aad3a | ||
|
bb5e1f688b | ||
|
e2883bc1e8 | ||
|
413b06bb8a | ||
|
398cde5481 | ||
|
5e3b2d2dce | ||
|
51bd556992 | ||
|
b9926ba634 | ||
|
c7a2b2f4d2 |
17
config.yaml
@@ -9,7 +9,6 @@ noJSConfigInAssets: true
|
||||
params:
|
||||
author: Dave Gallant
|
||||
subtitle: blog
|
||||
favicon: https://davegallant.ca/favicon.ico
|
||||
|
||||
logo:
|
||||
text: davegallant.ca
|
||||
@@ -48,11 +47,11 @@ params:
|
||||
|
||||
menu:
|
||||
main:
|
||||
- name: Posts
|
||||
url: /
|
||||
weight: 1
|
||||
- name: About
|
||||
url: /about
|
||||
weight: 1
|
||||
- name: Git
|
||||
url: https://git.davegallant.ca/explore/repos
|
||||
weight: 2
|
||||
- name: RSS
|
||||
url: /index.xml
|
||||
@@ -68,15 +67,7 @@ markup:
|
||||
|
||||
module:
|
||||
imports:
|
||||
- path: github.com/davegallant/hugo-theme-gruvbox
|
||||
- path: github.com/schnerring/hugo-mod-json-resume
|
||||
mounts:
|
||||
- source: data
|
||||
target: data
|
||||
- source: layouts
|
||||
target: layouts
|
||||
- source: assets/css/json-resume.css
|
||||
target: assets/css/critical/44-json-resume.css
|
||||
- path: hugo-theme-gruvbox
|
||||
mounts:
|
||||
- source: node_modules/simple-icons/icons
|
||||
target: assets/simple-icons
|
||||
|
@@ -2,4 +2,4 @@
|
||||
title: Welcome
|
||||
---
|
||||
|
||||
This is a space where I share notes about problems and solutions I've been exploring. Please do not hesitate to reach out by email, social media, or by commenting on the posts below. Continuous improvement is what motivates me to keep learning.
|
||||
This is a space where I share notes about problems and solutions I've been exploring. Check out the links in the menu bar for more information on how to connect with me.
|
||||
|
@@ -3,17 +3,27 @@ title: "About"
|
||||
draft: false
|
||||
---
|
||||
|
||||
Connect with me using any the following methods:
|
||||
👋 I'm a software tinkerer with a passion for infra, security and self-hosting.
|
||||
|
||||
- Email: <mailto:me@davegallant.ca>
|
||||
- LinkedIn: <https://www.linkedin.com/in/dave-gallant>
|
||||
- Mastodon: <https://mastodon.social/@davegallant>
|
||||
- GitHub: <https://github.com/davegallant>
|
||||
- RSS Feed: <https://davegallant.ca/index.xml>
|
||||
- Git: <https://git.davegallant.ca/explore/repos>
|
||||
My primary motivation for hosting this website is to document my learnings and share them with others. I hope you find something useful here. Continuous improvement is what motivates me to keep learning.
|
||||
|
||||
I choose to self-host this site and other tools instead of relying exclusively on larger platforms because I believe in the open web. Interopability is often not a primary concern for popular platforms today and I find that concerning. I first got access to the internet in 1996 and have seen it evolve into what it is today. I want to do my part to keep it open and free.
|
||||
|
||||
If you would like to reach out, find out how to contact me [here](/contact/).
|
||||
|
||||
## Contact
|
||||
|
||||
Connect with me by using any of the following methods:
|
||||
|
||||
- [me@davegallant.ca](mailto:me@davegallant.ca)
|
||||
- <https://www.linkedin.com/in/dave-gallant>
|
||||
- <https://mastodon.social/@davegallant>
|
||||
- <https://github.com/davegallant>
|
||||
- <https://davegallant.ca/index.xml>
|
||||
- <https://git.davegallant.ca/explore/repos>
|
||||
|
||||
## Credits
|
||||
|
||||
- This website is generated using [hugo](https://gohugo.io/)
|
||||
- The site is generated with [hugo](https://gohugo.io/)
|
||||
- The theme is a modified version of [hugo-theme-gruvbox](https://github.com/schnerring/hugo-theme-gruvbox)
|
||||
- The comments system is powered by [utterances](https://github.com/utterance/utterances)
|
||||
- The comments system uses [utterances](https://github.com/utterance/utterances)
|
||||
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 72 KiB |
After Width: | Height: | Size: 45 KiB |
@@ -116,11 +116,24 @@ Something to consider is whether or not you want to use ssh with git. One method
|
||||
|
||||
After adding the above configuration, running `docker compose up -d` should be enough to get an instance up and running. It will be accessible at [https://gitea.my-tailnet-name.ts.net](https://gitea.my-tailnet-name.ts.net) from within the tailnet.
|
||||
|
||||
## Connecting a Runner
|
||||
## Theming
|
||||
|
||||
I discovered some themes for gitea [here](https://git.sainnhe.dev/sainnhe/gitea-themes) and decided to try out gruvbox.
|
||||
|
||||
I added the theme by cloning [theme-gruvbox-auto.css](https://git.sainnhe.dev/sainnhe/gitea-themes/raw/branch/master/dist/theme-gruvbox-auto.css) into `./data/gitea/public/assets/css`. I then added the following to `environment` in `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
- GITEA__ui__DEFAULT_THEME=gruvbox-auto
|
||||
- GITEA__ui__THEMES=gruvbox-auto
|
||||
```
|
||||
|
||||
After restarting the gitea instance, the default theme was applied.
|
||||
|
||||
## Connecting runners
|
||||
|
||||
I installed the runner by [following the docs](https://docs.gitea.com/usage/actions/quickstart#set-up-runner). I opted for installing it on a separate host (another lxc container) as recommended in the docs. I used the systemd unit file to ensure that the runner comes back online after system reboots. I installed tailscale on this gitea runner as well, so that it can have the same "networking privileges" as the main instance.
|
||||
|
||||
After registering this runner and starting the daemon, it appeared in `/admin/actions/runners`:
|
||||
After registering this runner and starting the daemon, the runner appeared in `/admin/actions/runners`. I added two other runners to help with parallelization.
|
||||
|
||||

|
||||
|
||||
@@ -146,7 +159,7 @@ jobs:
|
||||
matrix:
|
||||
host:
|
||||
- changedetection
|
||||
- homelab
|
||||
- homer
|
||||
- invidious
|
||||
- jackett
|
||||
- ladder
|
||||
@@ -154,6 +167,7 @@ jobs:
|
||||
- plex
|
||||
- qbittorrent
|
||||
- tailscale-exit-node
|
||||
- tailscale-subnet-router
|
||||
- uptime-kuma
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
@@ -187,7 +201,7 @@ jobs:
|
||||
|
||||
And voilà:
|
||||
|
||||
{{< video poster="gitea-workflow" >}}
|
||||

|
||||
|
||||
You may be wondering how the gitea runner is allowed to connect to the other hosts using ansible? Well, the nodes are in the same tailnet and have [tailscale ssh](https://tailscale.com/tailscale-ssh) enabled.
|
||||
|
||||
|
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"basics": {
|
||||
"name": "Dave Gallant",
|
||||
"image": "",
|
||||
"email": "me@davegallant.ca",
|
||||
"summary": "👋 I'm a software tinkerer with a passion for infra, security and self-hosting.",
|
||||
"location": {
|
||||
"region": "From 🇨🇦"
|
||||
},
|
||||
"profiles": [
|
||||
{
|
||||
"network": "LinkTree",
|
||||
"url": "https://linktr.ee/davegallant"
|
||||
},
|
||||
{
|
||||
"network": "GitHub",
|
||||
"url": "https://github.com/davegallant"
|
||||
},
|
||||
{
|
||||
"network": "Mastodon",
|
||||
"url": "https://mastodon.social/@davegallant"
|
||||
},
|
||||
{
|
||||
"network": "LinkedIn",
|
||||
"url": "https://www.linkedin.com/in/dave-gallant"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@@ -1,23 +1,29 @@
|
||||
{{- $scriptSrc := "https://utteranc.es/client.js" -}}
|
||||
|
||||
{{- $issueTerm := .Page.Site.Params.comments.utterances.issueTerm -}}
|
||||
{{- $label := .Page.Site.Params.comments.utterances.label -}}
|
||||
{{- $username := .Page.Site.Params.comments.utterances.github.username -}}
|
||||
{{- $repository := .Page.Site.Params.comments.utterances.github.repository -}}
|
||||
{{- $scriptSrc := "https://utteranc.es/client.js" -}} {{- $issueTerm :=
|
||||
.Page.Site.Params.comments.utterances.issueTerm -}} {{- $label :=
|
||||
.Page.Site.Params.comments.utterances.label -}} {{- $username :=
|
||||
.Page.Site.Params.comments.utterances.github.username -}} {{- $repository :=
|
||||
.Page.Site.Params.comments.utterances.github.repository -}}
|
||||
|
||||
<script>
|
||||
// load utteranc comment
|
||||
var getTheme = window.localStorage && window.localStorage.getItem("theme");
|
||||
getTheme = getTheme == null ? 'dark' : getTheme;
|
||||
// load utteranc comment
|
||||
var getTheme = window.localStorage && window.localStorage.getItem("theme");
|
||||
getTheme =
|
||||
getTheme == null
|
||||
? window.matchMedia &&
|
||||
window.matchMedia("(prefers-color-scheme: light)").matches
|
||||
? "light"
|
||||
: "dark"
|
||||
: getTheme;
|
||||
getTheme = getTheme == null ? "dark" : getTheme;
|
||||
|
||||
let theme = getTheme === 'dark' ? 'gruvbox-dark' : 'github-light';
|
||||
let s = document.createElement('script');
|
||||
s.src = 'https://utteranc.es/client.js';
|
||||
s.setAttribute('repo', '{{ print $username "/" $repository }}');
|
||||
s.setAttribute('issue-term', '{{ $issueTerm }}');
|
||||
s.setAttribute('theme', theme);
|
||||
s.setAttribute('crossorigin', 'anonymous');
|
||||
s.setAttribute('async', '');
|
||||
document.querySelector('div.comments').innerHTML = '';
|
||||
document.querySelector('div.comments').appendChild(s);
|
||||
let theme = getTheme === "dark" ? "gruvbox-dark" : "github-light";
|
||||
let s = document.createElement("script");
|
||||
s.src = "https://utteranc.es/client.js";
|
||||
s.setAttribute("repo", '{{ print $username "/" $repository }}');
|
||||
s.setAttribute("issue-term", "{{ $issueTerm }}");
|
||||
s.setAttribute("theme", theme);
|
||||
s.setAttribute("crossorigin", "anonymous");
|
||||
s.setAttribute("async", "");
|
||||
document.querySelector("div.comments").innerHTML = "";
|
||||
document.querySelector("div.comments").appendChild(s);
|
||||
</script>
|
||||
|
@@ -1,5 +0,0 @@
|
||||
module github.com/davegallant/hugo-theme-gruvbox
|
||||
|
||||
go 1.21
|
||||
|
||||
require github.com/schnerring/hugo-mod-json-resume v0.0.0-20231022202951-552402b37357 // indirect
|
@@ -1,2 +0,0 @@
|
||||
github.com/schnerring/hugo-mod-json-resume v0.0.0-20231022202951-552402b37357 h1:FR5kIQJNpHrB+P6yb8PrDVO8FpbUxF5fdTXLQp7UUpI=
|
||||
github.com/schnerring/hugo-mod-json-resume v0.0.0-20231022202951-552402b37357/go.mod h1:an+FdylzRESQ2N+NuFK+iLerxnDRWbOqkxCDUXflGF4=
|
@@ -1 +0,0 @@
|
||||
{{ partial "image.html" (dict "src" .Destination "alt" .PlainText "caption" .Title "page" .Page "lazy" true) }}
|
@@ -1,8 +0,0 @@
|
||||
{{ define "main" }}
|
||||
<article class="post">
|
||||
<h1>{{ .Title | markdownify }}</h1>
|
||||
<div class="post-content">
|
||||
{{ .Content }}
|
||||
</div>
|
||||
</article>
|
||||
{{ end }}
|
@@ -1,30 +0,0 @@
|
||||
<div class="sidebar">
|
||||
{{ if .Params.toc }}
|
||||
{{ with .TableOfContents }}
|
||||
<aside class="toc">
|
||||
<nav>
|
||||
<p class="sidebar__heading">Table Of Contents</p>
|
||||
{{ . }}
|
||||
</nav>
|
||||
</aside>
|
||||
<hr />
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }}
|
||||
{{ if $cv.basics }}
|
||||
<aside class="bio">
|
||||
{{ partial "json-resume/basics.html" . }}
|
||||
|
||||
{{ if $.Site.Params.tagCloud.enable }}
|
||||
<hr />
|
||||
{{ end }}
|
||||
</aside>
|
||||
{{ end }}
|
||||
|
||||
{{ if $.Site.Params.tagCloud.enable }}
|
||||
<aside>
|
||||
{{ partial "tag-cloud.html" . }}
|
||||
</aside>
|
||||
{{ end }}
|
||||
</div>
|
@@ -1,20 +0,0 @@
|
||||
{{ $url := .Permalink }}
|
||||
{{ $title := .Title }}
|
||||
{{ with $.Site.Params.socialShare }}
|
||||
<div class="social-share">
|
||||
<strong class="social-share__heading">Share this post: </strong>
|
||||
{{ range . }}
|
||||
{{ $href := .formatString }}
|
||||
{{ $href := replace $href "{url}" (urlquery $url) }}
|
||||
{{ $href := replace $href "{title}" (urlquery $title) }}
|
||||
<a
|
||||
class="social-share__item"
|
||||
href="{{ $href | safeURL }}"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
{{ partial (printf "icons/%s" .iconSuite) .iconName }}
|
||||
</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
@@ -1,32 +0,0 @@
|
||||
<!--
|
||||
Original work by Artem Sidorenko: https://www.sidorenko.io/post/2017/07/nice-tagcloud-with-hugo/
|
||||
Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0/)
|
||||
-->
|
||||
|
||||
{{ with $.Site.Taxonomies.tags }}
|
||||
{{ $fontUnit := "rem" }}
|
||||
{{ $minFontSize := $.Site.Params.tagCloud.minFontSizeRem | default 0.8 }}
|
||||
{{ $maxFontSize := $.Site.Params.tagCloud.maxFontSizeRem | default 2.0 }}
|
||||
{{ $fontSizeSpread := sub $maxFontSize $minFontSize }}
|
||||
{{ $min := len (index .ByCount.Reverse 0).Pages }}
|
||||
{{ $max := add (len (index .ByCount 0).Pages) 1 }}
|
||||
|
||||
|
||||
<div class="tag-cloud">
|
||||
{{ range $tagName, $weightedPages := . }}
|
||||
{{ $count := len $weightedPages.Pages }}
|
||||
{{ $weight := div (sub (math.Log $count) (math.Log $min)) (sub (math.Log $max) (math.Log $min)) }}
|
||||
{{ $fontSize := (add $minFontSize (mul $fontSizeSpread $weight) ) }}
|
||||
<a
|
||||
href="{{ "/tags/" | relLangURL }}{{ $tagName | urlize }}"
|
||||
style="font-size:{{ $fontSize }}{{ $fontUnit }}"
|
||||
{{ if eq $.Page.Params.title $tagName -}}
|
||||
class="tag-cloud__tag tag-cloud__tag--active"
|
||||
{{ else -}}
|
||||
class="tag-cloud__tag"
|
||||
{{ end -}}
|
||||
>{{ $tagName }}</a
|
||||
>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
@@ -1,7 +0,0 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 2
|
||||
indent_style = space
|
@@ -1,40 +0,0 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": ["config:base"],
|
||||
"rebaseWhen": "behind-base-branch",
|
||||
"npm": {
|
||||
"fileMatch": ["(^|/)package\\.hugo\\.json$"],
|
||||
"rangeStrategy": "bump",
|
||||
"updateLockFiles": false,
|
||||
"ignoreTests": true,
|
||||
"ignorePaths": [
|
||||
"package.json",
|
||||
|
||||
"**/node_modules/**",
|
||||
"**/bower_components/**",
|
||||
"**/vendor/**",
|
||||
"**/examples/**",
|
||||
"**/__tests__/**",
|
||||
"**/test/**",
|
||||
"**/tests/**",
|
||||
"**/__fixtures__/**"
|
||||
]
|
||||
},
|
||||
"gomod": {
|
||||
"fileMatch": ["(^|/)go\\.mod$"],
|
||||
"rangeStrategy": "bump",
|
||||
"ignoreTests": true
|
||||
},
|
||||
"packageRules": [
|
||||
{
|
||||
"extends": "packages:linters",
|
||||
"groupName": "linters"
|
||||
},
|
||||
{
|
||||
"matchUpdateTypes": ["minor", "patch"],
|
||||
"matchCurrentVersion": "!/^0/",
|
||||
"automerge": true,
|
||||
"automergeType": "branch"
|
||||
}
|
||||
]
|
||||
}
|
@@ -1,39 +0,0 @@
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
update_hugo_dependencies:
|
||||
name: Update Hugo Dependencies
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "18"
|
||||
|
||||
- name: Install Hugo
|
||||
uses: peaceiris/actions-hugo@v2
|
||||
with:
|
||||
hugo-version: "0.111.3"
|
||||
extended: true
|
||||
|
||||
- name: Write composite package.json
|
||||
run: hugo mod npm pack
|
||||
|
||||
- name: Install npm Packages
|
||||
run: npm install
|
||||
|
||||
- name: Display Changes
|
||||
run: git status
|
||||
|
||||
- name: Commit Changes
|
||||
uses: stefanzweifel/git-auto-commit-action@v5
|
||||
with:
|
||||
commit_message: Update Hugo Dependencies
|
@@ -1,139 +0,0 @@
|
||||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/hugo,node
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=hugo,node
|
||||
|
||||
### Hugo ###
|
||||
# Generated files by hugo
|
||||
/public/
|
||||
/resources/_gen/
|
||||
|
||||
# Executable may be added to repository
|
||||
hugo.exe
|
||||
hugo.darwin
|
||||
hugo.linux
|
||||
|
||||
### Node ###
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
.env.production
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
### Node Patch ###
|
||||
# Serverless Webpack directories
|
||||
.webpack/
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/hugo,node
|
@@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx lint-staged
|
@@ -1,4 +0,0 @@
|
||||
node_modules
|
||||
|
||||
public
|
||||
resources
|
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"plugins": ["prettier-plugin-go-template"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.html"],
|
||||
"options": {
|
||||
"parser": "go-template"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Michael Schnerring
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@@ -1,118 +0,0 @@
|
||||
# hugo-mod-json-resume
|
||||
|
||||
A [Hugo module](https://gohugo.io/hugo-modules/) containing templates to
|
||||
integrate multilingual [JSON Resume](https://jsonresume.org/) data into your
|
||||
Hugo website.
|
||||
|
||||
## Getting Started
|
||||
|
||||
Initialize your Hugo site as a Hugo module:
|
||||
|
||||
```shell
|
||||
hugo mod init example.com
|
||||
```
|
||||
|
||||
Add the following to the `config.toml` file of your site to import the module:
|
||||
|
||||
```toml
|
||||
[module]
|
||||
[[module.imports]]
|
||||
path = "github.com/schnerring/hugo-mod-json-resume"
|
||||
[[module.mounts]]
|
||||
source = "node_modules/simple-icons/icons"
|
||||
target = "assets/simple-icons"
|
||||
```
|
||||
|
||||
Install the module:
|
||||
|
||||
```shell
|
||||
hugo mod get
|
||||
```
|
||||
|
||||
Initialize the NPM `package.json` and install the dependencies:
|
||||
|
||||
```shell
|
||||
hugo mod npm pack
|
||||
npm install
|
||||
```
|
||||
|
||||
The module offers a simple CSS stylesheet [assets/css/json-resume.css](./assets/css/json-resume.css)
|
||||
that you can use.
|
||||
|
||||
Use the `json-resume` shortcode in markdown files:
|
||||
|
||||
```markdown
|
||||
---
|
||||
title: "CV"
|
||||
draft: false
|
||||
---
|
||||
|
||||
## Experience
|
||||
|
||||
{{< json-resume "work" >}}
|
||||
|
||||
## Education
|
||||
|
||||
{{< json-resume "education" >}}
|
||||
```
|
||||
|
||||
Or use the partials in your layout files:
|
||||
|
||||
```html
|
||||
<div class="sidebar">
|
||||
<aside class="bio">{{ partial "json-resume/basics.html" . }}</aside>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Data Structure
|
||||
|
||||
The module reads JSON Resume data from Hugo's `data/` directory:
|
||||
|
||||
```text
|
||||
data/
|
||||
├─ json_resume/
|
||||
├─ de.json
|
||||
├─ en.json
|
||||
```
|
||||
|
||||
Each file must adhere to the [JSON Resume schema](https://github.com/jsonresume/resume-schema/blob/master/schema.json)
|
||||
specification. At least one file with the name `<default content language code>.json`
|
||||
must exist (defaults to `en`). See also [Hugo Multilingual Mode](https://gohugo.io/content-management/multilingual/).
|
||||
|
||||
## Styling
|
||||
|
||||
You can style the existing templates by using the pre-defined classes. There are
|
||||
generic classes prefixed with `jr__` like `jr__item` or `jr__date-range` that
|
||||
apply to any template.
|
||||
|
||||
Classes specific to resume sections are prefixed with `jr-<section>__<section-field>`,
|
||||
like `jr-work__description` or `jr-basics__name`.
|
||||
|
||||
### Example
|
||||
|
||||

|
||||
|
||||
The above requires the following CSS:
|
||||
|
||||
```css
|
||||
.jr__item-meta {
|
||||
align-items: center;
|
||||
flex-flow: row wrap;
|
||||
}
|
||||
|
||||
.jr__date,
|
||||
.jr__date-range,
|
||||
.jr-work__location {
|
||||
flex-grow: 1;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.jr-education__institution {
|
||||
flex-basis: 100%;
|
||||
}
|
||||
```
|
||||
|
||||
## Attributions
|
||||
|
||||
To display social icons, [Simple Icons](https://simpleicons.org/) (CC0) are
|
||||
used.
|
@@ -1,75 +0,0 @@
|
||||
.jr__item-meta {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.jr__item-meta,
|
||||
.jr-basics__image,
|
||||
.jr-basics__item,
|
||||
.jr-basics__profile-icon,
|
||||
.jr-basics__profile-item {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.jr-awards__title,
|
||||
.jr-certificates__name,
|
||||
.jr-education__area,
|
||||
.jr-projects__roles,
|
||||
.jr-publications__name,
|
||||
.jr-volunteer__position,
|
||||
.jr-work__position,
|
||||
.jr-basics__name {
|
||||
font-size: 1.125rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.jr-basics__item {
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.jr-basics__item hr {
|
||||
margin: 1.5rem auto;
|
||||
}
|
||||
|
||||
.jr-basics__image {
|
||||
border-radius: 50%;
|
||||
height: 250px;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
.jr-basics__name,
|
||||
.jr-basics__label,
|
||||
.jr-basics__summary {
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
|
||||
.jr-basics__profile svg {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
.jr-basics__profile,
|
||||
.jr-basics__profile-item {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.jr-basics__profile-item {
|
||||
display: flex;
|
||||
padding: 0.2rem;
|
||||
}
|
||||
|
||||
.jr-basics__profile--col {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.jr-basics__profile--row {
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.jr-basics__profile-icon {
|
||||
padding: 0 0.75rem;
|
||||
}
|
@@ -1,161 +0,0 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/jsonresume/resume-schema/v1.0.0/schema.json",
|
||||
"basics": {
|
||||
"name": "Richard Hendriks",
|
||||
"label": "Programmer",
|
||||
"image": "",
|
||||
"email": "richard.hendriks@mail.com",
|
||||
"phone": "(912) 555-4321",
|
||||
"url": "http://richardhendricks.example.com",
|
||||
"summary": "Richard hails from Tulsa. He has earned degrees from the University of Oklahoma and Stanford. (Go Sooners and Cardinal!) Before starting Pied Piper, he worked for Hooli as a part time software developer. While his work focuses on applied information theory, mostly optimizing lossless compression schema of both the length-limited and adaptive variants, his non-work interests range widely, everything from quantum computing to chaos theory. He could tell you about it, but THAT would NOT be a “length-limited” conversation!",
|
||||
"location": {
|
||||
"address": "2712 Broadway St",
|
||||
"postalCode": "CA 94115",
|
||||
"city": "San Francisco",
|
||||
"countryCode": "US",
|
||||
"region": "California"
|
||||
},
|
||||
"profiles": [
|
||||
{
|
||||
"network": "Twitter",
|
||||
"username": "neutralthoughts",
|
||||
"url": ""
|
||||
},
|
||||
{
|
||||
"network": "SoundCloud",
|
||||
"username": "dandymusicnl",
|
||||
"url": "https://soundcloud.example.com/dandymusicnl"
|
||||
}
|
||||
]
|
||||
},
|
||||
"work": [
|
||||
{
|
||||
"name": "Pied Piper",
|
||||
"location": "Palo Alto, CA",
|
||||
"description": "Awesome compression company",
|
||||
"position": "CEO/President",
|
||||
"url": "http://piedpiper.example.com",
|
||||
"startDate": "2013-12-01",
|
||||
"endDate": "2014-12-01",
|
||||
"summary": "Pied Piper is a multi-platform technology based on a proprietary universal compression algorithm that has consistently fielded high Weisman Scores™ that are not merely competitive, but approach the theoretical limit of lossless compression.",
|
||||
"highlights": [
|
||||
"Build an algorithm for artist to detect if their music was violating copy right infringement laws",
|
||||
"Successfully won Techcrunch Disrupt",
|
||||
"Optimized an algorithm that holds the current world record for Weisman Scores"
|
||||
]
|
||||
}
|
||||
],
|
||||
"volunteer": [
|
||||
{
|
||||
"organization": "CoderDojo",
|
||||
"position": "Teacher",
|
||||
"url": "http://coderdojo.example.com/",
|
||||
"startDate": "2012-01-01",
|
||||
"endDate": "2013-01-01",
|
||||
"summary": "Global movement of free coding clubs for young people.",
|
||||
"highlights": [
|
||||
"Awarded 'Teacher of the Month'"
|
||||
]
|
||||
}
|
||||
],
|
||||
"education": [
|
||||
{
|
||||
"institution": "University of Oklahoma",
|
||||
"url": "https://www.ou.edu/",
|
||||
"area": "Information Technology",
|
||||
"studyType": "Bachelor",
|
||||
"startDate": "2011-06-01",
|
||||
"endDate": "2014-01-01",
|
||||
"score": "4.0",
|
||||
"courses": [
|
||||
"DB1101 - Basic SQL",
|
||||
"CS2011 - Java Introduction"
|
||||
]
|
||||
}
|
||||
],
|
||||
"awards": [
|
||||
{
|
||||
"title": "Digital Compression Pioneer Award",
|
||||
"date": "2014-11-01",
|
||||
"awarder": "Techcrunch",
|
||||
"summary": "There is no spoon."
|
||||
}
|
||||
],
|
||||
"publications": [
|
||||
{
|
||||
"name": "Video compression for 3d media",
|
||||
"publisher": "Hooli",
|
||||
"releaseDate": "2014-10-01",
|
||||
"url": "http://en.wikipedia.org/wiki/Silicon_Valley_(TV_series)",
|
||||
"summary": "Innovative middle-out compression algorithm that changes the way we store data."
|
||||
}
|
||||
],
|
||||
"skills": [
|
||||
{
|
||||
"name": "Web Development",
|
||||
"level": "Master",
|
||||
"keywords": [
|
||||
"HTML",
|
||||
"CSS",
|
||||
"Javascript"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Compression",
|
||||
"level": "Master",
|
||||
"keywords": [
|
||||
"Mpeg",
|
||||
"MP4",
|
||||
"GIF"
|
||||
]
|
||||
}
|
||||
],
|
||||
"languages": [
|
||||
{
|
||||
"language": "English",
|
||||
"fluency": "Native speaker"
|
||||
}
|
||||
],
|
||||
"interests": [
|
||||
{
|
||||
"name": "Wildlife",
|
||||
"keywords": [
|
||||
"Ferrets",
|
||||
"Unicorns"
|
||||
]
|
||||
}
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"name": "Erlich Bachman",
|
||||
"reference": "It is my pleasure to recommend Richard, his performance working as a consultant for Main St. Company proved that he will be a valuable addition to any company."
|
||||
}
|
||||
],
|
||||
"projects": [
|
||||
{
|
||||
"name": "Miss Direction",
|
||||
"description": "A mapping engine that misguides you",
|
||||
"highlights": [
|
||||
"Won award at AIHacks 2016",
|
||||
"Built by all women team of newbie programmers",
|
||||
"Using modern technologies such as GoogleMaps, Chrome Extension and Javascript"
|
||||
],
|
||||
"keywords": [
|
||||
"GoogleMaps", "Chrome Extension", "Javascript"
|
||||
],
|
||||
"startDate": "2016-08-24",
|
||||
"endDate": "2016-08-24",
|
||||
"url": "missdirection.example.com",
|
||||
"roles": [
|
||||
"Team lead", "Designer"
|
||||
],
|
||||
"entity": "Smoogle",
|
||||
"type": "application"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"canonical": "https://raw.githubusercontent.com/jsonresume/resume-schema/master/resume.json",
|
||||
"version": "v1.0.0",
|
||||
"lastModified": "2017-12-24T15:53:00"
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
module github.com/schnerring/hugo-mod-json-resume
|
||||
|
||||
go 1.21.5
|
@@ -1,15 +0,0 @@
|
||||
{{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }}
|
||||
{{ with $cv.awards }}
|
||||
<div class="jr__list jr-awards__list">
|
||||
{{ range . }}
|
||||
<div class="jr__item jr-awards__item">
|
||||
<div class="jr__item-meta">
|
||||
<div class="jr-awards__title">{{ .title }}</div>
|
||||
<div class="jr__date jr-awards__date">{{ .date }}</div>
|
||||
<div class="jr-awards__awarder">{{ .awarder }}</div>
|
||||
</div>
|
||||
<p class="jr__item-content">{{ .summary }}</p>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
@@ -1,10 +0,0 @@
|
||||
{{ if .image }}
|
||||
<div class="jr-basics__image">
|
||||
<img
|
||||
src="{{ .image }}"
|
||||
alt="Picture{{ with .name }} of {{ . }}{{ end }}"
|
||||
width="250"
|
||||
height="250"
|
||||
/>
|
||||
</div>
|
||||
{{ end }}
|
@@ -1,72 +0,0 @@
|
||||
{{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }}
|
||||
{{ with $cv.basics }}
|
||||
<div class="jr__item jr-basics__item">
|
||||
{{ partial "json-resume/basics-image.html" . }}
|
||||
|
||||
{{ with .name }}
|
||||
<div class="jr-basics__name">{{ . }}</div>
|
||||
{{ end }}
|
||||
|
||||
{{ with .label }}
|
||||
<div class="jr-basics__label">{{ . }}</div>
|
||||
{{ end }}
|
||||
|
||||
{{ with .email }}
|
||||
<div class="jr-basics__email">{{ . }}</div>
|
||||
{{ end }}
|
||||
|
||||
{{ with .phone }}
|
||||
<div class="jr-basics__phone">{{ . }}</div>
|
||||
{{ end }}
|
||||
|
||||
{{ with .url }}
|
||||
<div class="jr-basics__url">
|
||||
<a href="{{ . }}">{{ . }}</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
{{ with .summary }}
|
||||
<div class="jr-basics__summary">{{ . }}</div>
|
||||
{{ end }}
|
||||
|
||||
{{ with .location }}
|
||||
{{ with .address }}
|
||||
<div class="jr-basics__location-address">{{ . }}</div>
|
||||
{{ end }}
|
||||
|
||||
{{ with .postalCode }}
|
||||
<div class="jr-basics__location-postalCode">{{ . }}</div>
|
||||
{{ end }}
|
||||
|
||||
{{ with .city }}
|
||||
<div class="jr-basics__location-city">{{ . }}</div>
|
||||
{{ end }}
|
||||
|
||||
{{ with .countryCode }}
|
||||
<div class="jr-basics__location-countryCode">{{ . }}</div>
|
||||
{{ end }}
|
||||
|
||||
{{ with .region }}
|
||||
<div class="jr-basics__location-region">{{ . }}</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ with where .profiles "username" "ne" nil }}
|
||||
<hr />
|
||||
<div class="jr-basics__profile jr-basics__profile--col">
|
||||
{{ range . }}
|
||||
{{ partial "simple-icon.html" (dict "url" .url "network" .network "username" .username) }}
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
{{ with where .profiles "username" "eq" nil }}
|
||||
<hr />
|
||||
<div class="jr-basics__profile jr-basics__profile--row">
|
||||
{{ range . }}
|
||||
{{ partial "simple-icon.html" (dict "url" .url "network" .network "username" .username) }}
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
@@ -1,22 +0,0 @@
|
||||
{{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }}
|
||||
{{ with $cv.certificates }}
|
||||
<div class="jr__list jr-certificates__list">
|
||||
{{ range . }}
|
||||
<div class="jr__item jr-certificates__item">
|
||||
<div class="jr__item-meta">
|
||||
<div class="jr-certificates__name">
|
||||
{{ if .url }}
|
||||
<a href="{{ .url }}">
|
||||
{{ .name }}
|
||||
</a>
|
||||
{{ else }}
|
||||
<span>{{ .name }}</span>
|
||||
{{ end }}
|
||||
</div>
|
||||
<div class="jr-certificates__date">{{ .date }}</div>
|
||||
<div class="jr-certificates__issuer">{{ .issuer }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
@@ -1,11 +0,0 @@
|
||||
<div class="jr__date-range">
|
||||
<span>{{ .context.startDate }}</span>
|
||||
<span>-</span>
|
||||
<span>
|
||||
{{- with .context.endDate -}}
|
||||
{{- . -}}
|
||||
{{- else -}}
|
||||
{{ .site.Params.jsonResume.present | default "present" }}
|
||||
{{- end -}}
|
||||
</span>
|
||||
</div>
|
@@ -1,32 +0,0 @@
|
||||
{{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }}
|
||||
{{ with $cv.education }}
|
||||
<div class="jr__list jr-education__list">
|
||||
{{ range . }}
|
||||
<div class="jr__item jr-education__item">
|
||||
<div class="jr__item-meta">
|
||||
<div class="jr-education__area">{{ .area }} ({{ .studyType }})</div>
|
||||
{{ partial "json-resume/duration.html" (dict "context" . "site" $.Site) }}
|
||||
{{ if .institution }}
|
||||
<div class="jr-education__institution">
|
||||
{{ if .url }}
|
||||
<a href="{{ .url }}">{{ .institution }}</a>
|
||||
{{ else }}
|
||||
<span>{{ .institution }}</span>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
<p class="jr-education__score">
|
||||
{{ .score }}
|
||||
</p>
|
||||
{{ with .courses }}
|
||||
<ul class="jr-education__courses">
|
||||
{{ range . }}
|
||||
<li>{{ . }}</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
@@ -1,13 +0,0 @@
|
||||
{{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }}
|
||||
{{ with $cv.interests }}
|
||||
<div class="jr__list jr-interests__list">
|
||||
<ul>
|
||||
{{ range . }}
|
||||
<li class="jr__item jr-interests__item">
|
||||
{{ .name }} —
|
||||
{{ delimit .keywords ", " }}
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
||||
{{ end }}
|
@@ -1,13 +0,0 @@
|
||||
{{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }}
|
||||
{{ with $cv.languages }}
|
||||
<div class="jr__list jr-languages__list">
|
||||
<ul>
|
||||
{{ range . }}
|
||||
<li class="jr__item jr-languages__item">
|
||||
{{ .language }} —
|
||||
{{ .fluency }}
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
||||
{{ end }}
|
@@ -1,48 +0,0 @@
|
||||
{{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }}
|
||||
{{ with $cv.projects }}
|
||||
<div class="jr__list jr-projects__list">
|
||||
{{ range . }}
|
||||
<div class="jr__item jr-projects__item">
|
||||
<div class="jr__item-meta">
|
||||
<div class="jr-projects__roles">
|
||||
{{ delimit .roles ", " }}
|
||||
</div>
|
||||
{{ partial "json-resume/duration.html" (dict "context" . "site" $.Site) }}
|
||||
<div class="jr-projects__name">
|
||||
{{ if .url }}
|
||||
<a href="{{ .url }}">{{ .name }}</a>
|
||||
{{ else }}
|
||||
<span>{{ .name }}</span>
|
||||
{{ end }}
|
||||
{{ with .type }}
|
||||
({{ . }})
|
||||
{{ end }}
|
||||
{{ with .description }}
|
||||
<span>—</span>
|
||||
<span class="jr-projects__description">{{ . }}</span>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ with .entity }}
|
||||
<div class="jr-projects__entity">{{ . }}</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
<div class="jr__item-content">
|
||||
{{ with .highlights }}
|
||||
<ul>
|
||||
{{ range . }}
|
||||
<li>{{ . }}</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
{{ with .keywords }}
|
||||
<p>
|
||||
{{ delimit . ", " }}
|
||||
</p>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
@@ -1,24 +0,0 @@
|
||||
{{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }}
|
||||
{{ with $cv.publications }}
|
||||
<div class="jr__list jr-publications__list">
|
||||
{{ range . }}
|
||||
<div class="jr__item jr-publications__item">
|
||||
<div class="jr__item-meta">
|
||||
<div class="jr-publications__name">
|
||||
{{ if .url }}
|
||||
<a href="{{ .url }}">{{ .name }}</a>
|
||||
{{ else }}
|
||||
<span>{{ .name }}</span>
|
||||
{{ end }}
|
||||
</div>
|
||||
<div class="jr__date jr-publications__release-date">
|
||||
{{ .releaseDate }}
|
||||
</div>
|
||||
<div class="jr-publications__publisher">{{ .publisher }}</div>
|
||||
</div>
|
||||
|
||||
<p class="jr__item-content">{{ .summary }}</p>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
@@ -1,11 +0,0 @@
|
||||
{{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }}
|
||||
{{ with $cv.references }}
|
||||
<div class="jr__list jr-references__list">
|
||||
{{ range . }}
|
||||
<blockquote class="jr__item jr-references__item">
|
||||
<p>{{ .reference }}</p>
|
||||
<p>— {{ .name }}</p>
|
||||
</blockquote>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
@@ -1,17 +0,0 @@
|
||||
{{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }}
|
||||
{{ with $cv.skills }}
|
||||
<div class="jr__list jr-skills__list">
|
||||
<ul>
|
||||
{{ range . }}
|
||||
<li class="jr__item jr-skills__item">
|
||||
<p><strong>{{ .name }} ({{ .level }})</strong></p>
|
||||
{{ with .keywords }}
|
||||
<p>
|
||||
{{ delimit . ", " }}
|
||||
</p>
|
||||
{{ end }}
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
||||
{{ end }}
|
@@ -1,35 +0,0 @@
|
||||
{{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }}
|
||||
{{ with $cv.volunteer }}
|
||||
<div class="jr__list jr-volunteer__list">
|
||||
{{ range . }}
|
||||
<div class="jr__item jr-volunteer__item">
|
||||
<div class="jr__item-meta">
|
||||
<div class="jr-volunteer__position">{{ .position }}</div>
|
||||
{{ partial "json-resume/duration.html" (dict "context" . "site" $.Site) }}
|
||||
{{ if .organization }}
|
||||
<div class="jr-volunteer__organization">
|
||||
{{ if .url }}
|
||||
<a href="{{ .url }}">{{ .organization }}</a>
|
||||
{{ else }}
|
||||
<span>{{ .organization }}</span>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
<div class="jr__item-content">
|
||||
{{ with .summary }}
|
||||
<p class="jr-volunteer__summary">{{ . }}</p>
|
||||
{{ end }}
|
||||
{{ with .highlights }}
|
||||
<ul class="jr-volunteer__highlights">
|
||||
{{ range . }}
|
||||
<li>{{ . }}</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
@@ -1,47 +0,0 @@
|
||||
{{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }}
|
||||
{{ with $cv.work }}
|
||||
<div class="jr__list jr-work__list">
|
||||
{{ range . }}
|
||||
<div class="jr__item jr-work__item">
|
||||
<div class="jr__item-meta">
|
||||
<div class="jr-work__position">{{ .position }}</div>
|
||||
{{ partial "json-resume/duration.html" (dict "context" . "site" $.Site) }}
|
||||
{{ if or .name .location }}
|
||||
<div class="jr-work__name">
|
||||
{{ if .name }}
|
||||
{{ if .url }}
|
||||
<a href="{{ .url }}">
|
||||
{{ .name }}
|
||||
</a>
|
||||
{{ else }}
|
||||
<span>{{ .name }}</span>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ with .description }}
|
||||
<span>—</span>
|
||||
<span class="jr-work__description">{{ . }}</span>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
{{ with .location }}
|
||||
<div class="jr-work__location">{{ . }}</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
<div class="jr__item-content">
|
||||
{{ with .summary }}
|
||||
<p class="jr-work__summary">{{ . }}</p>
|
||||
{{ end }}
|
||||
{{ with .highlights }}
|
||||
<ul class="jr-work__highlights">
|
||||
{{ range . }}
|
||||
<li>{{ . }}</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
@@ -1,17 +0,0 @@
|
||||
<!-- TODO see https://github.com/NiklasPor/prettier-plugin-go-template/issues/59 -->
|
||||
<!-- prettier-ignore -->
|
||||
{{ if .url }}<a href="{{ .url }}" target="_blank" rel="noreferrer me">{{ end }}
|
||||
|
||||
<div class="jr-basics__profile-item">
|
||||
<div class="jr-basics__profile-icon">
|
||||
{{ $path := printf "simple-icons/%s.svg" (lower .network) }}
|
||||
{{ (resources.Get $path).Content | safeHTML }}
|
||||
</div>
|
||||
|
||||
{{ if .username }}
|
||||
<div class="jr-basics__profile-username">{{ .username }}</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
{{ if .url }}</a>{{ end }}
|
@@ -1,2 +0,0 @@
|
||||
{{ $jsonResumeSection := .Get 0 }}
|
||||
{{ partial (printf "json-resume/%s" $jsonResumeSection) . }}
|
@@ -1,38 +0,0 @@
|
||||
{
|
||||
"name": "hugo-mod-json-resume",
|
||||
"version": "1.0.0",
|
||||
"description": "Hugo shortcodes to add structured JSON Resume data to your Hugo site.",
|
||||
"author": {
|
||||
"name": "Michael Schnerring",
|
||||
"email": "3743342+schnerring@users.noreply.github.com",
|
||||
"url": "https://schnerring.net"
|
||||
},
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/schnerring/hugo-mod-json-resume#readme",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/schnerring/hugo-mod-json-resume.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/schnerring/hugo-mod-json-resume/issues"
|
||||
},
|
||||
"keywords": ["hugo", "json-resume"],
|
||||
"scripts": {
|
||||
"lint:md": "markdownlint --fix **/*.md",
|
||||
"lint": "npm run lint:css && npm run lint:js && npm run lint:md",
|
||||
"prepare": "husky install"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.md": "markdownlint --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"simple-icons": "^11.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"husky": "^8.0.3",
|
||||
"lint-staged": "^15.2.0",
|
||||
"markdownlint-cli": "^0.38.0",
|
||||
"prettier": "^3.1.1",
|
||||
"prettier-plugin-go-template": "^0.0.15"
|
||||
}
|
||||
}
|
@@ -1,53 +0,0 @@
|
||||
{
|
||||
"author": {
|
||||
"email": "3743342+schnerring@users.noreply.github.com",
|
||||
"name": "Michael Schnerring",
|
||||
"url": "https://schnerring.net"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/schnerring/hugo-mod-json-resume/issues"
|
||||
},
|
||||
"comments": {
|
||||
"dependencies": {
|
||||
"simple-icons": "project"
|
||||
},
|
||||
"devDependencies": {
|
||||
"husky": "project",
|
||||
"lint-staged": "project",
|
||||
"markdownlint-cli": "project",
|
||||
"prettier": "project",
|
||||
"prettier-plugin-go-template": "project"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"simple-icons": "^11.0.0"
|
||||
},
|
||||
"description": "Hugo shortcodes to add structured JSON Resume data to your Hugo site.",
|
||||
"devDependencies": {
|
||||
"husky": "^8.0.3",
|
||||
"lint-staged": "^15.2.0",
|
||||
"markdownlint-cli": "^0.38.0",
|
||||
"prettier": "^3.1.1",
|
||||
"prettier-plugin-go-template": "^0.0.15"
|
||||
},
|
||||
"homepage": "https://github.com/schnerring/hugo-mod-json-resume#readme",
|
||||
"keywords": [
|
||||
"hugo",
|
||||
"json-resume"
|
||||
],
|
||||
"license": "MIT",
|
||||
"lint-staged": {
|
||||
"*.md": "markdownlint --fix"
|
||||
},
|
||||
"name": "hugo-mod-json-resume",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/schnerring/hugo-mod-json-resume.git"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "npm run lint:css && npm run lint:js && npm run lint:md",
|
||||
"lint:md": "markdownlint --fix **/*.md",
|
||||
"prepare": "husky install"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
}
|
Before Width: | Height: | Size: 74 KiB |
@@ -86,10 +86,6 @@ Add the following to the `config.toml` file:
|
||||
[[module.imports.mounts]]
|
||||
source = "assets/css/json-resume.css"
|
||||
target = "assets/css/critical/44-json-resume.css"
|
||||
[[module.mounts]]
|
||||
# required by hugo-mod-json-resume
|
||||
source = "node_modules/simple-icons/icons"
|
||||
target = "assets/simple-icons"
|
||||
[[module.mounts]]
|
||||
source = "assets"
|
||||
target = "assets"
|
@@ -13,7 +13,7 @@ main {
|
||||
display: grid;
|
||||
grid-area: main;
|
||||
grid-template-areas: "empty content sidebar";
|
||||
grid-template-columns: 1fr minmax(0, 650px) 4fr;
|
||||
grid-template-columns: 2fr minmax(0, 860px) 2fr;
|
||||
}
|
||||
|
||||
header {
|
@@ -68,16 +68,3 @@ aside.toc {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tag-cloud {
|
||||
line-height: 1.1;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.tag-cloud__tag:hover {
|
||||
color: var(--fg3);
|
||||
}
|
||||
|
||||
.tag-cloud__tag--active {
|
||||
text-decoration: underline;
|
||||
}
|
@@ -3,6 +3,10 @@ function getTheme() {
|
||||
// User preference
|
||||
return localStorage.getItem("theme");
|
||||
}
|
||||
// Undefined
|
||||
}
|
||||
|
||||
function getOSTheme() {
|
||||
if (window.matchMedia) {
|
||||
// OS preference
|
||||
return window.matchMedia("(prefers-color-scheme: light)").matches
|
||||
@@ -21,20 +25,28 @@ function setTheme(theme) {
|
||||
const prismLight = document.getElementById("prism-light");
|
||||
prismDark.toggleAttribute("disabled", theme === "light");
|
||||
prismLight.toggleAttribute("disabled", theme === "dark");
|
||||
}
|
||||
|
||||
// Store user preference
|
||||
function saveTheme(theme) {
|
||||
localStorage.setItem("theme", theme);
|
||||
}
|
||||
|
||||
// Initial load
|
||||
const theme = getTheme();
|
||||
if (theme) setTheme(theme);
|
||||
const osTheme = getOSTheme();
|
||||
if (theme) {
|
||||
setTheme(theme);
|
||||
// Store user preference
|
||||
} else if (osTheme) {
|
||||
setTheme(osTheme);
|
||||
}
|
||||
|
||||
function toggleTheme(e) {
|
||||
const theme = e.currentTarget.classList.contains("light--hidden")
|
||||
? "light"
|
||||
: "dark";
|
||||
setTheme(theme);
|
||||
saveTheme(theme);
|
||||
}
|
||||
|
||||
// This script is inlined in the <head> of the document, so we have to wait
|
@@ -3,21 +3,6 @@
|
||||
[hugoVersion]
|
||||
extended = true
|
||||
min = "0.84.0"
|
||||
[[imports]]
|
||||
path = "github.com/schnerring/hugo-mod-json-resume"
|
||||
[[imports.mounts]]
|
||||
source = "data"
|
||||
target = "data"
|
||||
[[imports.mounts]]
|
||||
source = "layouts"
|
||||
target = "layouts"
|
||||
[[imports.mounts]]
|
||||
source = "assets/css/json-resume.css"
|
||||
target = "assets/css/critical/44-json-resume.css"
|
||||
[[mounts]]
|
||||
# required by hugo-mod-json-resume
|
||||
source = "node_modules/simple-icons/icons"
|
||||
target = "assets/simple-icons"
|
||||
[[mounts]]
|
||||
source = "assets"
|
||||
target = "assets"
|
||||
@@ -41,4 +26,4 @@
|
||||
target = "static/fonts"
|
||||
[[mounts]]
|
||||
source = "node_modules/@tabler/icons/icons"
|
||||
target = "assets/tabler-icons"
|
||||
target = "assets/tabler-icons"
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.8 KiB |
Before Width: | Height: | Size: 4.0 MiB After Width: | Height: | Size: 4.0 MiB |
Before Width: | Height: | Size: 2.3 MiB After Width: | Height: | Size: 2.3 MiB |
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |