Add jsonresume support (#1547)

Just as discussed in #1513 , this pull request adds support for
[jsonresume](https://jsonresume.org/). Create the resume once, either as
a file in the repository or at [github gist](https://gist.github.com/)
called `resume.json`. Put the file in the `_config.yaml` file and that's
it! Other platforms like [resumake](https://latexresu.me/) use the same
schema.

I also incorperated the changes introduced by #1339 to the best of my
abilites. The style could be further improved.

**Please merge this pull request after #1339 is merged, due to
dependencies from it**

If someone has a bettet approach on how to solve the problem that each
section needs its own template, please let me know. But for now it works
fine and is still backwards compatible with the `cv.yaml` file.

Co-authored-by: George <31376482+george-gca@users.noreply.github.com>
This commit is contained in:
Mirza Arnaut 2023-07-12 04:26:25 +02:00 committed by GitHub
parent cd5138b9c6
commit 40505f4c5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 578 additions and 0 deletions

View File

@ -15,6 +15,7 @@ group :jekyll_plugins do
gem 'jekyll-sitemap'
gem 'jekyll-toc'
gem 'jekyll-twitter-plugin'
gem 'jekyll-get-json'
gem 'jemoji'
gem 'mini_racer'
gem 'unicode_utils'

View File

@ -230,6 +230,7 @@ plugins:
- jekyll-sitemap
- jekyll-toc
- jekyll-twitter-plugin
- jekyll-get-json
- jemoji
# Sitemap settings
@ -403,3 +404,24 @@ mdb:
medium_zoom:
version: "1.0.8"
integrity: "sha256-7PhEpEWEW0XXQ0k6kQrPKwuoIomz8R8IYyuU1Qew4P8="
# -----------------------------------------------------------------------------
# Get external JSON data
# -----------------------------------------------------------------------------
jekyll_get_json:
- data: resume
json: "https://alshedivat.github.io/al-folio/assets/json/resume.json"
jsonresume:
- basics
- work
- education
- publications
- projects
- volunteer
- awards
- certificates
- skills
- languages
- interests
- references

View File

@ -0,0 +1,23 @@
<ul class="card-text font-weight-light list-group list-group-flush">
{% for content in data[1] %}
<li class="list-group-item">
<div class="row">
<div class="col-xs-2 cl-sm-2 col-md-2 text-center" style="width: 75px;">
{% if content.date %}
{% assign date = content.date | split: "-" | join: "." %}
{% else %}
{% assign date = "" %}
{% endif %}
<span class="badge font-weight-bold danger-color-dark text-uppercase align-middle" style="min-width: 75px;">
{{ date }}
</span>
</div>
<div class="col-xs-10 cl-sm-10 col-md-10 mt-2 mt-md-0">
<h6 class="title font-weight-bold ml-1 ml-md-4"><a href="{{ content.url }}">{{content.title}}</a></h6>
<h6 class="ml-1 ml-md-4" style="font-size: 0.95rem;">{{content.awarder}}</h6>
<h6 class="ml-1 ml-md-4" style="font-size: 0.95rem; font-style: italic;">{{content.summary}}</h6>
</div>
</div>
</li>
{% endfor %}
</ul>

View File

@ -0,0 +1,23 @@
<table class="table table-cv table-sm table-borderless table-responsive table-cv-map">
{% assign skip_basics = "image,profiles,location" | split:"," %}
{% for content in data[1] %}
{% if (content[1] == "") or (skip_basics contains content[0]) %}
{% continue %}
{% endif %}
<tr>
<td class="p-1 pr-2 font-weight-bold"><b>{{ content[0] | capitalize }}</b></td>
<td class="p-1 pl-2 font-weight-light text">
{% if content[0] == "url" %}
<a href="{{ content[1] }}" target="_blank" rel="noopener noreferrer">{{ content[1] }}</a>
{% elsif content[0] == "email" %}
<a href="mailto:{{ content[1] }}" target="_blank">{{ content[1] }}</a>
{% elsif content[0] == "phone" %}
<a href="tel:{{ content[1] }}">{{ content[1] }}</a>
{% else %}
{{ content[1] }}
{% endif %}
</td>
</tr>
{% endfor %}
</table>

View File

@ -0,0 +1,31 @@
<div class="list-groups">
{% assign certificates = data[1] | sort: 'date' | reverse %}
{% for content in certificates %}
<div class="list-group col-md-6">
<table class="table-cv list-group-table">
<tbody>
<tr>
{% if content.icon %}
<td class="list-group-category-icon"><i class="{{ content.icon }}"></i></td>
{% else %}
<td class="list-group-category-icon"></td>
{% endif %}
<!-- Calculate colspan number for category title -->
{% assign i = 1 %}
{% for item in content.items %}
{% assign i = i | plus:1 %}
{% endfor %}
<td colspan="{{ i }}" class="list-group-category">
<a href="{{ content.url | default: # }}">{{ content.name }}</a>
</td>
</tr>
<tr>
<td></td>
<td class="list-group-name"><b>{{ content.issuer }}</b></td>
<td class="list-group-name">{{ content.date }}</td>
</tr>
</tbody>
</table>
</div>
{% endfor %}
</div>

View File

@ -0,0 +1,47 @@
<ul class="card-text font-weight-light list-group list-group-flush">
{% assign education = data[1] | sort: 'startDate' | reverse %}
{% for content in education %}
<li class="list-group-item">
<div class="row">
<div class="col-xs-2 cl-sm-2 col-md-2 text-center" style="width: 75px;">
{% if content.startDate %}
{% assign startDate = content.startDate | split: "-" | slice: 0,2 | join: "." %}
{% assign endDate = content.endDate | split: "-" | slice: 0,2 | join: "." | default: "Present" %}
{% assign date = startDate | append: " - "%}
{% assign date = date | append: endDate %}
{% else %}
{% assign date = "" %}
{% endif %}
<table class="table-cv">
<tbody>
<tr>
<td>
<span class="badge font-weight-bold danger-color-dark text-uppercase align-middle" style="min-width: 75px;">{{date}}</span>
</td>
</tr>
{% if content.location %}
<tr>
<td>
<p class="location"><i class="fas fa-map-marker-alt iconlocation"></i> {{ content.location }}</p>
</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
<div class="col-xs-10 cl-sm-10 col-md-10 mt-2 mt-md-0">
<h6 class="title font-weight-bold ml-1 ml-md-4"><a href="{{ content.url }}">{{content.studyType}}</a></h6>
<h6 class="ml-1 ml-md-4" style="font-size: 0.95rem;">{{content.institution}}</h6>
<h6 class="ml-1 ml-md-4" style="font-size: 0.95rem; font-style: italic;">{{content.area}}</h6>
<ul class="items">
{% for item in content.courses %}
<li>
<span class="item">{{ item }}</span>
</li>
{% endfor %}
</ul>
</div>
</div>
</li>
{% endfor %}
</ul>

View File

@ -0,0 +1,29 @@
<div class="list-groups">
{% for content in data[1] %}
<div class="list-group col-md-6">
<table class="table-cv list-group-table">
<tbody>
<tr>
{% if content.icon %}
<td class="list-group-category-icon"><i class="{{ content.icon }}"></i></td>
{% else %}
<td class="list-group-category-icon"></td>
{% endif %}
<!-- Calculate colspan number for category title -->
{% assign i = 1 %}
{% for item in content.items %}
{% assign i = i | plus:1 %}
{% endfor %}
<td colspan="{{ i }}" class="list-group-category">{{ content.name }}</td>
</tr>
{% for item in content.keywords %}
<tr>
<td></td>
<td class="list-group-name"><b>{{ item }}</b></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endfor %}
</div>

View File

@ -0,0 +1,27 @@
<div class="list-groups">
{% for content in data[1] %}
<div class="list-group col-md-6">
<table class="table-cv list-group-table">
<tbody>
<tr>
{% if content.icon %}
<td class="list-group-category-icon"><i class="{{ content.icon }}"></i></td>
{% else %}
<td class="list-group-category-icon"></td>
{% endif %}
<!-- Calculate colspan number for category title -->
{% assign i = 1 %}
{% for item in content.items %}
{% assign i = i | plus:1 %}
{% endfor %}
<td colspan="{{ i }}" class="list-group-category">{{ content.language }}</td>
</tr>
<tr>
<td></td>
<td class="list-group-name"><b>{{ content.fluency }}</b></td>
</tr>
</tbody>
</table>
</div>
{% endfor %}
</div>

View File

@ -0,0 +1,32 @@
<ul class="card-text font-weight-light list-group list-group-flush">
{% for content in data[1] %}
<li class="list-group-item">
<div class="row">
<div class="col-xs-2 cl-sm-2 col-md-2 text-center" style="width: 75px;">
{% if content.startDate %}
{% assign startDate = content.startDate | split: "-" | slice: 0,2 | join: "." %}
{% assign endDate = content.endDate | split: "-" | slice: 0,2 | join: "." | default: "Present" %}
{% assign date = startDate | append: " - "%}
{% assign date = date | append: endDate %}
{% else %}
{% assign date = "" %}
{% endif %}
<span class="badge font-weight-bold danger-color-dark text-uppercase align-middle" style="min-width: 75px;">
{{ date }}
</span>
</div>
<div class="col-xs-10 cl-sm-10 col-md-10 mt-2 mt-md-0">
<h6 class="title font-weight-bold ml-1 ml-md-4"><a href="{{ content.url }}">{{content.name}}</a></h6>
<h6 class="ml-1 ml-md-4" style="font-size: 0.95rem; font-style: italic;">{{content.summary}}</h6>
<ul class="items">
{% for item in content.highlights %}
<li>
<span class="item">{{ item }}</span>
</li>
{% endfor %}
</ul>
</div>
</div>
</li>
{% endfor %}
</ul>

View File

@ -0,0 +1,30 @@
<ul class="card-text font-weight-light list-group list-group-flush">
{% assign publications = data[1] | sort: 'releaseDate' | reverse %}
{% for content in publications %}
<li class="list-group-item">
<div class="row">
<div class="col-xs-2 cl-sm-2 col-md-2 text-center" style="width: 75px;">
{% if content.releaseDate %}
{% assign date = content.releaseDate | split: "-" | join: "." %}
{% else %}
{% assign date = "" %}
{% endif %}
<table class="table-cv">
<tbody>
<tr>
<td>
<span class="badge font-weight-bold danger-color-dark text-uppercase align-middle" style="min-width: 75px;">{{date}}</span>
</td>
</tr>
</tbody>
</table>
</div>
<div class="col-xs-10 cl-sm-10 col-md-10 mt-2 mt-md-0">
<h6 class="title font-weight-bold ml-1 ml-md-4"><a href="{{ content.url }}">{{content.name}}</a></h6>
<h6 class="ml-1 ml-md-4" style="font-size: 0.95rem;">{{content.publisher}}</h6>
<h6 class="ml-1 ml-md-4" style="font-size: 0.95rem; font-style: italic;">{{content.summary}}</h6>
</div>
</div>
</li>
{% endfor %}
</ul>

View File

@ -0,0 +1,27 @@
<div class="list-groups">
{% for content in data[1] %}
<div class="list-group col-md-6">
<table class="table-cv list-group-table">
<tbody>
<tr>
{% if content.icon %}
<td class="list-group-category-icon"><i class="{{ content.icon }}"></i></td>
{% else %}
<td class="list-group-category-icon"></td>
{% endif %}
<!-- Calculate colspan number for category title -->
{% assign i = 1 %}
{% for item in content.items %}
{% assign i = i | plus:1 %}
{% endfor %}
<td colspan="{{ i }}" class="list-group-category">{{ content.name }}</td>
</tr>
<tr>
<td></td>
<td class="list-group-name"><b>{{ content.reference }}</b></td>
</tr>
</tbody>
</table>
</div>
{% endfor %}
</div>

View File

@ -0,0 +1,29 @@
<div class="list-groups">
{% for content in data[1] %}
<div class="list-group col-md-6" title="{{ content.level }}">
<table class="table-cv list-group-table">
<tbody>
<tr>
{% if content.icon %}
<td class="list-group-category-icon"><i class="{{ content.icon }}"></i></td>
{% else %}
<td class="list-group-category-icon"></td>
{% endif %}
<!-- Calculate colspan number for category title -->
{% assign i = 1 %}
{% for item in content.items %}
{% assign i = i | plus:1 %}
{% endfor %}
<td colspan="{{ i }}" class="list-group-category">{{ content.name }}</td>
</tr>
{% for item in content.keywords %}
<tr>
<td></td>
<td class="list-group-name"><b>{{ item }}</b></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endfor %}
</div>

View File

@ -0,0 +1,34 @@
<ul class="card-text font-weight-light list-group list-group-flush">
{% assign volunteer = data[1] | sort: 'startDate' | reverse %}
{% for content in volunteer %}
<li class="list-group-item">
<div class="row">
<div class="col-xs-2 cl-sm-2 col-md-2 text-center" style="width: 75px;">
{% if content.startDate %}
{% assign startDate = content.startDate | split: "-" | slice: 0,2 | join: "." %}
{% assign endDate = content.endDate | split: "-" | slice: 0,2 | join: "." | default: "Present" %}
{% assign date = startDate | append: " - "%}
{% assign date = date | append: endDate %}
{% else %}
{% assign date = "" %}
{% endif %}
<span class="badge font-weight-bold danger-color-dark text-uppercase align-middle" style="min-width: 75px;">
{{ date }}
</span>
</div>
<div class="col-xs-10 cl-sm-10 col-md-10 mt-2 mt-md-0">
<h6 class="title font-weight-bold ml-1 ml-md-4"><a href="{{ content.url }}">{{content.position}}</a></h6>
<h6 class="ml-1 ml-md-4" style="font-size: 0.95rem;">{{content.organization}}</h6>
<h6 class="ml-1 ml-md-4" style="font-size: 0.95rem; font-style: italic;">{{content.summary}}</h6>
<ul class="items">
{% for item in content.highlights %}
<li>
<span class="item">{{ item }}</span>
</li>
{% endfor %}
</ul>
</div>
</div>
</li>
{% endfor %}
</ul>

View File

@ -0,0 +1,34 @@
<ul class="card-text font-weight-light list-group list-group-flush">
{% assign work = data[1] | sort: 'startDate' | reverse %}
{% for content in work %}
<li class="list-group-item">
<div class="row">
<div class="col-xs-2 cl-sm-2 col-md-2 text-center" style="width: 75px;">
{% if content.startDate %}
{% assign startDate = content.startDate | split: "-" | slice: 0,2 | join: "." %}
{% assign endDate = content.endDate | split: "-" | slice: 0,2 | join: "." | default: "Present" %}
{% assign date = startDate | append: " - "%}
{% assign date = date | append: endDate %}
{% else %}
{% assign date = "" %}
{% endif %}
<span class="badge font-weight-bold danger-color-dark text-uppercase align-middle" style="min-width: 75px;">
{{ date }}
</span>
</div>
<div class="col-xs-10 cl-sm-10 col-md-10 mt-2 mt-md-0">
<h6 class="title font-weight-bold ml-1 ml-md-4"><a href="{{ content.url }}">{{content.position}}</a></h6>
<h6 class="ml-1 ml-md-4" style="font-size: 0.95rem;">{{content.name}}</h6>
<h6 class="ml-1 ml-md-4" style="font-size: 0.95rem; font-style: italic;">{{content.summary}}</h6>
<ul class="items">
{% for item in content.highlights %}
<li>
<span class="item">{{ item }}</span>
</li>
{% endfor %}
</ul>
</div>
</div>
</li>
{% endfor %}
</ul>

View File

@ -2,6 +2,8 @@
layout: default
---
<!-- _layouts/cv.html -->
{% unless site.data.resume %}
<div class="post">
<div class="post">
<header class="post-header">
@ -42,4 +44,114 @@ layout: default
</div>
</article>
<header class="post-header">
<h1 class="post-title">{{ page.title }} {% if page.cv_pdf %}<a href="{{ page.cv_pdf | prepend: 'assets/pdf/' | relative_url}}" target="_blank" rel="noopener noreferrer" class="float-right"><i class="fas fa-file-pdf"></i></a>{% endif %}</h1>
{% if page.description %}<p class="post-description">{{ page.description }}</p>{% endif %}
</header>
<h4>Table of contents</h4>
<ul class="timeline">
{% for entry in site.data.cv %}
<li><a href="#{{ entry.title }}"><span class="badge-toc">{{ entry.title }}</span></a></li>
{% endfor %}
</ul>
<article>
<div class="cv">
{% for entry in site.data.cv %}
<a class="anchor" id="{{ entry.title }}"></a>
<div class="card mt-3 p-3">
<h3 class="card-title font-weight-medium">{{ entry.title }}</h3>
<div>
{% if entry.type == "list" %}
{% include cv/list.html %}
{% elsif entry.type == "map" %}
{% include cv/map.html %}
{% elsif entry.type == "nested_list" %}
{% include cv/nested_list.html %}
{% elsif entry.type == "time_table" %}
{% include cv/time_table.html %}
{% elsif entry.type == "list_groups" %}
{% include cv/list_groups.html %}
{% else %}
{{ entry.contents }}
{% endif %}
</div>
</div>
{% endfor %}
</div>
</article>
</div>
{% else %}
<div class="post">
<header class="post-header">
<h1 class="post-title">{{ page.title }} {% if page.cv_pdf %}<a href="{{ page.cv_pdf | prepend: 'assets/pdf/' | relative_url}}" target="_blank" rel="noopener noreferrer" class="float-right"><i class="fas fa-file-pdf"></i></a>{% endif %}</h1>
{% if page.description %}<p class="post-description">{{ page.description }}</p>{% endif %}
</header>
<h4>Table of contents</h4>
<ul class="timeline">
{% for entry in site.data.resume %}
{% if site.jsonresume and site.jsonresume.size > 0 %}
{% unless site.jsonresume contains entry[0] %}
{% continue %}
{% endunless %}
{% endif %}
{% if entry[0] == "meta" or entry[1].size == 0 %}
{% continue %}
{% endif %}
<li><a href="#{{ entry[0] }}"><span class="badge-toc">{{ entry[0] | capitalize }}</span></a></li>
{% endfor %}
</ul>
<article>
<div class="cv">
{% for data in site.data.resume %}
{% if site.jsonresume and site.jsonresume.size > 0 %}
{% unless site.jsonresume contains data[0] %}
{% continue %}
{% endunless %}
{% endif %}
{% if data[0] == "meta" or data[1].size == 0 %}
{% continue %}
{% endif %}
<a class="anchor" id="{{ data[0] }}"></a>
<div class="card mt-3 p-3">
<h3 class="card-title font-weight-medium">{{ data[0] | capitalize }}</h3>
<div>
{% case data[0] %}
{% when "basics" %}
{% include resume/basics.html %}
{% when "education" %}
{% include resume/education.html %}
{% when "work" %}
{% include resume/work.html %}
{% when "volunteer" %}
{% include resume/volunteer.html %}
{% when "projects" %}
{% include resume/projects.html %}
{% when "awards" %}
{% include resume/awards.html %}
{% when "skills" %}
{% include resume/skills.html %}
{% when "publications" %}
{% include resume/publications.html %}
{% when "languages" %}
{% include resume/languages.html %}
{% when "interests" %}
{% include resume/interests.html %}
{% when "certificates" %}
{% include resume/certificates.html %}
{% else %}
{% endcase %}
</div>
</div>
{% endfor %}
</div>
</article>
</div>
{% endunless %}

77
assets/json/resume.json Normal file
View File

@ -0,0 +1,77 @@
{
"basics": {
"name": "Albert Einstein",
"label": "Scientist",
"image": "",
"email": "albert@einstein.de",
"phone": "(912) 123-4567",
"url": "https://alshedivat.github.io/al-folio/",
"summary": "A German-born theoretical physicist, widely ranked among the greatest and most influential scientists of all time",
"location": {
"address": "2712 Broadway St",
"postalCode": "CA 94115",
"city": "San Francisco",
"countryCode": "US",
"region": "California"
},
"profiles": [
{
"network": "Twitter",
"username": "AlbertEinstein",
"url": "https://twitter.com/AlbertEinstein"
}
]
},
"work": [
{
"name": "Institute for Advanced Study, Princeton University",
"position": "Professor of Theoretical Physics",
"url": "https://example.com",
"startDate": "1933-01-01",
"endDate": "1955-01-01",
"summary": "Teaching at Palmer Physical Laboratory (now 302 Frist Campus Center). While not a professor at Princeton, I associated with the physics professors and continued to give lectures on campus.",
"highlights": [
"Relativity"
]
}
],
"volunteer": [],
"education": [
{
"institution": "University of Zurich, Zurich, Switzerland",
"url": "https://www.uzh.ch/",
"area": "Software Development",
"studyType": "PhD",
"startDate": "1905-01-01",
"endDate": "1905-01-01",
"score": "",
"courses": [
"Theory of Relativity"
]
}
],
"awards": [
{
"title": "Nobel Prize in Physics",
"date": "1921-11-01",
"awarder": "Royal Swedish Academy of Sciences",
"summary": "The Nobel Prizes are five separate prizes that, according to Alfred Nobel's will of 1895, are awarded to 'those who, during the preceding year, have conferred the greatest benefit to humankind.'"
}
],
"certificates": [],
"publications": [],
"skills": [],
"languages": [
{
"language": "German",
"fluency": "Native speaker"
},
{
"language": "English",
"fluency": "Fluent"
}
],
"interests": [],
"references": [],
"projects": []
}