Fixes #2787 as an alternative to #2969. It was getting too cumbersome to have 2 different data sources for CV and also a lot of different layout files, so I decided to unify them all. Main changes: - synchronized the information inside RenderCV (`_data/cv.yml`) and JSONResume (`assets/json/resume.json`) - unified layout files for CV information - added the option to set the "data source" in the CV page --------- Signed-off-by: George Araújo <george.gcac@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
387 lines
15 KiB
Plaintext
387 lines
15 KiB
Plaintext
---
|
|
layout: default
|
|
---
|
|
{% comment %}
|
|
Unified CV layout that handles both RenderCV (YAML) and JSONResume (JSON) formats
|
|
- If page.cv_format is set, it determines which format to render:
|
|
- 'rendercv': Load and render only RenderCV data (site.data.cv.cv)
|
|
- 'jsonresume': Load and render only JSONResume data (site.data.resume)
|
|
- If page.cv_format is not set, the legacy behavior applies:
|
|
- RenderCV data is in site.data.cv.cv
|
|
- JSONResume data is in site.data.resume
|
|
- RenderCV is prioritized if both exist
|
|
Both formats use the same unified rendering includes for consistent output
|
|
{% endcomment %}
|
|
|
|
<div class="post">
|
|
<header class="post-header">
|
|
<h1 class="post-title">
|
|
{{ page.title }}
|
|
{% if page.cv_pdf %}
|
|
<a
|
|
{% if page.cv_pdf contains '://' %}
|
|
href="{{ page.cv_pdf }}"
|
|
{% else %}
|
|
href="{{ page.cv_pdf | relative_url }}"
|
|
{% endif %}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
class="float-right"
|
|
>
|
|
<i class="fa-solid fa-file-pdf"></i>
|
|
</a>
|
|
{% endif %}
|
|
</h1>
|
|
{% if page.description %}
|
|
<p class="post-description">{{ page.description }}</p>
|
|
{% endif %}
|
|
</header>
|
|
|
|
<article>
|
|
<div class="cv">
|
|
{% comment %} Determine which CV format to render {% endcomment %}
|
|
{% assign render_rendercv = false %}
|
|
{% assign render_jsonresume = false %}
|
|
|
|
{% if page.cv_format == 'rendercv' %}
|
|
{% assign render_rendercv = true %}
|
|
{% elsif page.cv_format == 'jsonresume' %}
|
|
{% assign render_jsonresume = true %}
|
|
{% else %}
|
|
{% comment %} Legacy behavior: RenderCV takes priority if both exist {% endcomment %}
|
|
{% if site.data.cv and site.data.cv.cv %}
|
|
{% assign render_rendercv = true %}
|
|
{% elsif site.data.resume %}
|
|
{% assign render_jsonresume = true %}
|
|
{% endif %}
|
|
{% endif %}
|
|
|
|
{% if render_rendercv and site.data.cv and site.data.cv.cv %}
|
|
{% comment %} RenderCV format {% endcomment %}
|
|
{% assign cv = site.data.cv.cv %}
|
|
|
|
<!-- Header/Contact Information -->
|
|
{% if cv.name or cv.label or cv.location or cv.email or cv.phone or cv.website %}
|
|
<div class="card mt-3 p-3">
|
|
<h3 class="card-title font-weight-medium">Contact Information</h3>
|
|
<table class="table table-cv table-sm table-borderless">
|
|
{% if cv.name %}
|
|
<tr>
|
|
<td class="p-1 pr-2 font-weight-bold"><b>Name</b></td>
|
|
<td class="p-1 pl-2 font-weight-light">{{ cv.name }}</td>
|
|
</tr>
|
|
{% endif %}
|
|
{% if cv.label %}
|
|
<tr>
|
|
<td class="p-1 pr-2 font-weight-bold"><b>Professional Title</b></td>
|
|
<td class="p-1 pl-2 font-weight-light">{{ cv.label }}</td>
|
|
</tr>
|
|
{% endif %}
|
|
{% if cv.email %}
|
|
<tr>
|
|
<td class="p-1 pr-2 font-weight-bold"><b>Email</b></td>
|
|
<td class="p-1 pl-2 font-weight-light">{{ cv.email }}</td>
|
|
</tr>
|
|
{% endif %}
|
|
{% if cv.phone %}
|
|
<tr>
|
|
<td class="p-1 pr-2 font-weight-bold"><b>Phone</b></td>
|
|
<td class="p-1 pl-2 font-weight-light">{{ cv.phone }}</td>
|
|
</tr>
|
|
{% endif %}
|
|
{% if cv.address %}
|
|
<tr>
|
|
<td class="p-1 pr-2 font-weight-bold"><b>Location</b></td>
|
|
<td class="p-1 pl-2 font-weight-light">
|
|
{% if cv.address.street %}{{ cv.address.street }}, {% endif %}
|
|
{% if cv.address.city %}{{ cv.address.city }}, {% endif %}
|
|
{% if cv.address.region %}{{ cv.address.region }} {% endif %}
|
|
{% if cv.address.postalCode %}{{ cv.address.postalCode }}{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
{% if cv.website %}
|
|
<tr>
|
|
<td class="p-1 pr-2 font-weight-bold"><b>Website</b></td>
|
|
<td class="p-1 pl-2 font-weight-light">
|
|
<a href="{{ cv.website }}" target="_blank">{{ cv.website }}</a>
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
</table>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Summary -->
|
|
{% if cv.summary %}
|
|
<div class="card mt-3 p-3">
|
|
<h3 class="card-title font-weight-medium">Professional Summary</h3>
|
|
<p>{{ cv.summary | markdownify | remove: '<p>' | remove: '</p>' }}</p>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- RenderCV Sections - Merge Experience and Volunteer -->
|
|
{% comment %} First, combine Experience and Volunteer entries {% endcomment %}
|
|
{% assign combined_experience = cv.sections.Experience | concat: cv.sections.Volunteer %}
|
|
{% if combined_experience.size > 0 %}
|
|
<a class="anchor" id="experience"></a>
|
|
<div class="card mt-3 p-3">
|
|
<h3 class="card-title font-weight-medium">Experience</h3>
|
|
<div>
|
|
{% assign entries = combined_experience %}
|
|
{% include cv/experience.liquid %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% comment %} Now render all other sections except Experience and Volunteer {% endcomment %}
|
|
{% for section_pair in cv.sections %}
|
|
{% assign section_title = section_pair[0] %}
|
|
{% assign section_entries = section_pair[1] %}
|
|
|
|
{% comment %} Skip Experience and Volunteer as we've already processed them combined {% endcomment %}
|
|
{% if section_title == 'Experience' or section_title == 'Volunteer' %}
|
|
{% continue %}
|
|
{% endif %}
|
|
|
|
<a class="anchor" id="{{ section_title | slugify }}"></a>
|
|
<div class="card mt-3 p-3">
|
|
<h3 class="card-title font-weight-medium">{{ section_title }}</h3>
|
|
<div>
|
|
{% if section_title == 'Education' %}
|
|
{% assign entries = section_entries %}
|
|
{% include cv/education.liquid %}
|
|
{% elsif section_title == 'Awards' or section_title == 'Honors and Awards' %}
|
|
{% assign entries = section_entries %}
|
|
{% include cv/awards.liquid %}
|
|
{% elsif section_title == 'Publications' %}
|
|
{% assign entries = section_entries %}
|
|
{% include cv/publications.liquid %}
|
|
{% elsif section_title == 'Skills' %}
|
|
{% assign entries = section_entries %}
|
|
{% include cv/skills.liquid %}
|
|
{% elsif section_title == 'Languages' %}
|
|
{% assign entries = section_entries %}
|
|
{% include cv/languages.liquid %}
|
|
{% elsif section_title == 'Interests' or section_title == 'Academic Interests' %}
|
|
{% assign entries = section_entries %}
|
|
{% include cv/interests.liquid %}
|
|
{% elsif section_title == 'Certificates' %}
|
|
{% assign entries = section_entries %}
|
|
{% include cv/certificates.liquid %}
|
|
{% elsif section_title == 'Projects' or section_title == 'Open Source Projects' %}
|
|
{% assign entries = section_entries %}
|
|
{% include cv/projects.liquid %}
|
|
{% elsif section_title == 'References' %}
|
|
{% assign entries = section_entries %}
|
|
{% include cv/references.liquid %}
|
|
{% else %}
|
|
<!-- Generic section -->
|
|
{% for entry in section_entries %}
|
|
{% if entry.bullet %}
|
|
<ul class="card-text font-weight-light list-group list-group-flush">
|
|
<li class="list-group-item">{{ entry.bullet | markdownify | remove: '<p>' | remove: '</p>' }}</li>
|
|
</ul>
|
|
{% elsif entry.label %}
|
|
<div class="card-text font-weight-light">
|
|
<strong>{{ entry.label }}:</strong> {{ entry.details }}
|
|
</div>
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
|
|
{% elsif render_jsonresume and site.data.resume %}
|
|
{% comment %} JSONResume format {% endcomment %}
|
|
|
|
<!-- Contact Information -->
|
|
{% if site.data.resume.basics %}
|
|
<div class="card mt-3 p-3">
|
|
<h3 class="card-title font-weight-medium">Contact Information</h3>
|
|
{% assign basics = site.data.resume.basics %}
|
|
<table class="table table-cv table-sm table-borderless">
|
|
{% if basics.name %}
|
|
<tr>
|
|
<td class="p-1 pr-2 font-weight-bold"><b>Name</b></td>
|
|
<td class="p-1 pl-2 font-weight-light">{{ basics.name }}</td>
|
|
</tr>
|
|
{% endif %}
|
|
{% if basics.label %}
|
|
<tr>
|
|
<td class="p-1 pr-2 font-weight-bold"><b>Professional Title</b></td>
|
|
<td class="p-1 pl-2 font-weight-light">{{ basics.label }}</td>
|
|
</tr>
|
|
{% endif %}
|
|
{% if basics.email %}
|
|
<tr>
|
|
<td class="p-1 pr-2 font-weight-bold"><b>Email</b></td>
|
|
<td class="p-1 pl-2 font-weight-light">{{ basics.email }}</td>
|
|
</tr>
|
|
{% endif %}
|
|
{% if basics.phone %}
|
|
<tr>
|
|
<td class="p-1 pr-2 font-weight-bold"><b>Phone</b></td>
|
|
<td class="p-1 pl-2 font-weight-light">{{ basics.phone }}</td>
|
|
</tr>
|
|
{% endif %}
|
|
{% if basics.location %}
|
|
<tr>
|
|
<td class="p-1 pr-2 font-weight-bold"><b>Location</b></td>
|
|
<td class="p-1 pl-2 font-weight-light">
|
|
{% if basics.location.address %}{{ basics.location.address }}, {% endif %}
|
|
{% if basics.location.city %}{{ basics.location.city }}, {% endif %}
|
|
{% if basics.location.region %}{{ basics.location.region }} {% endif %}
|
|
{% if basics.location.postalCode %}{{ basics.location.postalCode }}{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
{% if basics.url %}
|
|
<tr>
|
|
<td class="p-1 pr-2 font-weight-bold"><b>Website</b></td>
|
|
<td class="p-1 pl-2 font-weight-light">
|
|
<a href="{{ basics.url }}" target="_blank">{{ basics.url }}</a>
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
</table>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Summary -->
|
|
{% if site.data.resume.basics.summary %}
|
|
<div class="card mt-3 p-3">
|
|
<h3 class="card-title font-weight-medium">Professional Summary</h3>
|
|
<p>{{ site.data.resume.basics.summary | markdownify | remove: '<p>' | remove: '</p>' }}</p>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- JSONResume Sections - Merge work and volunteer into Experience -->
|
|
{% assign combined_experience = site.data.resume.work | concat: site.data.resume.volunteer %}
|
|
{% if combined_experience.size > 0 %}
|
|
<a class="anchor" id="experience"></a>
|
|
<div class="card mt-3 p-3">
|
|
<h3 class="card-title font-weight-medium">Experience</h3>
|
|
<div>
|
|
{% assign entries = combined_experience %}
|
|
{% include cv/experience.liquid %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Education -->
|
|
{% if site.data.resume.education.size > 0 %}
|
|
<a class="anchor" id="education"></a>
|
|
<div class="card mt-3 p-3">
|
|
<h3 class="card-title font-weight-medium">Education</h3>
|
|
<div>
|
|
{% assign entries = site.data.resume.education %}
|
|
{% include cv/education.liquid %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Awards -->
|
|
{% if site.data.resume.awards.size > 0 %}
|
|
<a class="anchor" id="awards"></a>
|
|
<div class="card mt-3 p-3">
|
|
<h3 class="card-title font-weight-medium">Awards</h3>
|
|
<div>
|
|
{% assign entries = site.data.resume.awards %}
|
|
{% include cv/awards.liquid %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Publications -->
|
|
{% if site.data.resume.publications.size > 0 %}
|
|
<a class="anchor" id="publications"></a>
|
|
<div class="card mt-3 p-3">
|
|
<h3 class="card-title font-weight-medium">Publications</h3>
|
|
<div>
|
|
{% assign entries = site.data.resume.publications %}
|
|
{% include cv/publications.liquid %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Skills -->
|
|
{% if site.data.resume.skills.size > 0 %}
|
|
<a class="anchor" id="skills"></a>
|
|
<div class="card mt-3 p-3">
|
|
<h3 class="card-title font-weight-medium">Skills</h3>
|
|
<div>
|
|
{% assign entries = site.data.resume.skills %}
|
|
{% include cv/skills.liquid %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Languages -->
|
|
{% if site.data.resume.languages.size > 0 %}
|
|
<a class="anchor" id="languages"></a>
|
|
<div class="card mt-3 p-3">
|
|
<h3 class="card-title font-weight-medium">Languages</h3>
|
|
<div>
|
|
{% assign entries = site.data.resume.languages %}
|
|
{% include cv/languages.liquid %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Interests -->
|
|
{% if site.data.resume.interests.size > 0 %}
|
|
<a class="anchor" id="interests"></a>
|
|
<div class="card mt-3 p-3">
|
|
<h3 class="card-title font-weight-medium">Interests</h3>
|
|
<div>
|
|
{% assign entries = site.data.resume.interests %}
|
|
{% include cv/interests.liquid %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Certificates -->
|
|
{% if site.data.resume.certificates.size > 0 %}
|
|
<a class="anchor" id="certificates"></a>
|
|
<div class="card mt-3 p-3">
|
|
<h3 class="card-title font-weight-medium">Certificates</h3>
|
|
<div>
|
|
{% assign entries = site.data.resume.certificates %}
|
|
{% include cv/certificates.liquid %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Projects -->
|
|
{% if site.data.resume.projects.size > 0 %}
|
|
<a class="anchor" id="projects"></a>
|
|
<div class="card mt-3 p-3">
|
|
<h3 class="card-title font-weight-medium">Projects</h3>
|
|
<div>
|
|
{% assign entries = site.data.resume.projects %}
|
|
{% include cv/projects.liquid %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- References -->
|
|
{% if site.data.resume.references.size > 0 %}
|
|
<a class="anchor" id="references"></a>
|
|
<div class="card mt-3 p-3">
|
|
<h3 class="card-title font-weight-medium">References</h3>
|
|
<div>
|
|
{% assign entries = site.data.resume.references %}
|
|
{% include cv/references.liquid %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% else %}
|
|
<p>No CV data found. Please configure either RenderCV (cv.yml) or JSONResume (resume.json) data.</p>
|
|
{% endif %}
|
|
</div>
|
|
</article>
|
|
</div>
|