al_folio_cv 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e37c2fee391369069d49478404ddc88f4b69337992b96d7cba2ec39472c6c16c
4
+ data.tar.gz: 49c29ef1bbaccbff167e8d4a86dfad41efef7c5ec73beab5239cd81a1b619de2
5
+ SHA512:
6
+ metadata.gz: 347cd226c6de23f5cc8797594643f61d02a274ad2ae0d011ceaf6b28ac04334c48dbe33deb69c5948c073a0ee7070b77a4a15a5314e66e810a1c3f0dccd6093c
7
+ data.tar.gz: 8d3ece2ff37d0298b3c2a9ea60fb261ed485d7a3713b7a76169690c40fef87ae12fb586b35e98f913b571cda5436958c37b074611fbcd11facca206b64b2c934
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # Changelog
2
+
3
+ ## 1.0.0
4
+
5
+ - Initial CV extraction from `al_folio_core`.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 al-folio maintainers
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.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # al-folio-cv
2
+
3
+ CV rendering plugin for al-folio v1.x.
4
+
5
+ ## What it provides
6
+
7
+ - Shared CV rendering templates used by `layout: cv`
8
+ - CV helper Liquid tag: `{% al_folio_cv_render %}`
9
+ - Packaged stylesheet at `/assets/css/al-folio-cv.css`
10
+
11
+ ## Usage
12
+
13
+ Add the gem and plugin:
14
+
15
+ ```ruby
16
+ gem 'al_folio_cv'
17
+ ```
18
+
19
+ ```yml
20
+ plugins:
21
+ - al_folio_cv
22
+ al_folio:
23
+ features:
24
+ cv:
25
+ enabled: true
26
+ ```
27
+
28
+ `al_folio_core` delegates `layout: cv` rendering to this plugin.
@@ -0,0 +1 @@
1
+ div.container-link-button{margin-right:.5rem}table.table-cv{background-color:rgba(0,0,0,0) !important}table.table-cv td,table.table-cv th{padding:1px}a.btncv{color:var(--global-text-color) !important;border:1px solid var(--global-text-color) !important;border-radius:.125rem;padding-left:1rem;padding-right:1rem;padding-top:.25rem;padding-bottom:.25rem;text-decoration:none;font-weight:400;font-size:.7rem;text-align:center;vertical-align:middle;text-transform:uppercase;white-space:nowrap}a.btncv:hover{color:var(--global-theme-color) !important;border-color:var(--global-theme-color) !important;text-decoration:none !important}p.location{font-size:.7rem;white-space:nowrap}i.iconlocation{color:var(--global-theme-color);font-size:.8rem}i.iconinstitution{color:var(--global-theme-color);font-size:.95rem;margin-right:.3rem}i.icondepartment{color:var(--global-theme-color);font-size:.8rem;margin-right:.3rem}table.institution{margin-bottom:1rem}td.department{font-size:.8rem}div.container-links{display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:flex-start;margin-top:1rem;margin-bottom:.5rem}div.container-pdf{display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:flex-start}div.list-groups{display:flex;flex-wrap:wrap;justify-content:flex-start;flex-direction:row;align-content:center}div.list-group{display:flex;flex-wrap:wrap;flex-direction:column;align-items:flex-start;margin-bottom:2rem}td.list-group-category{color:var(--global-theme-color);margin-bottom:.5rem}td.list-group-category-icon{font-size:.8rem;color:var(--global-theme-color);width:1.4rem;padding-right:.4rem}td.list-group-name{font-size:.8rem}td.list-group-level{font-size:.8rem;padding-left:.5rem}td.list-group-school{font-size:.7rem;padding-left:.5rem;text-align:center}p.list-group-time{font-size:.7rem;padding-left:.5rem}td.list-group-link{padding-left:.5rem}a.anchor{display:block;position:relative;top:-50px;visibility:hidden}ul.timeline{margin-top:2rem;margin-bottom:2rem}ul.timeline li{position:relative;min-height:2.2rem;color:var(--global-text-color);list-style-position:inside}span.badge-toc{color:var(--global-bg-color);background-color:var(--global-theme-color);border-radius:.125rem;padding:.125rem .5rem .125rem .5rem;font-weight:700 !important;display:inline-block;inline-size:fit-content}ul.timeline li::before{content:"";min-height:2.5rem;width:1px;background:var(--global-text-color);margin:0;padding:0;position:absolute;left:2px;top:-0.5rem}/*# sourceMappingURL=al-folio-cv.css.map */
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AlFolioCv
4
+ VERSION = "1.0.0"
5
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jekyll"
4
+ require_relative "al_folio_cv/version"
5
+
6
+ module AlFolioCv
7
+ PLUGIN_ROOT = File.expand_path("..", __dir__)
8
+ TEMPLATES_ROOT = File.join(PLUGIN_ROOT, "templates")
9
+ ASSETS_ROOT = File.join(PLUGIN_ROOT, "assets")
10
+
11
+ class PluginStaticFile < Jekyll::StaticFile; end
12
+
13
+ module_function
14
+
15
+ def enabled?(site)
16
+ site.config.dig("al_folio", "features", "cv", "enabled") != false
17
+ end
18
+
19
+ class AssetsGenerator < Jekyll::Generator
20
+ safe true
21
+ priority :low
22
+
23
+ def generate(site)
24
+ return unless AlFolioCv.enabled?(site)
25
+
26
+ Dir.glob(File.join(ASSETS_ROOT, "**", "*")).sort.each do |source_path|
27
+ next if File.directory?(source_path)
28
+
29
+ relative_dir = File.dirname(source_path).sub("#{PLUGIN_ROOT}/", "")
30
+ site.static_files << PluginStaticFile.new(site, PLUGIN_ROOT, relative_dir, File.basename(source_path))
31
+ end
32
+ end
33
+ end
34
+
35
+ class RenderTag < Liquid::Tag
36
+ def render(context)
37
+ site = context.registers[:site]
38
+ return "" unless site && AlFolioCv.enabled?(site)
39
+
40
+ Liquid::Template.parse("{% include cv/render.liquid %}").render!(
41
+ context.environments.first,
42
+ registers: context.registers
43
+ )
44
+ end
45
+ end
46
+ end
47
+
48
+ Liquid::Template.register_tag("al_folio_cv_render", AlFolioCv::RenderTag)
49
+
50
+ Jekyll::Hooks.register :site, :after_init do |site|
51
+ next unless site.respond_to?(:includes_load_paths)
52
+
53
+ include_path = AlFolioCv::TEMPLATES_ROOT
54
+ site.includes_load_paths << include_path unless site.includes_load_paths.include?(include_path)
55
+ end
@@ -0,0 +1,66 @@
1
+ {% comment %}
2
+ Unified awards entry renderer for both formats
3
+ {% endcomment %}
4
+
5
+ <ul class="card-text font-weight-light list-group list-group-flush">
6
+ {% for entry in entries %}
7
+ <li class="list-group-item">
8
+ <div class="row">
9
+ {% capture start_date %}
10
+ {% if entry.date %}{{ entry.date }}{% endif %}
11
+ {% endcapture %}
12
+
13
+ {% if start_date != '' %}
14
+ <div class="col-xs-2 col-sm-2 col-md-2 text-center">
15
+ <table class="table-cv">
16
+ <tbody>
17
+ <tr>
18
+ <td>
19
+ <span class="badge font-weight-bold danger-color-dark text-uppercase align-middle" style="min-width: 75px">
20
+ {{- start_date | split: '-' | slice: 0, 1 | join: '' -}}
21
+ </span>
22
+ </td>
23
+ </tr>
24
+ </tbody>
25
+ </table>
26
+ </div>
27
+ <div class="col-xs-10 col-sm-10 col-md-10 mt-2 mt-md-0">
28
+ {% if entry.url %}
29
+ <h6 class="title font-weight-bold ml-1 ml-md-4">
30
+ <a href="{{ entry.url }}">{{ entry.title }}</a>
31
+ </h6>
32
+ {% elsif entry.title %}
33
+ <h6 class="title font-weight-bold ml-1 ml-md-4">{{ entry.title }}</h6>
34
+ {% endif %}
35
+
36
+ {% if entry.awarder %}
37
+ <h6 class="ml-1 ml-md-4" style="font-size: 0.95rem">{{ entry.awarder }}</h6>
38
+ {% endif %}
39
+
40
+ {% if entry.summary %}
41
+ <p class="ml-1 ml-md-4">{{ entry.summary | markdownify | remove: '<p>' | remove: '</p>' }}</p>
42
+ {% endif %}
43
+ </div>
44
+ {% else %}
45
+ <div class="col-xs-12 col-sm-12 col-md-12">
46
+ {% if entry.url %}
47
+ <h6 class="title font-weight-bold ml-1 ml-md-4">
48
+ <a href="{{ entry.url }}">{{ entry.title }}</a>
49
+ </h6>
50
+ {% elsif entry.title %}
51
+ <h6 class="title font-weight-bold ml-1 ml-md-4">{{ entry.title }}</h6>
52
+ {% endif %}
53
+
54
+ {% if entry.awarder %}
55
+ <h6 class="ml-1 ml-md-4" style="font-size: 0.95rem">{{ entry.awarder }}</h6>
56
+ {% endif %}
57
+
58
+ {% if entry.summary %}
59
+ <p class="ml-1 ml-md-4">{{ entry.summary | markdownify | remove: '<p>' | remove: '</p>' }}</p>
60
+ {% endif %}
61
+ </div>
62
+ {% endif %}
63
+ </div>
64
+ </li>
65
+ {% endfor %}
66
+ </ul>
@@ -0,0 +1,28 @@
1
+ {% comment %}
2
+ Unified certificates entry renderer for both formats
3
+ {% endcomment %}
4
+
5
+ <ul class="card-text font-weight-light list-group list-group-flush">
6
+ {% for entry in entries %}
7
+ <li class="list-group-item">
8
+ {% if entry.icon %}
9
+ <i class="{{ entry.icon }}"></i>
10
+ {% endif %}
11
+ {% if entry.url %}
12
+ <strong
13
+ ><a href="{{ entry.url }}" target="_blank">{{ entry.name }}</a></strong
14
+ >
15
+ {% else %}
16
+ <strong>{{ entry.name }}</strong>
17
+ {% endif %}
18
+
19
+ {% if entry.issuer %}
20
+ - <em>{{ entry.issuer }}</em>
21
+ {% endif %}
22
+
23
+ {% if entry.date %}
24
+ ({{ entry.date | split: '-' | slice: 0, 1 | join: '' }})
25
+ {% endif %}
26
+ </li>
27
+ {% endfor %}
28
+ </ul>
@@ -0,0 +1,93 @@
1
+ {% comment %}
2
+ Unified education entry renderer for both RenderCV and JSONResume formats
3
+ Handles both:
4
+ - RenderCV: institution, area, studyType (or degree), start_date, end_date, location, courses, highlights
5
+ - JSONResume: institution, area, studyType, startDate, endDate, location, courses, highlights
6
+ {% endcomment %}
7
+
8
+ <ul class="card-text font-weight-light list-group list-group-flush">
9
+ {% for entry in entries %}
10
+ <li class="list-group-item">
11
+ <div class="row">
12
+ <div class="col-xs-2 col-sm-2 col-md-2 text-center date-column">
13
+ {% capture start_date %}
14
+ {% if entry.start_date %}{{ entry.start_date }}{% elsif entry.startDate %}{{ entry.startDate }}{% endif %}
15
+ {% endcapture %}
16
+ {% capture end_date %}
17
+ {% if entry.end_date %}{{ entry.end_date }}{% elsif entry.endDate %}{{ entry.endDate }}{% endif %}
18
+ {% endcapture %}
19
+
20
+ {% if start_date != '' %}
21
+ {% comment %} Extract year only from dates like "1933-01-01" or just use "1933" as is {% endcomment %}
22
+ {% assign startDate = start_date | split: '-' | first %}
23
+ {% assign endDate = end_date | split: '-' | first | default: 'Present' %}
24
+ {% assign date = startDate | append: ' - ' | append: endDate %}
25
+ {% else %}
26
+ {% assign date = null %}
27
+ {% endif %}
28
+
29
+ <table class="table-cv">
30
+ <tbody>
31
+ <tr>
32
+ <td>
33
+ {% if date %}
34
+ <span class="badge font-weight-bold danger-color-dark text-uppercase align-middle" style="min-width: 75px">{{ date }}</span>
35
+ {% endif %}
36
+ </td>
37
+ </tr>
38
+ {% capture location %}
39
+ {% if entry.location %}{{ entry.location }}{% endif %}
40
+ {% endcapture %}
41
+ {% if location != '' %}
42
+ <tr>
43
+ <td>
44
+ <p class="location">
45
+ <i class="fa-solid fa-location-dot iconlocation"></i>
46
+ {{ location }}
47
+ </p>
48
+ </td>
49
+ </tr>
50
+ {% endif %}
51
+ </tbody>
52
+ </table>
53
+ </div>
54
+ <div class="col-xs-10 col-sm-10 col-md-10 mt-2 mt-md-0">
55
+ {% capture study_type %}
56
+ {% if entry.studyType %}{{ entry.studyType }}{% elsif entry.degree %}{{ entry.degree }}{% endif %}
57
+ {% endcapture %}
58
+
59
+ {% if entry.url %}
60
+ <h6 class="title font-weight-bold ml-1 ml-md-4">
61
+ <a href="{{ entry.url }}">{{ study_type }}</a>
62
+ </h6>
63
+ {% elsif study_type != '' %}
64
+ <h6 class="title font-weight-bold ml-1 ml-md-4">{{ study_type }}</h6>
65
+ {% endif %}
66
+
67
+ {% if entry.institution %}
68
+ <h6 class="ml-1 ml-md-4" style="font-size: 0.95rem">{{ entry.institution }}</h6>
69
+ {% endif %}
70
+
71
+ {% if entry.area %}
72
+ <h6 class="ml-1 ml-md-4" style="font-size: 0.95rem; font-style: italic">{{ entry.area }}</h6>
73
+ {% endif %}
74
+
75
+ {% if entry.courses or entry.highlights %}
76
+ <ul class="items">
77
+ {% for item in entry.courses %}
78
+ <li>
79
+ <span class="item">{{ item }}</span>
80
+ </li>
81
+ {% endfor %}
82
+ {% for item in entry.highlights %}
83
+ <li>
84
+ <span class="item">{{ item | markdownify | remove: '<p>' | remove: '</p>' }}</span>
85
+ </li>
86
+ {% endfor %}
87
+ </ul>
88
+ {% endif %}
89
+ </div>
90
+ </div>
91
+ </li>
92
+ {% endfor %}
93
+ </ul>
@@ -0,0 +1,91 @@
1
+ {% comment %}
2
+ Unified work/experience entry renderer for both RenderCV and JSONResume formats
3
+ Handles both:
4
+ - RenderCV: company, position, start_date, end_date, location, url, summary, highlights
5
+ - JSONResume: name, position, startDate, endDate, location, url, summary, highlights
6
+ {% endcomment %}
7
+
8
+ <ul class="card-text font-weight-light list-group list-group-flush">
9
+ {% for entry in entries %}
10
+ <li class="list-group-item">
11
+ <div class="row">
12
+ <div class="col-xs-2 col-sm-2 col-md-2 text-center date-column">
13
+ {% capture start_date %}
14
+ {% if entry.start_date %}{{ entry.start_date }}{% elsif entry.startDate %}{{ entry.startDate }}{% endif %}
15
+ {% endcapture %}
16
+ {% capture end_date %}
17
+ {% if entry.end_date %}{{ entry.end_date }}{% elsif entry.endDate %}{{ entry.endDate }}{% endif %}
18
+ {% endcapture %}
19
+
20
+ {% if start_date != '' %}
21
+ {% comment %} Extract year only from dates like "1933-01-01" or just use "1933" as is {% endcomment %}
22
+ {% assign startDate = start_date | split: '-' | first %}
23
+ {% assign endDate = end_date | split: '-' | first | default: 'Present' %}
24
+ {% assign date = startDate | append: ' - ' | append: endDate %}
25
+ {% else %}
26
+ {% assign date = '' %}
27
+ {% endif %}
28
+
29
+ <table class="table-cv">
30
+ <tbody>
31
+ <tr>
32
+ <td>
33
+ <span class="badge font-weight-bold danger-color-dark text-uppercase align-middle" style="min-width: 75px">{{ date }}</span>
34
+ </td>
35
+ </tr>
36
+ {% capture location %}
37
+ {% if entry.location %}{{ entry.location }}{% endif %}
38
+ {% endcapture %}
39
+ {% if location != '' %}
40
+ <tr>
41
+ <td>
42
+ <p class="location">
43
+ <i class="fa-solid fa-location-dot iconlocation"></i>
44
+ {{ location }}
45
+ </p>
46
+ </td>
47
+ </tr>
48
+ {% endif %}
49
+ </tbody>
50
+ </table>
51
+ </div>
52
+ <div class="col-xs-10 col-sm-10 col-md-10 mt-2 mt-md-0">
53
+ {% capture position_title %}
54
+ {% if entry.position %}{{ entry.position }}{% endif %}
55
+ {% endcapture %}
56
+
57
+ {% if entry.url %}
58
+ <h6 class="title font-weight-bold ml-1 ml-md-4">
59
+ <a href="{{ entry.url }}">{{ position_title }}</a>
60
+ </h6>
61
+ {% elsif position_title != '' %}
62
+ <h6 class="title font-weight-bold ml-1 ml-md-4">{{ position_title }}</h6>
63
+ {% endif %}
64
+
65
+ {% capture company_name %}
66
+ {% if entry.name %}{{ entry.name }}{% elsif entry.company %}{{ entry.company }}{% elsif entry.organization %}{{ entry.organization }}{% endif %}
67
+ {% endcapture %}
68
+ {% if company_name != '' %}
69
+ <h6 class="ml-1 ml-md-4" style="font-size: 0.95rem">{{ company_name }}</h6>
70
+ {% endif %}
71
+
72
+ {% if entry.summary %}
73
+ <h6 class="ml-1 ml-md-4" style="font-size: 0.95rem; font-style: italic">
74
+ {{ entry.summary | markdownify | remove: '<p>' | remove: '</p>' }}
75
+ </h6>
76
+ {% endif %}
77
+
78
+ {% if entry.highlights %}
79
+ <ul class="items">
80
+ {% for item in entry.highlights %}
81
+ <li>
82
+ <span class="item">{{ item | markdownify | remove: '<p>' | remove: '</p>' }}</span>
83
+ </li>
84
+ {% endfor %}
85
+ </ul>
86
+ {% endif %}
87
+ </div>
88
+ </div>
89
+ </li>
90
+ {% endfor %}
91
+ </ul>
@@ -0,0 +1,29 @@
1
+ {% comment %}
2
+ Unified interests entry renderer for both formats
3
+ {% endcomment %}
4
+
5
+ <div class="card-text font-weight-light">
6
+ {% for entry in entries %}
7
+ <div class="interest-item">
8
+ {% if entry.icon %}
9
+ <i class="{{ entry.icon }}"></i>
10
+ {% endif %}
11
+ <strong>{{ entry.name }}:</strong>
12
+ {% if entry.keywords %}
13
+ {% for keyword in entry.keywords %}
14
+ {% if forloop.last %}
15
+ {{ keyword }}
16
+ {% else %}
17
+ {{ keyword }},
18
+ {% endif %}
19
+ {% endfor %}
20
+ {% endif %}
21
+ </div>
22
+ {% endfor %}
23
+ </div>
24
+
25
+ <style>
26
+ .interest-item {
27
+ padding: 0.5rem 0;
28
+ }
29
+ </style>
@@ -0,0 +1,28 @@
1
+ {% comment %}
2
+ Unified languages entry renderer for both formats
3
+ - RenderCV uses: name, summary
4
+ - JSONResume uses: language, fluency
5
+ {% endcomment %}
6
+
7
+ <div class="card-text font-weight-light">
8
+ {% for entry in entries %}
9
+ <div class="language-item">
10
+ {% if entry.icon %}
11
+ <i class="{{ entry.icon }}"></i>
12
+ {% endif %}
13
+ {% capture lang_name %}
14
+ {% if entry.name %}{{ entry.name }}{% elsif entry.language %}{{ entry.language }}{% endif %}
15
+ {% endcapture %}
16
+ {% capture fluency %}
17
+ {% if entry.summary %}{{ entry.summary }}{% elsif entry.fluency %}{{ entry.fluency }}{% endif %}
18
+ {% endcapture %}
19
+ <strong>{{ lang_name }}:</strong> {{ fluency }}
20
+ </div>
21
+ {% endfor %}
22
+ </div>
23
+
24
+ <style>
25
+ .language-item {
26
+ padding: 0.5rem 0;
27
+ }
28
+ </style>
@@ -0,0 +1,31 @@
1
+ {% comment %}
2
+ Unified projects entry renderer for both formats
3
+ {% endcomment %}
4
+
5
+ <ul class="card-text font-weight-light list-group list-group-flush">
6
+ {% for entry in entries %}
7
+ <li class="list-group-item">
8
+ {% if entry.url %}
9
+ <h6 class="title font-weight-bold">
10
+ <a href="{{ entry.url }}" target="_blank">{{ entry.name }}</a>
11
+ </h6>
12
+ {% else %}
13
+ <h6 class="title font-weight-bold">{{ entry.name }}</h6>
14
+ {% endif %}
15
+
16
+ {% if entry.summary %}
17
+ <p>{{ entry.summary | markdownify | remove: '<p>' | remove: '</p>' }}</p>
18
+ {% endif %}
19
+
20
+ {% if entry.highlights %}
21
+ <ul class="items">
22
+ {% for item in entry.highlights %}
23
+ <li>
24
+ <span class="item">{{ item | markdownify | remove: '<p>' | remove: '</p>' }}</span>
25
+ </li>
26
+ {% endfor %}
27
+ </ul>
28
+ {% endif %}
29
+ </li>
30
+ {% endfor %}
31
+ </ul>
@@ -0,0 +1,70 @@
1
+ {% comment %}
2
+ Unified publications entry renderer for both formats
3
+ {% endcomment %}
4
+
5
+ <ul class="card-text font-weight-light list-group list-group-flush">
6
+ {% for entry in entries %}
7
+ <li class="list-group-item">
8
+ <div class="row">
9
+ {% capture pub_date %}
10
+ {% if entry.releaseDate %}{{ entry.releaseDate }}{% elsif entry.date %}{{ entry.date }}{% endif %}
11
+ {% endcapture %}
12
+
13
+ {% if pub_date != '' %}
14
+ <div class="col-xs-2 col-sm-2 col-md-2 text-center">
15
+ <table class="table-cv">
16
+ <tbody>
17
+ <tr>
18
+ <td>
19
+ <span class="badge font-weight-bold danger-color-dark text-uppercase align-middle" style="min-width: 75px">
20
+ {{- pub_date | split: '-' | slice: 0, 1 | join: '' -}}
21
+ </span>
22
+ </td>
23
+ </tr>
24
+ </tbody>
25
+ </table>
26
+ </div>
27
+ <div class="col-xs-10 col-sm-10 col-md-10 mt-2 mt-md-0">
28
+ {% if entry.url %}
29
+ <h6 class="title font-weight-bold ml-1 ml-md-4">
30
+ <a href="{{ entry.url }}">{{ entry.title | default: entry.name }}</a>
31
+ </h6>
32
+ {% elsif entry.title %}
33
+ <h6 class="title font-weight-bold ml-1 ml-md-4">{{ entry.title }}</h6>
34
+ {% endif %}
35
+
36
+ {% if entry.publisher %}
37
+ <h6 class="ml-1 ml-md-4" style="font-size: 0.95rem">
38
+ <em>{{ entry.publisher }}</em>
39
+ </h6>
40
+ {% endif %}
41
+
42
+ {% if entry.summary %}
43
+ <p class="ml-1 ml-md-4">{{ entry.summary | markdownify | remove: '<p>' | remove: '</p>' }}</p>
44
+ {% endif %}
45
+ </div>
46
+ {% else %}
47
+ <div class="col-xs-12 col-sm-12 col-md-12">
48
+ {% if entry.url %}
49
+ <h6 class="title font-weight-bold ml-1 ml-md-4">
50
+ <a href="{{ entry.url }}">{{ entry.title | default: entry.name }}</a>
51
+ </h6>
52
+ {% elsif entry.title %}
53
+ <h6 class="title font-weight-bold ml-1 ml-md-4">{{ entry.title }}</h6>
54
+ {% endif %}
55
+
56
+ {% if entry.publisher %}
57
+ <h6 class="ml-1 ml-md-4" style="font-size: 0.95rem">
58
+ <em>{{ entry.publisher }}</em>
59
+ </h6>
60
+ {% endif %}
61
+
62
+ {% if entry.summary %}
63
+ <p class="ml-1 ml-md-4">{{ entry.summary | markdownify | remove: '<p>' | remove: '</p>' }}</p>
64
+ {% endif %}
65
+ </div>
66
+ {% endif %}
67
+ </div>
68
+ </li>
69
+ {% endfor %}
70
+ </ul>
@@ -0,0 +1,15 @@
1
+ {% comment %}
2
+ Unified references entry renderer for both formats
3
+ {% endcomment %}
4
+
5
+ <ul class="card-text font-weight-light list-group list-group-flush">
6
+ {% for entry in entries %}
7
+ <li class="list-group-item">
8
+ {% if entry.icon %}
9
+ <i class="{{ entry.icon }}"></i>
10
+ {% endif %}
11
+ <strong>{{ entry.name }}</strong>
12
+ <p>{{ entry.reference | markdownify | remove: '<p>' | remove: '</p>' }}</p>
13
+ </li>
14
+ {% endfor %}
15
+ </ul>
@@ -0,0 +1,389 @@
1
+ {% comment %}
2
+ Unified CV layout that handles both RenderCV (YAML) and JSONResume (JSON) formats
3
+ - If page.cv_format is set, it determines which format to render:
4
+ - 'rendercv': Load and render only RenderCV data (site.data.cv.cv)
5
+ - 'jsonresume': Load and render only JSONResume data (site.data.resume)
6
+ - If page.cv_format is not set, the legacy behavior applies:
7
+ - RenderCV data is in site.data.cv.cv
8
+ - JSONResume data is in site.data.resume
9
+ - RenderCV is prioritized if both exist
10
+ Both formats use the same unified rendering includes for consistent output
11
+ {% endcomment %}
12
+
13
+ <div class="post">
14
+ <header class="post-header">
15
+ <h1 class="post-title">
16
+ {{ page.title }}
17
+ {% if page.cv_pdf %}
18
+ <a
19
+ {% if page.cv_pdf contains '://' %}
20
+ href="{{ page.cv_pdf }}"
21
+ {% else %}
22
+ href="{{ page.cv_pdf | relative_url }}"
23
+ {% endif %}
24
+ target="_blank"
25
+ rel="noopener noreferrer"
26
+ class="float-right"
27
+ >
28
+ <i class="fa-solid fa-file-pdf"></i>
29
+ </a>
30
+ {% endif %}
31
+ </h1>
32
+ {% if page.description %}
33
+ <p class="post-description">{{ page.description }}</p>
34
+ {% endif %}
35
+ </header>
36
+
37
+ <article>
38
+ <div class="cv">
39
+ {% comment %} Determine which CV format to render {% endcomment %}
40
+ {% assign render_rendercv = false %}
41
+ {% assign render_jsonresume = false %}
42
+
43
+ {% if page.cv_format == 'rendercv' %}
44
+ {% assign render_rendercv = true %}
45
+ {% elsif page.cv_format == 'jsonresume' %}
46
+ {% assign render_jsonresume = true %}
47
+ {% else %}
48
+ {% comment %} Legacy behavior: RenderCV takes priority if both exist {% endcomment %}
49
+ {% if site.data.cv and site.data.cv.cv %}
50
+ {% assign render_rendercv = true %}
51
+ {% elsif site.data.resume %}
52
+ {% assign render_jsonresume = true %}
53
+ {% endif %}
54
+ {% endif %}
55
+
56
+ {% if render_rendercv and site.data.cv and site.data.cv.cv %}
57
+ {% comment %} RenderCV format {% endcomment %}
58
+ {% assign cv = site.data.cv.cv %}
59
+
60
+ <!-- Header/Contact Information -->
61
+ {% if cv.name or cv.label or cv.location or cv.email or cv.phone or cv.website %}
62
+ <div class="card mt-3 p-3">
63
+ <h3 class="card-title font-weight-medium">Contact Information</h3>
64
+ <table class="table table-cv table-sm table-borderless">
65
+ {% if cv.name %}
66
+ <tr>
67
+ <td class="p-1 pr-2 font-weight-bold"><b>Name</b></td>
68
+ <td class="p-1 pl-2 font-weight-light">{{ cv.name }}</td>
69
+ </tr>
70
+ {% endif %}
71
+ {% if cv.label %}
72
+ <tr>
73
+ <td class="p-1 pr-2 font-weight-bold"><b>Professional Title</b></td>
74
+ <td class="p-1 pl-2 font-weight-light">{{ cv.label }}</td>
75
+ </tr>
76
+ {% endif %}
77
+ {% if cv.email %}
78
+ <tr>
79
+ <td class="p-1 pr-2 font-weight-bold"><b>Email</b></td>
80
+ <td class="p-1 pl-2 font-weight-light">{{ cv.email }}</td>
81
+ </tr>
82
+ {% endif %}
83
+ {% if cv.phone %}
84
+ <tr>
85
+ <td class="p-1 pr-2 font-weight-bold"><b>Phone</b></td>
86
+ <td class="p-1 pl-2 font-weight-light">{{ cv.phone }}</td>
87
+ </tr>
88
+ {% endif %}
89
+ {% if cv.address %}
90
+ <tr>
91
+ <td class="p-1 pr-2 font-weight-bold"><b>Location</b></td>
92
+ <td class="p-1 pl-2 font-weight-light">
93
+ {% if cv.address.street %}{{ cv.address.street }}, {% endif %}
94
+ {% if cv.address.city %}{{ cv.address.city }}, {% endif %}
95
+ {% if cv.address.region %}{{ cv.address.region }} {% endif %}
96
+ {% if cv.address.postalCode %}{{ cv.address.postalCode }}{% endif %}
97
+ </td>
98
+ </tr>
99
+ {% endif %}
100
+ {% if cv.website %}
101
+ <tr>
102
+ <td class="p-1 pr-2 font-weight-bold"><b>Website</b></td>
103
+ <td class="p-1 pl-2 font-weight-light">
104
+ <a href="{{ cv.website }}" target="_blank">{{ cv.website }}</a>
105
+ </td>
106
+ </tr>
107
+ {% endif %}
108
+ </table>
109
+ </div>
110
+ {% endif %}
111
+
112
+ <!-- Summary -->
113
+ {% if cv.summary %}
114
+ <div class="card mt-3 p-3">
115
+ <h3 class="card-title font-weight-medium">Professional Summary</h3>
116
+ <p>{{ cv.summary | markdownify | remove: '<p>' | remove: '</p>' }}</p>
117
+ </div>
118
+ {% endif %}
119
+
120
+ <!-- RenderCV Sections - Merge Experience and Volunteer -->
121
+ {% comment %} First, combine Experience and Volunteer entries {% endcomment %}
122
+ {% assign empty_array = '' | split: ',' %}
123
+ {% assign exp = cv.sections.Experience | default: empty_array %}
124
+ {% assign vol = cv.sections.Volunteer | default: empty_array %}
125
+ {% assign combined_experience = exp | concat: vol %}
126
+ {% if combined_experience.size > 0 %}
127
+ <a class="anchor" id="experience"></a>
128
+ <div class="card mt-3 p-3">
129
+ <h3 class="card-title font-weight-medium">Experience</h3>
130
+ <div>
131
+ {% assign entries = combined_experience %}
132
+ {% include cv/experience.liquid %}
133
+ </div>
134
+ </div>
135
+ {% endif %}
136
+
137
+ {% comment %} Now render all other sections except Experience and Volunteer {% endcomment %}
138
+ {% for section_pair in cv.sections %}
139
+ {% assign section_title = section_pair[0] %}
140
+ {% assign section_entries = section_pair[1] %}
141
+
142
+ {% comment %} Skip Experience and Volunteer as we've already processed them combined {% endcomment %}
143
+ {% if section_title == 'Experience' or section_title == 'Volunteer' %}
144
+ {% continue %}
145
+ {% endif %}
146
+
147
+ <a class="anchor" id="{{ section_title | slugify }}"></a>
148
+ <div class="card mt-3 p-3">
149
+ <h3 class="card-title font-weight-medium">{{ section_title }}</h3>
150
+ <div>
151
+ {% if section_title == 'Education' %}
152
+ {% assign entries = section_entries %}
153
+ {% include cv/education.liquid %}
154
+ {% elsif section_title == 'Awards' or section_title == 'Honors and Awards' %}
155
+ {% assign entries = section_entries %}
156
+ {% include cv/awards.liquid %}
157
+ {% elsif section_title == 'Publications' %}
158
+ {% assign entries = section_entries %}
159
+ {% include cv/publications.liquid %}
160
+ {% elsif section_title == 'Skills' %}
161
+ {% assign entries = section_entries %}
162
+ {% include cv/skills.liquid %}
163
+ {% elsif section_title == 'Languages' %}
164
+ {% assign entries = section_entries %}
165
+ {% include cv/languages.liquid %}
166
+ {% elsif section_title == 'Interests' or section_title == 'Academic Interests' %}
167
+ {% assign entries = section_entries %}
168
+ {% include cv/interests.liquid %}
169
+ {% elsif section_title == 'Certificates' %}
170
+ {% assign entries = section_entries %}
171
+ {% include cv/certificates.liquid %}
172
+ {% elsif section_title == 'Projects' or section_title == 'Open Source Projects' %}
173
+ {% assign entries = section_entries %}
174
+ {% include cv/projects.liquid %}
175
+ {% elsif section_title == 'References' %}
176
+ {% assign entries = section_entries %}
177
+ {% include cv/references.liquid %}
178
+ {% else %}
179
+ <!-- Generic section -->
180
+ {% for entry in section_entries %}
181
+ {% if entry.bullet %}
182
+ <ul class="card-text font-weight-light list-group list-group-flush">
183
+ <li class="list-group-item">{{ entry.bullet | markdownify | remove: '<p>' | remove: '</p>' }}</li>
184
+ </ul>
185
+ {% elsif entry.label %}
186
+ <div class="card-text font-weight-light">
187
+ <strong>{{ entry.label }}:</strong> {{ entry.details }}
188
+ </div>
189
+ {% endif %}
190
+ {% endfor %}
191
+ {% endif %}
192
+ </div>
193
+ </div>
194
+ {% endfor %}
195
+
196
+ {% elsif render_jsonresume and site.data.resume %}
197
+ {% comment %} JSONResume format {% endcomment %}
198
+
199
+ <!-- Contact Information -->
200
+ {% if site.data.resume.basics %}
201
+ <div class="card mt-3 p-3">
202
+ <h3 class="card-title font-weight-medium">Contact Information</h3>
203
+ {% assign basics = site.data.resume.basics %}
204
+ <table class="table table-cv table-sm table-borderless">
205
+ {% if basics.name %}
206
+ <tr>
207
+ <td class="p-1 pr-2 font-weight-bold"><b>Name</b></td>
208
+ <td class="p-1 pl-2 font-weight-light">{{ basics.name }}</td>
209
+ </tr>
210
+ {% endif %}
211
+ {% if basics.label %}
212
+ <tr>
213
+ <td class="p-1 pr-2 font-weight-bold"><b>Professional Title</b></td>
214
+ <td class="p-1 pl-2 font-weight-light">{{ basics.label }}</td>
215
+ </tr>
216
+ {% endif %}
217
+ {% if basics.email %}
218
+ <tr>
219
+ <td class="p-1 pr-2 font-weight-bold"><b>Email</b></td>
220
+ <td class="p-1 pl-2 font-weight-light">{{ basics.email }}</td>
221
+ </tr>
222
+ {% endif %}
223
+ {% if basics.phone %}
224
+ <tr>
225
+ <td class="p-1 pr-2 font-weight-bold"><b>Phone</b></td>
226
+ <td class="p-1 pl-2 font-weight-light">{{ basics.phone }}</td>
227
+ </tr>
228
+ {% endif %}
229
+ {% if basics.location %}
230
+ <tr>
231
+ <td class="p-1 pr-2 font-weight-bold"><b>Location</b></td>
232
+ <td class="p-1 pl-2 font-weight-light">
233
+ {% if basics.location.address %}{{ basics.location.address }}, {% endif %}
234
+ {% if basics.location.city %}{{ basics.location.city }}, {% endif %}
235
+ {% if basics.location.region %}{{ basics.location.region }} {% endif %}
236
+ {% if basics.location.postalCode %}{{ basics.location.postalCode }}{% endif %}
237
+ </td>
238
+ </tr>
239
+ {% endif %}
240
+ {% if basics.url %}
241
+ <tr>
242
+ <td class="p-1 pr-2 font-weight-bold"><b>Website</b></td>
243
+ <td class="p-1 pl-2 font-weight-light">
244
+ <a href="{{ basics.url }}" target="_blank">{{ basics.url }}</a>
245
+ </td>
246
+ </tr>
247
+ {% endif %}
248
+ </table>
249
+ </div>
250
+ {% endif %}
251
+
252
+ <!-- Summary -->
253
+ {% if site.data.resume.basics.summary %}
254
+ <div class="card mt-3 p-3">
255
+ <h3 class="card-title font-weight-medium">Professional Summary</h3>
256
+ <p>{{ site.data.resume.basics.summary | markdownify | remove: '<p>' | remove: '</p>' }}</p>
257
+ </div>
258
+ {% endif %}
259
+
260
+ <!-- JSONResume Sections - Merge work and volunteer into Experience -->
261
+ {% assign empty_array = '' | split: ',' %}
262
+ {% assign work = site.data.resume.work | default: empty_array %}
263
+ {% assign vol = site.data.resume.volunteer | default: empty_array %}
264
+ {% assign combined_experience = work | concat: vol %}
265
+ {% if combined_experience.size > 0 %}
266
+ <a class="anchor" id="experience"></a>
267
+ <div class="card mt-3 p-3">
268
+ <h3 class="card-title font-weight-medium">Experience</h3>
269
+ <div>
270
+ {% assign entries = combined_experience %}
271
+ {% include cv/experience.liquid %}
272
+ </div>
273
+ </div>
274
+ {% endif %}
275
+
276
+ <!-- Education -->
277
+ {% if site.data.resume.education.size > 0 %}
278
+ <a class="anchor" id="education"></a>
279
+ <div class="card mt-3 p-3">
280
+ <h3 class="card-title font-weight-medium">Education</h3>
281
+ <div>
282
+ {% assign entries = site.data.resume.education %}
283
+ {% include cv/education.liquid %}
284
+ </div>
285
+ </div>
286
+ {% endif %}
287
+
288
+ <!-- Awards -->
289
+ {% if site.data.resume.awards.size > 0 %}
290
+ <a class="anchor" id="awards"></a>
291
+ <div class="card mt-3 p-3">
292
+ <h3 class="card-title font-weight-medium">Awards</h3>
293
+ <div>
294
+ {% assign entries = site.data.resume.awards %}
295
+ {% include cv/awards.liquid %}
296
+ </div>
297
+ </div>
298
+ {% endif %}
299
+
300
+ <!-- Publications -->
301
+ {% if site.data.resume.publications.size > 0 %}
302
+ <a class="anchor" id="publications"></a>
303
+ <div class="card mt-3 p-3">
304
+ <h3 class="card-title font-weight-medium">Publications</h3>
305
+ <div>
306
+ {% assign entries = site.data.resume.publications %}
307
+ {% include cv/publications.liquid %}
308
+ </div>
309
+ </div>
310
+ {% endif %}
311
+
312
+ <!-- Skills -->
313
+ {% if site.data.resume.skills.size > 0 %}
314
+ <a class="anchor" id="skills"></a>
315
+ <div class="card mt-3 p-3">
316
+ <h3 class="card-title font-weight-medium">Skills</h3>
317
+ <div>
318
+ {% assign entries = site.data.resume.skills %}
319
+ {% include cv/skills.liquid %}
320
+ </div>
321
+ </div>
322
+ {% endif %}
323
+
324
+ <!-- Languages -->
325
+ {% if site.data.resume.languages.size > 0 %}
326
+ <a class="anchor" id="languages"></a>
327
+ <div class="card mt-3 p-3">
328
+ <h3 class="card-title font-weight-medium">Languages</h3>
329
+ <div>
330
+ {% assign entries = site.data.resume.languages %}
331
+ {% include cv/languages.liquid %}
332
+ </div>
333
+ </div>
334
+ {% endif %}
335
+
336
+ <!-- Interests -->
337
+ {% if site.data.resume.interests.size > 0 %}
338
+ <a class="anchor" id="interests"></a>
339
+ <div class="card mt-3 p-3">
340
+ <h3 class="card-title font-weight-medium">Interests</h3>
341
+ <div>
342
+ {% assign entries = site.data.resume.interests %}
343
+ {% include cv/interests.liquid %}
344
+ </div>
345
+ </div>
346
+ {% endif %}
347
+
348
+ <!-- Certificates -->
349
+ {% if site.data.resume.certificates.size > 0 %}
350
+ <a class="anchor" id="certificates"></a>
351
+ <div class="card mt-3 p-3">
352
+ <h3 class="card-title font-weight-medium">Certificates</h3>
353
+ <div>
354
+ {% assign entries = site.data.resume.certificates %}
355
+ {% include cv/certificates.liquid %}
356
+ </div>
357
+ </div>
358
+ {% endif %}
359
+
360
+ <!-- Projects -->
361
+ {% if site.data.resume.projects.size > 0 %}
362
+ <a class="anchor" id="projects"></a>
363
+ <div class="card mt-3 p-3">
364
+ <h3 class="card-title font-weight-medium">Projects</h3>
365
+ <div>
366
+ {% assign entries = site.data.resume.projects %}
367
+ {% include cv/projects.liquid %}
368
+ </div>
369
+ </div>
370
+ {% endif %}
371
+
372
+ <!-- References -->
373
+ {% if site.data.resume.references.size > 0 %}
374
+ <a class="anchor" id="references"></a>
375
+ <div class="card mt-3 p-3">
376
+ <h3 class="card-title font-weight-medium">References</h3>
377
+ <div>
378
+ {% assign entries = site.data.resume.references %}
379
+ {% include cv/references.liquid %}
380
+ </div>
381
+ </div>
382
+ {% endif %}
383
+
384
+ {% else %}
385
+ <p>No CV data found. Please configure either RenderCV (cv.yml) or JSONResume (resume.json) data.</p>
386
+ {% endif %}
387
+ </div>
388
+ </article>
389
+ </div>
@@ -0,0 +1,32 @@
1
+ {% comment %}
2
+ Unified skills entry renderer for both formats
3
+ {% endcomment %}
4
+
5
+ <div class="card-text font-weight-light">
6
+ {% for entry in entries %}
7
+ <div class="skill-item">
8
+ {% if entry.icon %}
9
+ <i class="{{ entry.icon }}"></i>
10
+ {% endif %}
11
+ <strong>
12
+ {{- entry.name -}}
13
+ {%- if entry.level %} ({{ entry.level }}){% endif %}:</strong
14
+ >
15
+ {% if entry.keywords %}
16
+ {% for keyword in entry.keywords %}
17
+ {% if forloop.last %}
18
+ {{ keyword }}
19
+ {% else %}
20
+ {{ keyword }},
21
+ {% endif %}
22
+ {% endfor %}
23
+ {% endif %}
24
+ </div>
25
+ {% endfor %}
26
+ </div>
27
+
28
+ <style>
29
+ .skill-item {
30
+ padding: 0.5rem 0;
31
+ }
32
+ </style>
metadata ADDED
@@ -0,0 +1,152 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: al_folio_cv
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - al-folio maintainers
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-02-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jekyll
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.9'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '5.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '3.9'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: liquid
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '4.0'
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: '6.0'
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '4.0'
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '6.0'
53
+ - !ruby/object:Gem::Dependency
54
+ name: bundler
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '2.0'
60
+ - - "<"
61
+ - !ruby/object:Gem::Version
62
+ version: '3.0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '2.0'
70
+ - - "<"
71
+ - !ruby/object:Gem::Version
72
+ version: '3.0'
73
+ - !ruby/object:Gem::Dependency
74
+ name: rake
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '13.0'
80
+ type: :development
81
+ prerelease: false
82
+ version_requirements: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - "~>"
85
+ - !ruby/object:Gem::Version
86
+ version: '13.0'
87
+ - !ruby/object:Gem::Dependency
88
+ name: minitest
89
+ requirement: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - "~>"
92
+ - !ruby/object:Gem::Version
93
+ version: '5.0'
94
+ type: :development
95
+ prerelease: false
96
+ version_requirements: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - "~>"
99
+ - !ruby/object:Gem::Version
100
+ version: '5.0'
101
+ description: Provides CV templates, rendering tags, and packaged CV assets for al-folio
102
+ sites.
103
+ email:
104
+ - maintainers@al-folio.dev
105
+ executables: []
106
+ extensions: []
107
+ extra_rdoc_files: []
108
+ files:
109
+ - CHANGELOG.md
110
+ - LICENSE
111
+ - README.md
112
+ - assets/css/al-folio-cv.css
113
+ - lib/al_folio_cv.rb
114
+ - lib/al_folio_cv/version.rb
115
+ - templates/cv/awards.liquid
116
+ - templates/cv/certificates.liquid
117
+ - templates/cv/education.liquid
118
+ - templates/cv/experience.liquid
119
+ - templates/cv/interests.liquid
120
+ - templates/cv/languages.liquid
121
+ - templates/cv/projects.liquid
122
+ - templates/cv/publications.liquid
123
+ - templates/cv/references.liquid
124
+ - templates/cv/render.liquid
125
+ - templates/cv/skills.liquid
126
+ homepage: https://github.com/al-org-dev/al-folio-cv
127
+ licenses:
128
+ - MIT
129
+ metadata:
130
+ allowed_push_host: https://rubygems.org
131
+ homepage_uri: https://github.com/al-org-dev/al-folio-cv
132
+ source_code_uri: https://github.com/al-org-dev/al-folio-cv
133
+ post_install_message:
134
+ rdoc_options: []
135
+ require_paths:
136
+ - lib
137
+ required_ruby_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '2.7'
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ requirements: []
148
+ rubygems_version: 3.4.10
149
+ signing_key:
150
+ specification_version: 4
151
+ summary: CV rendering plugin for al-folio v1.x
152
+ test_files: []