├── .gitattributes ├── .husky └── pre-commit ├── .prettierignore ├── go.mod ├── .editorconfig ├── layouts ├── shortcodes │ └── json-resume.html └── partials │ ├── json-resume │ ├── basics-image.html │ ├── duration.html │ ├── references.html │ ├── languages.html │ ├── interests.html │ ├── skills.html │ ├── awards.html │ ├── certificates.html │ ├── publications.html │ ├── education.html │ ├── volunteer.html │ ├── projects.html │ ├── work.html │ └── basics.html │ └── simple-icon.html ├── screenshots └── example-resume-section-headers.png ├── .vscode ├── extensions.json └── settings.json ├── .prettierrc.json ├── .github ├── renovate.json └── workflows │ └── update-hugo-dependencies.yml ├── package.hugo.json ├── LICENSE ├── assets └── css │ └── json-resume.css ├── package.json ├── .gitignore ├── README.md └── data └── json_resume └── en.json /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | npx lint-staged 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | public 4 | resources -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/schnerring/hugo-mod-json-resume 2 | 3 | go 1.25.5 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 2 7 | indent_style = space -------------------------------------------------------------------------------- /layouts/shortcodes/json-resume.html: -------------------------------------------------------------------------------- 1 | {{ $jsonResumeSection := .Get 0 }} 2 | {{ partial (printf "json-resume/%s" $jsonResumeSection) . }} 3 | -------------------------------------------------------------------------------- /screenshots/example-resume-section-headers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schnerring/hugo-mod-json-resume/HEAD/screenshots/example-resume-section-headers.png -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "davidanson.vscode-markdownlint", 4 | "editorconfig.editorconfig", 5 | "esbenp.prettier-vscode", 6 | ] 7 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.defaultFormatter": "esbenp.prettier-vscode", 3 | "[html]": { 4 | "editor.defaultFormatter": "esbenp.prettier-vscode" 5 | }, 6 | "editor.formatOnSave": true, 7 | } -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["prettier-plugin-go-template"], 3 | "overrides": [ 4 | { 5 | "files": ["*.html"], 6 | "options": { 7 | "parser": "go-template" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /layouts/partials/json-resume/basics-image.html: -------------------------------------------------------------------------------- 1 | {{ if .image }} 2 |
3 | Picture{{ with .name }} of {{ . }}{{ end }} 9 |
10 | {{ end }} 11 | -------------------------------------------------------------------------------- /layouts/partials/json-resume/duration.html: -------------------------------------------------------------------------------- 1 |
2 | {{ .context.startDate }} 3 | - 4 | 5 | {{- with .context.endDate -}} 6 | {{- . -}} 7 | {{- else -}} 8 | {{ .site.Params.jsonResume.present | default "present" }} 9 | {{- end -}} 10 | 11 |
12 | -------------------------------------------------------------------------------- /layouts/partials/json-resume/references.html: -------------------------------------------------------------------------------- 1 | {{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }} 2 | {{ with $cv.references }} 3 |
4 | {{ range . }} 5 |
6 |

{{ .reference }}

7 |

— {{ .name }}

8 |
9 | {{ end }} 10 |
11 | {{ end }} 12 | -------------------------------------------------------------------------------- /layouts/partials/json-resume/languages.html: -------------------------------------------------------------------------------- 1 | {{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }} 2 | {{ with $cv.languages }} 3 |
4 | 12 |
13 | {{ end }} 14 | -------------------------------------------------------------------------------- /layouts/partials/json-resume/interests.html: -------------------------------------------------------------------------------- 1 | {{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }} 2 | {{ with $cv.interests }} 3 |
4 | 12 |
13 | {{ end }} 14 | -------------------------------------------------------------------------------- /layouts/partials/json-resume/skills.html: -------------------------------------------------------------------------------- 1 | {{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }} 2 | {{ with $cv.skills }} 3 |
4 | 16 |
17 | {{ end }} 18 | -------------------------------------------------------------------------------- /layouts/partials/json-resume/awards.html: -------------------------------------------------------------------------------- 1 | {{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }} 2 | {{ with $cv.awards }} 3 |
4 | {{ range . }} 5 |
6 |
7 |
{{ .title }}
8 |
{{ .date }}
9 |
{{ .awarder }}
10 |
11 |

{{ .summary }}

12 |
13 | {{ end }} 14 |
15 | {{ end }} 16 | -------------------------------------------------------------------------------- /layouts/partials/simple-icon.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ if .url }}{{ end }} 4 | 5 |
6 |
7 | {{ $path := printf "simple-icons/%s.svg" (lower .network) }} 8 | {{ (resources.Get $path).Content | safeHTML }} 9 |
10 | 11 | {{ if .username }} 12 |
{{ .username }}
13 | {{ end }} 14 |
15 | 16 | 17 | {{ if .url }}
{{ end }} 18 | -------------------------------------------------------------------------------- /layouts/partials/json-resume/certificates.html: -------------------------------------------------------------------------------- 1 | {{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }} 2 | {{ with $cv.certificates }} 3 |
4 | {{ range . }} 5 |
6 |
7 |
8 | {{ if .url }} 9 | 10 | {{ .name }} 11 | 12 | {{ else }} 13 | {{ .name }} 14 | {{ end }} 15 |
16 |
{{ .date }}
17 |
{{ .issuer }}
18 |
19 |
20 | {{ end }} 21 |
22 | {{ end }} 23 | -------------------------------------------------------------------------------- /layouts/partials/json-resume/publications.html: -------------------------------------------------------------------------------- 1 | {{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }} 2 | {{ with $cv.publications }} 3 |
4 | {{ range . }} 5 |
6 |
7 |
8 | {{ if .url }} 9 | {{ .name }} 10 | {{ else }} 11 | {{ .name }} 12 | {{ end }} 13 |
14 |
15 | {{ .releaseDate }} 16 |
17 |
{{ .publisher }}
18 |
19 | 20 |

{{ .summary }}

21 |
22 | {{ end }} 23 |
24 | {{ end }} 25 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": ["config:recommended"], 4 | "rebaseWhen": "behind-base-branch", 5 | "npm": { 6 | "managerFilePatterns": ["/(^|/)package\\.hugo\\.json$/"], 7 | "rangeStrategy": "bump", 8 | "skipArtifactsUpdate": true, 9 | "ignoreTests": true, 10 | "ignorePaths": [ 11 | "package.json", 12 | "**/node_modules/**", 13 | "**/bower_components/**", 14 | "**/vendor/**", 15 | "**/examples/**", 16 | "**/__tests__/**", 17 | "**/test/**", 18 | "**/tests/**", 19 | "**/__fixtures__/**" 20 | ] 21 | }, 22 | "gomod": { 23 | "managerFilePatterns": ["/(^|/)go\\.mod$/"], 24 | "rangeStrategy": "bump", 25 | "ignoreTests": true 26 | }, 27 | "packageRules": [ 28 | { 29 | "extends": ["packages:linters"], 30 | "groupName": "linters" 31 | }, 32 | { 33 | "matchUpdateTypes": ["minor", "patch"], 34 | "matchCurrentVersion": "!/^0/", 35 | "automerge": true, 36 | "automergeType": "branch" 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /package.hugo.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hugo-mod-json-resume", 3 | "version": "1.0.0", 4 | "description": "Hugo shortcodes to add structured JSON Resume data to your Hugo site.", 5 | "author": { 6 | "name": "Michael Schnerring", 7 | "email": "3743342+schnerring@users.noreply.github.com", 8 | "url": "https://schnerring.net" 9 | }, 10 | "license": "MIT", 11 | "homepage": "https://github.com/schnerring/hugo-mod-json-resume#readme", 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/schnerring/hugo-mod-json-resume.git" 15 | }, 16 | "bugs": { 17 | "url": "https://github.com/schnerring/hugo-mod-json-resume/issues" 18 | }, 19 | "keywords": ["hugo", "json-resume"], 20 | "scripts": { 21 | "prepare": "husky" 22 | }, 23 | "lint-staged": { 24 | "*.md": "markdownlint --fix" 25 | }, 26 | "dependencies": { 27 | "simple-icons": "^15.22.0" 28 | }, 29 | "devDependencies": { 30 | "husky": "^9.1.7", 31 | "lint-staged": "^16.2.7", 32 | "markdownlint-cli": "^0.45.0", 33 | "prettier": "^3.7.4", 34 | "prettier-plugin-go-template": "^0.0.15" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Michael Schnerring 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 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/update-hugo-dependencies.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | 6 | jobs: 7 | update_hugo_dependencies: 8 | name: Update Hugo Dependencies 9 | runs-on: ubuntu-latest 10 | permissions: 11 | contents: write 12 | steps: 13 | - name: Checkout Repository 14 | uses: actions/checkout@v5 15 | 16 | - name: Install Node 17 | uses: actions/setup-node@v5 18 | with: 19 | node-version: "24" 20 | 21 | - name: Install Hugo 22 | uses: peaceiris/actions-hugo@v3 23 | with: 24 | hugo-version: "0.133.0" 25 | extended: true 26 | 27 | - name: Write composite package.json 28 | run: hugo mod npm pack 29 | 30 | - name: Install npm Packages 31 | run: npm install 32 | 33 | - name: Display Changes 34 | run: git status 35 | 36 | - name: Commit Changes 37 | uses: stefanzweifel/git-auto-commit-action@v6 38 | with: 39 | commit_message: Update Hugo Dependencies 40 | commit_author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 41 | -------------------------------------------------------------------------------- /layouts/partials/json-resume/education.html: -------------------------------------------------------------------------------- 1 | {{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }} 2 | {{ with $cv.education }} 3 |
4 | {{ range . }} 5 |
6 |
7 |
{{ .area }} ({{ .studyType }})
8 | {{ partial "json-resume/duration.html" (dict "context" . "site" $.Site) }} 9 | {{ if .institution }} 10 |
11 | {{ if .url }} 12 | {{ .institution }} 13 | {{ else }} 14 | {{ .institution }} 15 | {{ end }} 16 |
17 | {{ end }} 18 |
19 |

20 | {{ .score }} 21 |

22 | {{ with .courses }} 23 | 28 | {{ end }} 29 |
30 | {{ end }} 31 |
32 | {{ end }} 33 | -------------------------------------------------------------------------------- /layouts/partials/json-resume/volunteer.html: -------------------------------------------------------------------------------- 1 | {{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }} 2 | {{ with $cv.volunteer }} 3 |
4 | {{ range . }} 5 |
6 |
7 |
{{ .position }}
8 | {{ partial "json-resume/duration.html" (dict "context" . "site" $.Site) }} 9 | {{ if .organization }} 10 |
11 | {{ if .url }} 12 | {{ .organization }} 13 | {{ else }} 14 | {{ .organization }} 15 | {{ end }} 16 |
17 | {{ end }} 18 |
19 | 20 |
21 | {{ with .summary }} 22 |

{{ . }}

23 | {{ end }} 24 | {{ with .highlights }} 25 |
    26 | {{ range . }} 27 |
  • {{ . }}
  • 28 | {{ end }} 29 |
30 | {{ end }} 31 |
32 |
33 | {{ end }} 34 |
35 | {{ end }} 36 | -------------------------------------------------------------------------------- /assets/css/json-resume.css: -------------------------------------------------------------------------------- 1 | .jr__item-meta { 2 | flex-direction: column; 3 | } 4 | 5 | .jr__item-meta, 6 | .jr-basics__image, 7 | .jr-basics__item, 8 | .jr-basics__profile-icon, 9 | .jr-basics__profile-item { 10 | align-items: center; 11 | display: flex; 12 | } 13 | 14 | .jr-awards__title, 15 | .jr-certificates__name, 16 | .jr-education__area, 17 | .jr-projects__roles, 18 | .jr-publications__name, 19 | .jr-volunteer__position, 20 | .jr-work__position, 21 | .jr-basics__name { 22 | font-size: 1.125rem; 23 | font-weight: bold; 24 | } 25 | 26 | .jr-basics__item { 27 | flex-direction: column; 28 | text-align: center; 29 | } 30 | 31 | .jr-basics__item hr { 32 | margin: 1.5rem auto; 33 | } 34 | 35 | .jr-basics__image { 36 | border-radius: 50%; 37 | height: 250px; 38 | justify-content: center; 39 | overflow: hidden; 40 | width: 250px; 41 | } 42 | 43 | .jr-basics__name, 44 | .jr-basics__label, 45 | .jr-basics__summary { 46 | margin-top: 0.75rem; 47 | } 48 | 49 | .jr-basics__profile svg { 50 | height: 24px; 51 | width: 24px; 52 | } 53 | 54 | .jr-basics__profile, 55 | .jr-basics__profile-item { 56 | display: flex; 57 | } 58 | 59 | .jr-basics__profile-item { 60 | display: flex; 61 | padding: 0.2rem; 62 | } 63 | 64 | .jr-basics__profile--col { 65 | flex-direction: column; 66 | } 67 | 68 | .jr-basics__profile--row { 69 | flex-wrap: wrap; 70 | justify-content: space-evenly; 71 | } 72 | 73 | .jr-basics__profile-icon { 74 | padding: 0 0.75rem; 75 | } 76 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": { 3 | "email": "3743342+schnerring@users.noreply.github.com", 4 | "name": "Michael Schnerring", 5 | "url": "https://schnerring.net" 6 | }, 7 | "bugs": { 8 | "url": "https://github.com/schnerring/hugo-mod-json-resume/issues" 9 | }, 10 | "comments": { 11 | "dependencies": { 12 | "simple-icons": "project" 13 | }, 14 | "devDependencies": { 15 | "husky": "project", 16 | "lint-staged": "project", 17 | "markdownlint-cli": "project", 18 | "prettier": "project", 19 | "prettier-plugin-go-template": "project" 20 | } 21 | }, 22 | "dependencies": { 23 | "simple-icons": "^15.22.0" 24 | }, 25 | "description": "Hugo shortcodes to add structured JSON Resume data to your Hugo site.", 26 | "devDependencies": { 27 | "husky": "^9.1.7", 28 | "lint-staged": "^16.2.7", 29 | "markdownlint-cli": "^0.45.0", 30 | "prettier": "^3.7.4", 31 | "prettier-plugin-go-template": "^0.0.15" 32 | }, 33 | "homepage": "https://github.com/schnerring/hugo-mod-json-resume#readme", 34 | "keywords": [ 35 | "hugo", 36 | "json-resume" 37 | ], 38 | "license": "MIT", 39 | "lint-staged": { 40 | "*.md": "markdownlint --fix" 41 | }, 42 | "name": "hugo-mod-json-resume", 43 | "repository": { 44 | "type": "git", 45 | "url": "git+https://github.com/schnerring/hugo-mod-json-resume.git" 46 | }, 47 | "scripts": { 48 | "prepare": "husky" 49 | }, 50 | "version": "1.0.0" 51 | } 52 | -------------------------------------------------------------------------------- /layouts/partials/json-resume/projects.html: -------------------------------------------------------------------------------- 1 | {{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }} 2 | {{ with $cv.projects }} 3 |
4 | {{ range . }} 5 |
6 |
7 |
8 | {{ delimit .roles ", " }} 9 |
10 | {{ partial "json-resume/duration.html" (dict "context" . "site" $.Site) }} 11 |
12 | {{ if .url }} 13 | {{ .name }} 14 | {{ else }} 15 | {{ .name }} 16 | {{ end }} 17 | {{ with .type }} 18 | ({{ . }}) 19 | {{ end }} 20 | {{ with .description }} 21 | 22 | {{ . }} 23 | {{ end }} 24 |
25 | {{ with .entity }} 26 |
{{ . }}
27 | {{ end }} 28 |
29 | 30 |
31 | {{ with .highlights }} 32 |
    33 | {{ range . }} 34 |
  • {{ . }}
  • 35 | {{ end }} 36 |
37 | {{ end }} 38 |
39 | 40 | {{ with .keywords }} 41 |

42 | {{ delimit . ", " }} 43 |

44 | {{ end }} 45 |
46 | {{ end }} 47 |
48 | {{ end }} 49 | -------------------------------------------------------------------------------- /layouts/partials/json-resume/work.html: -------------------------------------------------------------------------------- 1 | {{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }} 2 | {{ with $cv.work }} 3 |
4 | {{ range . }} 5 |
6 |
7 |
{{ .position }}
8 | {{ partial "json-resume/duration.html" (dict "context" . "site" $.Site) }} 9 | {{ if or .name .location }} 10 |
11 | {{ if .name }} 12 | {{ if .url }} 13 | 14 | {{ .name }} 15 | 16 | {{ else }} 17 | {{ .name }} 18 | {{ end }} 19 | {{ end }} 20 | {{ with .description }} 21 | 22 | {{ . }} 23 | {{ end }} 24 |
25 | {{ end }} 26 | 27 | {{ with .location }} 28 |
{{ . }}
29 | {{ end }} 30 |
31 | 32 |
33 | {{ with .summary }} 34 |

{{ . }}

35 | {{ end }} 36 | {{ with .highlights }} 37 |
    38 | {{ range . }} 39 |
  • {{ . }}
  • 40 | {{ end }} 41 |
42 | {{ end }} 43 |
44 |
45 | {{ end }} 46 |
47 | {{ end }} 48 | -------------------------------------------------------------------------------- /layouts/partials/json-resume/basics.html: -------------------------------------------------------------------------------- 1 | {{ $cv := index $.Site.Data.json_resume $.Site.Language.Lang }} 2 | {{ with $cv.basics }} 3 |
4 | {{ partial "json-resume/basics-image.html" . }} 5 | 6 | {{ with .name }} 7 |
{{ . }}
8 | {{ end }} 9 | 10 | {{ with .label }} 11 |
{{ . }}
12 | {{ end }} 13 | 14 | {{ with .email }} 15 |
{{ . }}
16 | {{ end }} 17 | 18 | {{ with .phone }} 19 |
{{ . }}
20 | {{ end }} 21 | 22 | {{ with .url }} 23 |
24 | {{ . }} 25 |
26 | {{ end }} 27 | 28 | {{ with .summary }} 29 |
{{ . }}
30 | {{ end }} 31 | 32 | {{ with .location }} 33 | {{ with .address }} 34 |
{{ . }}
35 | {{ end }} 36 | 37 | {{ with .postalCode }} 38 |
{{ . }}
39 | {{ end }} 40 | 41 | {{ with .city }} 42 |
{{ . }}
43 | {{ end }} 44 | 45 | {{ with .countryCode }} 46 |
{{ . }}
47 | {{ end }} 48 | 49 | {{ with .region }} 50 |
{{ . }}
51 | {{ end }} 52 | {{ end }} 53 | 54 | {{ with where .profiles "username" "ne" nil }} 55 |
56 |
57 | {{ range . }} 58 | {{ partial "simple-icon.html" (dict "url" .url "network" .network "username" .username) }} 59 | {{ end }} 60 |
61 | {{ end }} 62 | 63 | {{ with where .profiles "username" "eq" nil }} 64 |
65 |
66 | {{ range . }} 67 | {{ partial "simple-icon.html" (dict "url" .url "network" .network "username" .username) }} 68 | {{ end }} 69 |
70 | {{ end }} 71 |
72 | {{ end }} 73 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/hugo,node 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=hugo,node 4 | 5 | ### Hugo ### 6 | # Generated files by hugo 7 | /public/ 8 | /resources/_gen/ 9 | 10 | # Executable may be added to repository 11 | hugo.exe 12 | hugo.darwin 13 | hugo.linux 14 | 15 | ### Node ### 16 | # Logs 17 | logs 18 | *.log 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | lerna-debug.log* 23 | .pnpm-debug.log* 24 | 25 | # Diagnostic reports (https://nodejs.org/api/report.html) 26 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 27 | 28 | # Runtime data 29 | pids 30 | *.pid 31 | *.seed 32 | *.pid.lock 33 | 34 | # Directory for instrumented libs generated by jscoverage/JSCover 35 | lib-cov 36 | 37 | # Coverage directory used by tools like istanbul 38 | coverage 39 | *.lcov 40 | 41 | # nyc test coverage 42 | .nyc_output 43 | 44 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 45 | .grunt 46 | 47 | # Bower dependency directory (https://bower.io/) 48 | bower_components 49 | 50 | # node-waf configuration 51 | .lock-wscript 52 | 53 | # Compiled binary addons (https://nodejs.org/api/addons.html) 54 | build/Release 55 | 56 | # Dependency directories 57 | node_modules/ 58 | jspm_packages/ 59 | 60 | # Snowpack dependency directory (https://snowpack.dev/) 61 | web_modules/ 62 | 63 | # TypeScript cache 64 | *.tsbuildinfo 65 | 66 | # Optional npm cache directory 67 | .npm 68 | 69 | # Optional eslint cache 70 | .eslintcache 71 | 72 | # Microbundle cache 73 | .rpt2_cache/ 74 | .rts2_cache_cjs/ 75 | .rts2_cache_es/ 76 | .rts2_cache_umd/ 77 | 78 | # Optional REPL history 79 | .node_repl_history 80 | 81 | # Output of 'npm pack' 82 | *.tgz 83 | 84 | # Yarn Integrity file 85 | .yarn-integrity 86 | 87 | # dotenv environment variables file 88 | .env 89 | .env.test 90 | .env.production 91 | 92 | # parcel-bundler cache (https://parceljs.org/) 93 | .cache 94 | .parcel-cache 95 | 96 | # Next.js build output 97 | .next 98 | out 99 | 100 | # Nuxt.js build / generate output 101 | .nuxt 102 | dist 103 | 104 | # Gatsby files 105 | .cache/ 106 | # Comment in the public line in if your project uses Gatsby and not Next.js 107 | # https://nextjs.org/blog/next-9-1#public-directory-support 108 | # public 109 | 110 | # vuepress build output 111 | .vuepress/dist 112 | 113 | # Serverless directories 114 | .serverless/ 115 | 116 | # FuseBox cache 117 | .fusebox/ 118 | 119 | # DynamoDB Local files 120 | .dynamodb/ 121 | 122 | # TernJS port file 123 | .tern-port 124 | 125 | # Stores VSCode versions used for testing VSCode extensions 126 | .vscode-test 127 | 128 | # yarn v2 129 | .yarn/cache 130 | .yarn/unplugged 131 | .yarn/build-state.yml 132 | .yarn/install-state.gz 133 | .pnp.* 134 | 135 | ### Node Patch ### 136 | # Serverless Webpack directories 137 | .webpack/ 138 | 139 | # End of https://www.toptal.com/developers/gitignore/api/hugo,node 140 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # hugo-mod-json-resume 2 | 3 | A [Hugo module](https://gohugo.io/hugo-modules/) containing templates to 4 | integrate multilingual [JSON Resume](https://jsonresume.org/) data into your 5 | Hugo website. 6 | 7 | ## Getting Started 8 | 9 | Initialize your Hugo site as a Hugo module: 10 | 11 | ```shell 12 | hugo mod init example.com 13 | ``` 14 | 15 | Add the following to the `config.toml` file of your site to import the module: 16 | 17 | ```toml 18 | [module] 19 | [[module.imports]] 20 | path = "github.com/schnerring/hugo-mod-json-resume" 21 | [[module.mounts]] 22 | source = "node_modules/simple-icons/icons" 23 | target = "assets/simple-icons" 24 | ``` 25 | 26 | Install the module: 27 | 28 | ```shell 29 | hugo mod get 30 | ``` 31 | 32 | Initialize the NPM `package.json` and install the dependencies: 33 | 34 | ```shell 35 | hugo mod npm pack 36 | npm install 37 | ``` 38 | 39 | The module offers a simple CSS stylesheet [assets/css/json-resume.css](./assets/css/json-resume.css) 40 | that you can use. 41 | 42 | Use the `json-resume` shortcode in markdown files: 43 | 44 | ```markdown 45 | --- 46 | title: "CV" 47 | draft: false 48 | --- 49 | 50 | ## Experience 51 | 52 | {{< json-resume "work" >}} 53 | 54 | ## Education 55 | 56 | {{< json-resume "education" >}} 57 | ``` 58 | 59 | Or use the partials in your layout files: 60 | 61 | ```html 62 | 65 | ``` 66 | 67 | ## Data Structure 68 | 69 | The module reads JSON Resume data from Hugo's `data/` directory: 70 | 71 | ```text 72 | data/ 73 | ├─ json_resume/ 74 | ├─ de.json 75 | ├─ en.json 76 | ``` 77 | 78 | Each file must adhere to the [JSON Resume schema](https://github.com/jsonresume/resume-schema/blob/master/schema.json) 79 | specification. At least one file with the name `.json` 80 | must exist (defaults to `en`). See also [Hugo Multilingual Mode](https://gohugo.io/content-management/multilingual/). 81 | 82 | ## Styling 83 | 84 | You can style the existing templates by using the pre-defined classes. There are 85 | generic classes prefixed with `jr__` like `jr__item` or `jr__date-range` that 86 | apply to any template. 87 | 88 | Classes specific to resume sections are prefixed with `jr-
__`, 89 | like `jr-work__description` or `jr-basics__name`. 90 | 91 | ### Example 92 | 93 | ![Example resume section header screenshot](./screenshots/example-resume-section-headers.png) 94 | 95 | The above requires the following CSS: 96 | 97 | ```css 98 | .jr__item-meta { 99 | align-items: center; 100 | flex-flow: row wrap; 101 | } 102 | 103 | .jr__date, 104 | .jr__date-range, 105 | .jr-work__location { 106 | flex-grow: 1; 107 | text-align: right; 108 | } 109 | 110 | .jr-education__institution { 111 | flex-basis: 100%; 112 | } 113 | ``` 114 | 115 | ## Attributions 116 | 117 | To display social icons, [Simple Icons](https://simpleicons.org/) (CC0) are 118 | used. 119 | -------------------------------------------------------------------------------- /data/json_resume/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/jsonresume/resume-schema/v1.0.0/schema.json", 3 | "basics": { 4 | "name": "Richard Hendriks", 5 | "label": "Programmer", 6 | "image": "", 7 | "email": "richard.hendriks@mail.com", 8 | "phone": "(912) 555-4321", 9 | "url": "http://richardhendricks.example.com", 10 | "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!", 11 | "location": { 12 | "address": "2712 Broadway St", 13 | "postalCode": "CA 94115", 14 | "city": "San Francisco", 15 | "countryCode": "US", 16 | "region": "California" 17 | }, 18 | "profiles": [ 19 | { 20 | "network": "Twitter", 21 | "username": "neutralthoughts", 22 | "url": "" 23 | }, 24 | { 25 | "network": "SoundCloud", 26 | "username": "dandymusicnl", 27 | "url": "https://soundcloud.example.com/dandymusicnl" 28 | } 29 | ] 30 | }, 31 | "work": [ 32 | { 33 | "name": "Pied Piper", 34 | "location": "Palo Alto, CA", 35 | "description": "Awesome compression company", 36 | "position": "CEO/President", 37 | "url": "http://piedpiper.example.com", 38 | "startDate": "2013-12-01", 39 | "endDate": "2014-12-01", 40 | "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.", 41 | "highlights": [ 42 | "Build an algorithm for artist to detect if their music was violating copy right infringement laws", 43 | "Successfully won Techcrunch Disrupt", 44 | "Optimized an algorithm that holds the current world record for Weisman Scores" 45 | ] 46 | } 47 | ], 48 | "volunteer": [ 49 | { 50 | "organization": "CoderDojo", 51 | "position": "Teacher", 52 | "url": "http://coderdojo.example.com/", 53 | "startDate": "2012-01-01", 54 | "endDate": "2013-01-01", 55 | "summary": "Global movement of free coding clubs for young people.", 56 | "highlights": [ 57 | "Awarded 'Teacher of the Month'" 58 | ] 59 | } 60 | ], 61 | "education": [ 62 | { 63 | "institution": "University of Oklahoma", 64 | "url": "https://www.ou.edu/", 65 | "area": "Information Technology", 66 | "studyType": "Bachelor", 67 | "startDate": "2011-06-01", 68 | "endDate": "2014-01-01", 69 | "score": "4.0", 70 | "courses": [ 71 | "DB1101 - Basic SQL", 72 | "CS2011 - Java Introduction" 73 | ] 74 | } 75 | ], 76 | "awards": [ 77 | { 78 | "title": "Digital Compression Pioneer Award", 79 | "date": "2014-11-01", 80 | "awarder": "Techcrunch", 81 | "summary": "There is no spoon." 82 | } 83 | ], 84 | "publications": [ 85 | { 86 | "name": "Video compression for 3d media", 87 | "publisher": "Hooli", 88 | "releaseDate": "2014-10-01", 89 | "url": "http://en.wikipedia.org/wiki/Silicon_Valley_(TV_series)", 90 | "summary": "Innovative middle-out compression algorithm that changes the way we store data." 91 | } 92 | ], 93 | "skills": [ 94 | { 95 | "name": "Web Development", 96 | "level": "Master", 97 | "keywords": [ 98 | "HTML", 99 | "CSS", 100 | "Javascript" 101 | ] 102 | }, 103 | { 104 | "name": "Compression", 105 | "level": "Master", 106 | "keywords": [ 107 | "Mpeg", 108 | "MP4", 109 | "GIF" 110 | ] 111 | } 112 | ], 113 | "languages": [ 114 | { 115 | "language": "English", 116 | "fluency": "Native speaker" 117 | } 118 | ], 119 | "interests": [ 120 | { 121 | "name": "Wildlife", 122 | "keywords": [ 123 | "Ferrets", 124 | "Unicorns" 125 | ] 126 | } 127 | ], 128 | "references": [ 129 | { 130 | "name": "Erlich Bachman", 131 | "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." 132 | } 133 | ], 134 | "projects": [ 135 | { 136 | "name": "Miss Direction", 137 | "description": "A mapping engine that misguides you", 138 | "highlights": [ 139 | "Won award at AIHacks 2016", 140 | "Built by all women team of newbie programmers", 141 | "Using modern technologies such as GoogleMaps, Chrome Extension and Javascript" 142 | ], 143 | "keywords": [ 144 | "GoogleMaps", "Chrome Extension", "Javascript" 145 | ], 146 | "startDate": "2016-08-24", 147 | "endDate": "2016-08-24", 148 | "url": "missdirection.example.com", 149 | "roles": [ 150 | "Team lead", "Designer" 151 | ], 152 | "entity": "Smoogle", 153 | "type": "application" 154 | } 155 | ], 156 | "meta": { 157 | "canonical": "https://raw.githubusercontent.com/jsonresume/resume-schema/master/resume.json", 158 | "version": "v1.0.0", 159 | "lastModified": "2017-12-24T15:53:00" 160 | } 161 | } 162 | --------------------------------------------------------------------------------