bilingual-jekyll-resume-theme 1.0.2 → 1.1.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.

Potentially problematic release.


This version of bilingual-jekyll-resume-theme might be problematic. Click here for more details.

Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +74 -0
  3. data/README.md +51 -65
  4. data/SECURITY.md +30 -0
  5. data/_config.sample.yml +26 -8
  6. data/_data/locales/ar.yml +0 -4
  7. data/_data/locales/de.yml +0 -4
  8. data/_data/locales/en.yml +0 -4
  9. data/_data/locales/es.yml +0 -4
  10. data/_data/locales/fr.yml +0 -4
  11. data/_data/locales/ur.yml +0 -4
  12. data/_data/social_networks.yml +83 -0
  13. data/_includes/data-loader.html +1 -1
  14. data/_includes/date-formatter.html +24 -11
  15. data/_includes/grouped-item-list.html +6 -6
  16. data/_includes/print-social-links.html +6 -74
  17. data/_includes/resume-section.html +28 -28
  18. data/_includes/shared-head.html +7 -0
  19. data/_includes/social-links.html +22 -119
  20. data/_includes/vendors/svg-icons/ATTRIBUTION.md +34 -0
  21. data/_includes/vendors/svg-icons/envelope.svg +4 -0
  22. data/_includes/vendors/svg-icons/globe-1.svg +3 -0
  23. data/_includes/vendors/svg-icons/medium.svg +3 -0
  24. data/_layouts/default.html +2 -2
  25. data/_layouts/error.html +5 -1
  26. data/_layouts/profile.html +8 -4
  27. data/_layouts/resume.html +3 -11
  28. data/_plugins/json_resume_generator.rb +78 -0
  29. data/_plugins/resume_pages_generator.rb +63 -0
  30. data/_plugins/resume_validator.rb +2 -2
  31. data/_sass/_all-pages.scss +1 -15
  32. data/_sass/_layout.scss +3 -80
  33. data/_sass/_mixins.scss +22 -10
  34. data/_sass/_profile-page.scss +3 -16
  35. data/_sass/_resume-ltr.scss +7 -50
  36. data/_sass/_resume-rtl.scss +1 -4
  37. data/assets/css/cv-ltr.scss +1 -1
  38. data/assets/css/cv-rtl.scss +1 -1
  39. data/bin/verify +27 -0
  40. data/docs/README.md +89 -0
  41. data/docs/explanation/accessibility-decisions.md +27 -0
  42. data/docs/explanation/architecture.md +44 -0
  43. data/docs/explanation/dark-mode-approach.md +25 -0
  44. data/docs/explanation/data-driven-model.md +25 -0
  45. data/docs/explanation/multilingual-and-rtl-design.md +40 -0
  46. data/docs/how-to/add-a-language.md +57 -0
  47. data/docs/how-to/add-a-section.md +35 -0
  48. data/docs/how-to/add-a-social-platform.md +32 -0
  49. data/docs/how-to/add-a-test.md +34 -0
  50. data/docs/how-to/create-a-custom-layout.md +64 -0
  51. data/docs/how-to/enable-dark-mode.md +43 -0
  52. data/docs/how-to/link-translations-with-hreflang.md +25 -0
  53. data/docs/how-to/migrate-v0.9-to-v1.0.md +46 -0
  54. data/docs/how-to/override-locale-strings.md +51 -0
  55. data/docs/how-to/override-sass-partials.md +26 -0
  56. data/docs/how-to/proof-built-html.md +22 -0
  57. data/docs/how-to/publish-json-resume.md +38 -0
  58. data/docs/how-to/show-language-proficiency-in-header.md +13 -0
  59. data/docs/how-to/switch-resume-versions.md +42 -0
  60. data/docs/how-to/troubleshoot-builds.md +39 -0
  61. data/docs/how-to/validate-in-ci.md +38 -0
  62. data/docs/how-to/verify-accessibility.md +28 -0
  63. data/docs/reference/accessibility-coverage.md +39 -0
  64. data/docs/{CONFIG_GUIDE.md → reference/config.md} +51 -115
  65. data/docs/{DATA_GUIDE.md → reference/data-schemas.md} +62 -86
  66. data/docs/reference/glossary.md +39 -0
  67. data/docs/{INCLUDES_GUIDE.md → reference/includes.md} +32 -134
  68. data/docs/reference/json-resume-fields.md +124 -0
  69. data/docs/reference/layouts.md +144 -0
  70. data/docs/reference/locale-keys.md +76 -0
  71. data/docs/reference/repository-map.md +82 -0
  72. data/docs/{SASS_GUIDE.md → reference/sass-tokens.md} +74 -81
  73. data/docs/reference/testing-suites.md +62 -0
  74. data/docs/reference/validator-cli.md +201 -0
  75. data/docs/tutorials/getting-started.md +173 -0
  76. data/lib/bilingual-jekyll-resume-theme/json_resume_exporter.rb +328 -0
  77. data/lib/bilingual-jekyll-resume-theme/resume_validator.rb +66 -46
  78. data/lib/bilingual-jekyll-resume-theme/schemas/LICENSE.md +21 -0
  79. data/lib/bilingual-jekyll-resume-theme/schemas/json_resume_v1.0.0.json +500 -0
  80. data/lib/bilingual-jekyll-resume-theme.rb +2 -0
  81. metadata +107 -35
  82. data/_includes/main-head.html +0 -7
  83. data/_includes/profile-head.html +0 -7
  84. data/_includes/vendors/lineicons-v4.0/envelope.svg +0 -8
  85. data/_includes/vendors/lineicons-v5.0/globe-1.svg +0 -3
  86. data/_includes/vendors/lineicons-v5.0/medium-alt.svg +0 -3
  87. data/bin/check-data-keys +0 -67
  88. data/docs/ACCESSIBILITY_GUIDE.md +0 -137
  89. data/docs/COMPLETED_AUDIT.md +0 -749
  90. data/docs/LAYOUTS_GUIDE.md +0 -169
  91. data/docs/MULTILINGUAL_GUIDE.md +0 -169
  92. data/docs/PROJECT_OVERVIEW.md +0 -167
  93. data/docs/VALIDATION_GUIDE.md +0 -264
  94. data/lib/bilingual-jekyll-resume-theme/template_key_checker.rb +0 -337
  95. /data/_includes/vendors/{lineicons-v5.0 → svg-icons}/dev.svg +0 -0
  96. /data/_includes/vendors/{lineicons-v5.0 → svg-icons}/dribbble-symbol.svg +0 -0
  97. /data/_includes/vendors/{lineicons-v5.0 → svg-icons}/facebook.svg +0 -0
  98. /data/_includes/vendors/{lineicons-v5.0 → svg-icons}/flickr.svg +0 -0
  99. /data/_includes/vendors/{lineicons-v5.0 → svg-icons}/github.svg +0 -0
  100. /data/_includes/vendors/{lineicons-v5.0 → svg-icons}/instagram.svg +0 -0
  101. /data/_includes/vendors/{lineicons-v5.0 → svg-icons}/linkedin.svg +0 -0
  102. /data/_includes/vendors/{lineicons-v4.0 → svg-icons}/phone.svg +0 -0
  103. /data/_includes/vendors/{lineicons-v5.0 → svg-icons}/pinterest.svg +0 -0
  104. /data/_includes/vendors/{lineicons-v4.0 → svg-icons}/postcard.svg +0 -0
  105. /data/_includes/vendors/{lineicons-v5.0 → svg-icons}/telegram.svg +0 -0
  106. /data/_includes/vendors/{lineicons-v5.0 → svg-icons}/whatsapp.svg +0 -0
  107. /data/_includes/vendors/{lineicons-v5.0 → svg-icons}/x.svg +0 -0
  108. /data/_includes/vendors/{lineicons-v5.0 → svg-icons}/youtube.svg +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b8eb8d16040a681b4a06c1d6eba60b957aee132434d038ce56b53415e74774f9
4
- data.tar.gz: e7cb05ea3e65d241cab36fb5734062a13af1931e8cabe736ee749a108bf8655b
3
+ metadata.gz: 1a68cc1ed280f841cfa0f14e22be9bbd010076876dbf789d46469ee408fd2907
4
+ data.tar.gz: 9ca8bf08818ba3e53a7e05d3f7efb64e8152a0b46dd0c0423d8ae736719bf2b6
5
5
  SHA512:
6
- metadata.gz: c13e0bd5ff9f935997e3977abe7e7e8b257ace6499f0fdc098f8955dc1999ffd36103518e5143c9d3357763f511cb9e5448e8fbb8cc41bc9c7be9ee9493cd432
7
- data.tar.gz: '0069c903af37bd0e31ffa14ac4e5901d4f5c19d4ae3ffca36d41dd647196f931bd5d87593b65a158fd25017f75704cf7750f4803a6887e6a41665e6ed3ddda3a'
6
+ metadata.gz: 62aa3ab455d1c96ea8ecd15dd79e9fd4e3de073c84565d8eda4c642e85154ca4f2810638ad4ed5702d076fcdc4505ad471fc62b80f202dbd636a2340d13391c2
7
+ data.tar.gz: 9d4b20f4f4c5da2ab13331a763763482871dec6f6e95228acf285fe1eca415ac7ed2d84ada251cd65097956a2694148a8ae16555428ab6ca2739912752df367e
data/CHANGELOG.md CHANGED
@@ -4,6 +4,79 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+ ## [1.1.0] - 2026-10-01
8
+
9
+ ### Added
10
+ * Add bin/verify to run the Rule 5 suite with a log ([`333b939`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/333b93947c9f7ac20e21a97ce51ecbbec64bb0b0))
11
+
12
+ * Add security briefs and streamline completed audit log ([`9580a55`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/9580a55411a605d7636227233a97c7d2f38e9822))
13
+
14
+ * Add end-to-end rendered site, packaging, and error page suites ([`8eb6cb3`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/8eb6cb3526dbfde6587f4d6e00019be72bcb679d))
15
+
16
+ * Add Feature 3.2 publications & references blueprint ([`8024a8a`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/8024a8aad060fdab0e2f4f0f4b75d5c75d311064))
17
+
18
+ * Add exporter and generator test suite ([`aa237dd`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/aa237dd65da91894cafe87b7800533c49244ed51))
19
+
20
+ * Add localized JSON Resume exporter and generator ([`c600361`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/c60036172e9f856d9fe538d8a381bca95bbc2968))
21
+
22
+
23
+ ### Changed
24
+ * Filter Liquid frozen-string warning from tests, bump demo ([`8f3f5f9`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/8f3f5f98f62c6590c46a4db398c9a48f50af28c2))
25
+
26
+ * Bump submodule to the docs-path update ([`38ae031`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/38ae031651476f4004ea1475af2000fb8dd855e9))
27
+
28
+ * Expand four short guides with verified steps and checks ([`9b1f337`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/9b1f337807c2098ef3ba5e43e3fd53052a53bcef))
29
+
30
+ * Correct stale layout names in stylesheet comments ([`ce7e1c3`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/ce7e1c3a2b1db4f2b60be1c87fd93c3b7be3fb51))
31
+
32
+ * Restructure documentation into Diataxis (tutorial, how-to, reference, explanation) ([`1348d88`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/1348d88b17e3f6d0397bc881b25003bfa5362d89))
33
+
34
+ * Record ADR 0001 and exclude docs/adr from the gem ([`59695d5`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/59695d5cb679602bcd06dba37851681c8f4e3d63))
35
+
36
+ * Restructure AGENTS.md and update README.md ([`9cb2459`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/9cb245966949cc48db63ac4157bbdbaf9013640b))
37
+
38
+ * Update guides, README, and gemspec metadata for recent architecture ([`0ff18c0`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/0ff18c0dade5fd632d1af8770b6902b355aab56e))
39
+
40
+ * Enforce canonical keys in data files with alias hints ([`9f43702`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/9f43702da1404277d8ef8994a843590696c8d365))
41
+
42
+ * Localized JSON Resume export ([`898dce1`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/898dce11a250029c23285964ca6ecbcf26d50552))
43
+
44
+ * Document the JSON Resume export feature ([`a304320`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/a3043204b51d17547f66e095d7521cae178d8836))
45
+
46
+ * Wire discovery link and sample config ([`4fb5333`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/4fb53333a6e343877ee4e3c1048480d2ff5bdf37))
47
+
48
+ * Validate optional JSON Resume enrichment fields ([`591cb9f`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/591cb9fbab4b5613c6a378aa06a0e3530125493c))
49
+
50
+ * Merge vendor SVG folders and data-drive social links ([`e22afb8`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/e22afb874357c93d66308de38d9ceab1c462ca32))
51
+
52
+ * Sync repository documentation, guides, and roadmap ([`40425a2`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/40425a2ebddfaa0dcba06748329b99f739f456bc))
53
+
54
+ * Upgrade Lineicons to v5.1 and consolidate vendor assets ([`794edcb`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/794edcb35f707ac32cc190ce8deb45e6cc0a6867))
55
+
56
+ * Inline single-caller stylesheet includes ([`4513f29`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/4513f2997f57577358820a1b2b0ba0bf82a0ca90))
57
+
58
+ * Auto-generate CV and profile pages per language ([`abaf487`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/abaf48779013fa6524d60f1ba8f7bfdf06641168))
59
+
60
+ * Deduplicate repeated CSS rules and remove dead code ([`a354b62`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/a354b62253aed4637f0e07df4397adaf27ca2ba9))
61
+
62
+
63
+ ### Fixed
64
+ * Match GitHub host by parsed URL, not substring ([`98c8d83`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/98c8d83f69a408536c41a8de3ea9258bb4a43436))
65
+
66
+ * Check doc links and anchors; assert docs ship and docs/adr does not ([`0e097d9`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/0e097d9a945b6757f48c26abafef225c485ce5ae))
67
+
68
+ * Require date to fix CI error on Ruby 3.3 ([`fc7cb6e`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/fc7cb6e595809de402470f393bae7a934c9ca210))
69
+
70
+ * Improve date formatting, presence checks, and accessible social labels ([`ea7dfeb`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/ea7dfeb40ae4dc8db865d52d39d203ebbbb8a140))
71
+
72
+ * Match script closing tags with trailing garbage ([`abd4d95`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/abd4d9586183b9a3dc0bdaae2be701ecace07a34))
73
+
74
+ * Decode HTML entities before stripping tags ([`cae8378`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/cae8378d111b23f38d62406b4c8c58ac2a547864))
75
+
76
+ * Close CodeQL tag-stripping bypasses in text() ([`365b7f6`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/365b7f655a2adcc825033f5aab92c8c51edbe354))
77
+
78
+ * Stop packaging dev-only tools and internal audit log ([`4c5f7d8`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/4c5f7d8ba256a0bf16f10e6bde9216fb0b93769e))
79
+
7
80
  ## [1.0.2] - 2026-09-25
8
81
 
9
82
  ### Changed
@@ -372,6 +445,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
372
445
 
373
446
  * Initial commit (New Theme Template) ([`00af662`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/00af6628dfec7aefe0ef7d7083bf98c9713a5ffd))
374
447
 
448
+ [1.1.0]: https://github.com/kmutahar/bilingual-jekyll-resume-theme/compare/v1.0.2...v1.1.0
375
449
  [1.0.2]: https://github.com/kmutahar/bilingual-jekyll-resume-theme/compare/v1.0.1...v1.0.2
376
450
  [1.0.1]: https://github.com/kmutahar/bilingual-jekyll-resume-theme/compare/v1.0.0...v1.0.1
377
451
  [1.0.0]: https://github.com/kmutahar/bilingual-jekyll-resume-theme/compare/v0.9.0...v1.0.0
data/README.md CHANGED
@@ -3,6 +3,8 @@
3
3
  [![CI Test Suite](https://github.com/kmutahar/bilingual-jekyll-resume-theme/actions/workflows/ci.yml/badge.svg)](https://github.com/kmutahar/bilingual-jekyll-resume-theme/actions/workflows/ci.yml) [![Latest release](https://img.shields.io/github/v/release/kmutahar/bilingual-jekyll-resume-theme?display_name=tag)](https://github.com/kmutahar/bilingual-jekyll-resume-theme/releases) [![Gem Version](https://badge.fury.io/rb/bilingual-jekyll-resume-theme.svg?icon=si%3Arubygems)](https://badge.fury.io/rb/bilingual-jekyll-resume-theme)
4
4
 
5
5
  A flexible Jekyll theme for clean, data-driven, multilingual resume/CV websites. Ships English, Arabic, Spanish, French, German, and Urdu; any other language is added from your site alone. Created and maintained by Khaldoon Mutahar. See the latest version on the [Releases page](https://github.com/kmutahar/bilingual-jekyll-resume-theme/releases).
6
+
7
+ **Links:** [RubyGems](https://rubygems.org/gems/bilingual-jekyll-resume-theme) · [Live demo](https://www.mutahr.me/bilingual-jekyll-resume-theme) · [Source](https://github.com/kmutahar/bilingual-jekyll-resume-theme)
6
8
  Inspired by and originally forked from [Joel Glovier’s resume template](https://github.com/jglovier/resume-template/). Joel’s version was a basic English-only theme with limited customization (e.g., no section reordering); this project has since evolved into a fully separate theme authored by Khaldoon.
7
9
 
8
10
  ## Features
@@ -11,17 +13,19 @@ Inspired by and originally forked from [Joel Glovier’s resume template](https:
11
13
  - **Dark mode**: System preference detection (`prefers-color-scheme`) with optional interactive toggle, `localStorage` persistence, and zero-FOUC inline script
12
14
  - **Data-driven architecture**: All resume content stored in YAML files, supporting multiple data paths and versioning
13
15
  - **12 resume sections**: Experience, Education, Certifications, Courses, Volunteering, Projects, Skills, Recognition, Associations, Languages, Links, Interests
14
- - **WCAG 2.1 AA Accessible**: Full screen reader and keyboard accessibility with `.sr-only` labels and declarative aria attributes
16
+ - **Accessibility features**: Semantic landmarks, keyboard navigation, localized skip links, and labelled social controls. See the [Accessibility coverage](docs/reference/accessibility-coverage.md) for coverage and known limitations.
15
17
  - **Modern favicon suite**: High-resolution favicons (Apple touch icon, 32x32, 16x16, webmanifest) with subpath-safe URLs and `_config.yml` override support
16
18
  - **Print-friendly**: Optimized for PDF generation and printing with bidirectional text isolation (`dir="ltr"`) for URLs
17
19
  - **SEO ready**: Built-in support for multilingual SEO, standardized canonical tags via `jekyll-seo-tag`, sitemaps, and feeds
20
+ - **JSON Resume Export**: Multilingual builds generate standards-validated JSON Resume files at `/<lang>/resume.json` (on by default; opt out with `json_resume.enabled: false`).
21
+ - **Automatic pages**: Missing CV and profile pages are generated for each configured language; hand-authored pages take precedence.
18
22
  - **Data validation**: `validate-resume` CLI and build-time checks for schemas, dates, URLs, and parity across every configured language
19
23
 
20
24
  ## Quick Start
21
25
 
22
26
  ### Installation
23
27
 
24
- 1. Add to your Jekyll site's `Gemfile`, inside `group :jekyll_plugins`. A plain `gem "bilingual-jekyll-resume-theme"` line never requires the theme's `lib/bilingual-jekyll-resume-theme.rb`, so its bundled plugins (the error page generator and build-time validation) silently never run:
28
+ 1. Add to your Jekyll site's `Gemfile`, inside `group :jekyll_plugins`. The `:jekyll_plugins` group loads the theme’s bundled generators and validator. Alternatively, explicitly list `bilingual-jekyll-resume-theme` under `plugins:` in `_config.yml` (as the sample does); a plain Gemfile entry plus `theme:` alone is insufficient:
25
29
  ```ruby
26
30
  group :jekyll_plugins do
27
31
  gem "bilingual-jekyll-resume-theme"
@@ -38,61 +42,25 @@ theme: bilingual-jekyll-resume-theme
38
42
  bundle install
39
43
  ```
40
44
 
41
- > **Upgrading from v0.9.0?** v1.0.0 removes the `resume-en` / `resume-ar` layouts and every `*_en` / `*_ar` config key with no compatibility aliases. Follow the migration table in the [Multilingual Guide](docs/MULTILINGUAL_GUIDE.md#breaking-changes--migration-v090-to-v100).
42
-
43
- ### Basic Setup
44
-
45
- 1. **Copy sample configuration**: Use `_config.sample.yml` at the repository root as a starting point for your `_config.yml`. Keep a `languages.<lang>` entry for each language you publish and delete the rest.
46
-
47
- 2. **Copy sample data files**: Copy each language folder you need from `demo/_data/` (`en`, `ar`, `es`, `fr`, `de`, `ur`) to your site's `_data/`. Each holds 13 files, including `header.yml` for the intro paragraph.
48
-
49
- 3. **Create resume pages**: One page per language, all using the `resume` layout:
50
- ```yaml
51
- ---
52
- layout: resume
53
- lang: en
54
- permalink: /en/cv/
55
- t_id: resume
56
- ---
57
- ```
45
+ > **Upgrading from v0.9.0?** v1.0.0 removes the `resume-en` / `resume-ar` layouts and every `*_en` / `*_ar` config key with no compatibility aliases. Follow the migration table in the [migration guide](docs/how-to/migrate-v0.9-to-v1.0.md).
58
46
 
59
- 4. **Run the development server**:
60
- ```bash
61
- bundle exec jekyll serve
62
- ```
47
+ ### Next steps
63
48
 
64
- Visit `http://localhost:4000` to see your resume!
49
+ Follow [Getting Started](docs/tutorials/getting-started.md) for a complete walkthrough from an empty folder to a running two-language resume. The theme generates the CV and profile page for every language you configure (see [the languages table](docs/reference/config.md#3-languages)), and the sample data for six languages lives in `demo/_data/`.
65
50
 
66
51
  ## Documentation
67
52
 
68
- This theme is fully documented. Choose the guide that fits your needs:
69
-
70
- ### 📘 [Configuration Guide](docs/CONFIG_GUIDE.md)
71
- Complete guide to `_config.yml` settings. Learn how to configure sections, contact info, social links, analytics, and more. **Start here for beginners.**
53
+ The documentation is organized by what you need. Start at the [documentation index](docs/README.md).
72
54
 
73
- ### 🌐 [Multilingual Guide](docs/MULTILINGUAL_GUIDE.md)
74
- Locale files, adding a language, overriding theme strings and fonts, RTL typography, and the **v0.9.0 to v1.0.0 migration table**.
55
+ | I want to... | Go to |
56
+ |---|---|
57
+ | Build my first resume site | [Getting Started](docs/tutorials/getting-started.md) (tutorial) |
58
+ | Do one task: add a language, override strings, publish JSON, validate in CI | [How-to guides](docs/README.md#how-to-guides) |
59
+ | Look up a setting, schema, or flag | [Reference](docs/README.md#reference) |
60
+ | Understand why the theme works this way | [Explanation](docs/README.md#explanation) |
61
+ | Contribute or follow the project rules | [AGENTS.md](AGENTS.md) · [Changelog](CHANGELOG.md) |
75
62
 
76
- ### ✅ [Validation Guide](docs/VALIDATION_GUIDE.md)
77
- The `validate-resume` CLI, build-time validation, rules per section, and CI setup.
78
-
79
- ### 📊 [Data Structure Guide](docs/DATA_GUIDE.md)
80
- Detailed documentation of all 12 data file types (experience, education, skills, etc.) with examples. Learn how to structure your YAML files and what fields are required vs optional.
81
-
82
- ### 🎨 [Layouts Guide](docs/LAYOUTS_GUIDE.md)
83
- Deep dive into how layouts work, how data flows through them, and how to create custom layouts. Useful for advanced customization.
84
-
85
- ### 🧩 [Includes Guide](docs/INCLUDES_GUIDE.md)
86
- Understanding the theme's include system, how sections render, and how to add new sections or customize existing ones.
87
-
88
- ### 🎨 [SASS/SCSS Guide](docs/SASS_GUIDE.md)
89
- Complete guide to the theme's styling system, how to customize colors/fonts, and how to override styles without forking the theme.
90
-
91
- ### 🗺️ [Project Overview](docs/PROJECT_OVERVIEW.md)
92
- High-level architecture summary, repository conventions, layout hierarchy, and design philosophy.
93
-
94
- ### 📜 [Completed Historical Audit](docs/COMPLETED_AUDIT.md)
95
- Permanent engineering record of historical bug fixes, security hardening, and architectural upgrades.
63
+ Most-used reference pages: [Configuration reference](docs/reference/config.md) (**start here** for `_config.yml`), [Data schemas](docs/reference/data-schemas.md), [Locale keys](docs/reference/locale-keys.md), [Validator and build checks](docs/reference/validator-cli.md), [JSON Resume export reference](docs/reference/json-resume-fields.md), and [Accessibility coverage](docs/reference/accessibility-coverage.md).
96
64
 
97
65
  ## Project Structure
98
66
 
@@ -106,9 +74,9 @@ bilingual-jekyll-resume-theme/
106
74
  ├── lib/ # Gem entrypoint and validator engine
107
75
  ├── bin/ # validate-resume CLI
108
76
  ├── assets/ # CSS entrypoints (cv-ltr, cv-rtl), images, favicons
109
- └── docs/ # Documentation, demo pages, and sample files
110
- ├── _data/ # Sample config and six-language demo data (copy to your site's _data/)
111
- └── *.md # Documentation guides
77
+ ├── _config.sample.yml # Annotated configuration for consuming sites
78
+ ├── demo/ # Separate demo-site submodule, including six-language data
79
+ └── docs/ # Documentation: tutorial, how-to guides, reference, explanation
112
80
  ```
113
81
 
114
82
  ## Key Concepts
@@ -126,7 +94,7 @@ languages:
126
94
 
127
95
  Use one folder per language even for a single-language site; adding a language later is then one more folder. Dot paths (`"2025-06.v1"`) select nested, versioned datasets, and `""` reads `_data/` itself.
128
96
 
129
- See the [Configuration Guide](docs/CONFIG_GUIDE.md#3-languages) for every per-language key.
97
+ See the [Configuration reference](docs/reference/config.md#3-languages) for every per-language key.
130
98
 
131
99
  ### Sample Files
132
100
 
@@ -134,22 +102,28 @@ See the [Configuration Guide](docs/CONFIG_GUIDE.md#3-languages) for every per-la
134
102
 
135
103
  ### Locales
136
104
 
137
- Month names, "Present" labels, section titles, fonts, and text direction come from `_data/locales/<lang>.yml`, shipped inside the gem for all six languages. Override single strings or add a new language from your site's own `_data/locales/`; see the [Multilingual Guide](docs/MULTILINGUAL_GUIDE.md).
105
+ Month names, "Present" labels, section titles, fonts, and text direction come from `_data/locales/<lang>.yml`, shipped inside the gem for all six languages. Override single strings or add a new language from your site's own `_data/locales/`; see [Override locale strings](docs/how-to/override-locale-strings.md) and [Add a language](docs/how-to/add-a-language.md).
138
106
 
139
107
  ## Development
140
108
 
141
109
  To develop this theme locally:
142
110
 
143
111
  ```bash
144
- # Install dependencies
112
+ # Initialize the demo submodule, then install dependencies
113
+ git submodule update --init --recursive
145
114
  bundle install
146
115
 
147
116
  # Serve the six-language demo from the demo submodule
148
117
  bundle exec jekyll serve --source demo --destination _site
118
+ # (Or with live reload and incremental builds)
119
+ bundle exec jekyll serve --source demo --destination _site --livereload --incremental
149
120
 
150
121
  # Build static output
151
122
  bundle exec jekyll build --source demo --destination _site
152
123
 
124
+ # Clean cached Jekyll build artifacts
125
+ bundle exec jekyll clean
126
+
153
127
  # Validate resume data schemas and parity (CLI or Rake)
154
128
  ./bin/validate-resume demo/_data
155
129
  bundle exec rake validate
@@ -158,20 +132,35 @@ bundle exec rake validate
158
132
  ./bin/check-data-keys demo/_data
159
133
  bundle exec rake check_data_keys
160
134
 
161
- # Validators, RuboCop, and tests together
135
+ # Data validator, template key checker, RuboCop, and every test suite
162
136
  bundle exec rake
163
137
 
138
+ # Verify built HTML (separate from the default Rake task)
139
+ bundle exec rake "proof[_site,demo/_config.yml]"
140
+
164
141
  # Build the gem
165
142
  gem build bilingual-jekyll-resume-theme.gemspec
143
+
144
+ # List packaged files (must include locales and bin, exclude tests)
145
+ gem spec bilingual-jekyll-resume-theme-*.gem files
146
+ rm -f bilingual-jekyll-resume-theme-*.gem
147
+
148
+ # Dependency Audit
149
+ bundle outdated
150
+ bundle update
151
+
152
+ # Automated Version Release (updates gemspec, changelog, commits, and tags)
153
+ ./bin/release <version>
154
+ ./bin/release --bump
166
155
  ```
167
156
 
168
- For more details on resume schema checks, see [VALIDATION_GUIDE.md](docs/VALIDATION_GUIDE.md). Contributor and agent rules are in [AGENTS.md](AGENTS.md).
157
+ For more details on resume schema checks, see [Validator and build checks](docs/reference/validator-cli.md). Contributor and agent rules are in [AGENTS.md](AGENTS.md).
169
158
 
170
159
  ## Requirements
171
160
 
172
- - Ruby 3.3+ (standard support on Ruby 3.3, 3.4, 4.0+; Ruby <= 3.2 is EOL)
173
- - Jekyll 4.4+ (specified in `bilingual-jekyll-resume-theme.gemspec`)
174
- - Required plugins (automatically included):
161
+ - Ruby 3.3+; this repository’s CI matrix tests 3.3, 3.4, and 4.0.
162
+ - Jekyll `~> 4.4` (4.4 or later, below 5.0), as specified in the gemspec.
163
+ - Runtime plugin dependencies (Jekyll loads them automatically when `theme:` is set; the sample config also lists them under `plugins:` to make them explicit):
175
164
  - `jekyll-feed`
176
165
  - `jekyll-seo-tag`
177
166
  - `jekyll-sitemap`
@@ -187,12 +176,9 @@ The theme is available as open source under the terms of the [MIT License](LICEN
187
176
 
188
177
  ## Support
189
178
 
190
- - 📖 Check the [documentation guides](docs/) for detailed information
179
+ - 📖 Check the [Documentation](#documentation) for detailed information
191
180
  - 🐛 Report issues on [GitHub Issues](https://github.com/kmutahar/bilingual-jekyll-resume-theme/issues)
192
- - 💡 See [PROJECT_OVERVIEW.md](docs/PROJECT_OVERVIEW.md) for a high-level architecture overview
193
- - 📜 See [COMPLETED_AUDIT.md](docs/COMPLETED_AUDIT.md) for historical remediations and architectural decisions
194
181
 
195
182
  ---
196
183
 
197
184
  **Created by Khaldoon Mutahar** | MIT License
198
-
data/SECURITY.md ADDED
@@ -0,0 +1,30 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ We take the security of our resume theme and the dependencies it delivers to our users seriously. Because this theme is distributed as a RubyGem package used to build static sites, we actively patch vulnerabilities discovered in our runtime plugin requirements.
6
+
7
+ The following versions of `bilingual-jekyll-resume-theme` currently receive security updates:
8
+
9
+ | Version | Supported | Notes |
10
+ | ------- | ------------------ | ----------------------------------- |
11
+ | 1.0.x | :white_check_mark: | Current stable release branch. |
12
+ | 0.9.x | :white_check_mark: | Maintenance & security patches. |
13
+ | < 0.9 | :x: | Legacy branches; please upgrade. |
14
+
15
+ ## Our Dependency Monitoring
16
+
17
+ The checked-in [Dependabot configuration](.github/dependabot.yml) schedules daily Bundler dependency updates and weekly GitHub Actions updates. The repository also contains [Mend configuration](.whitesource) with a `LOW` minimum issue severity. These files describe configuration, not proof that a hosted service is enabled or that all alerts are resolved. No CodeQL workflow is checked in.
18
+
19
+ ## Reporting a Vulnerability
20
+
21
+ If you discover a security vulnerability within this theme or find an unpatched runtime dependency risk, please do not disclose it publicly via GitHub Issues. Instead, report it responsibly through private channels:
22
+
23
+ 1. **Email the Maintainer:** Send a detailed report to **contact@mutahar.me**.
24
+ 2. **Include Details:** Please provide a description of the vulnerability, the version affected, and a proof-of-concept or steps to reproduce the issue if possible.
25
+
26
+ ### What to Expect
27
+
28
+ * **Acknowledgment:** You will receive a response acknowledging your report within 48 hours.
29
+ * **Triage & Status Updates:** We will update you at least once a week while working on a resolution.
30
+ * **Resolution:** If the vulnerability is accepted, a patched release (e.g., a new patch gem version) will be published, and credit will be given to the reporter if desired.
data/_config.sample.yml CHANGED
@@ -17,9 +17,8 @@ url: "https://your-domain.com" # Full site URL (protocol + host), e.g. https://e
17
17
  baseurl: "" # Subpath if hosted in a subdirectory (e.g., /resume); keep "" if at root
18
18
  timezone: UTC # Timezone for date rendering (e.g., UTC, America/New_York, Asia/Riyadh)
19
19
 
20
- # Default site language and text direction (used in default and error layouts)
21
- # lang: "en" # Default: "en"
22
- # dir: "ltr" # Default: "ltr" (use "rtl" for right-to-left base layout)
20
+ # Language comes from page.lang or default_lang (Section 6.5).
21
+ # Direction comes from _data/locales/<lang>.yml; no site-wide lang/dir keys are used.
23
22
 
24
23
  # ==============================================================================
25
24
  # 2. FAVICONS & WEB APP MANIFEST (Optional - defaults to theme bundled assets)
@@ -177,10 +176,16 @@ languages:
177
176
 
178
177
  default_lang: en # Drives hreflang x-default and fallback lookups
179
178
 
179
+ # A languages.<lang> entry with no hand-authored CV/profile page gets one auto-generated
180
+ # (CV at languages.<lang>.url, profile at "/" for default_lang or "/<lang>/" otherwise).
181
+ # Set false to require every language to have its own hand-authored page. Override per
182
+ # language with languages.<lang>.auto_generate_pages: true/false.
183
+ resume_auto_generate_pages: true
184
+
180
185
  # ==============================================================================
181
186
  # 7. RESUME DISPLAY & BEHAVIOR CONTROLS
182
187
  # ==============================================================================
183
- # Interactive language switcher (floating button, lists every entry in `languages`)
188
+ # Language dropdown (fixed top-left, lists every other configured language)
184
189
  resume_language_switcher: true # Toggle floating language switcher (default: true)
185
190
 
186
191
  # Header display toggles
@@ -242,8 +247,9 @@ resume_section_order:
242
247
  # 9. STYLING, FONTS & DARK MODE
243
248
  # ==============================================================================
244
249
  # Dark Mode Configuration:
245
- # - "auto" (default): CSS-only system detection (prefers-color-scheme); zero JS, no toggle button
250
+ # - "auto" (default): system-preference CSS, no toggle button; shared preference script still runs
246
251
  # - "enabled" or true: Renders interactive floating toggle button with localStorage persistence
252
+ # - false or "disabled": hides the toggle; does not force the page into light mode
247
253
  dark_mode: auto
248
254
 
249
255
  # Visual theme variant (default: "default")
@@ -251,9 +257,9 @@ resume_theme: default
251
257
 
252
258
  # To use a self-hosted or alternate CDN font for a locale, override that locale's
253
259
  # font_url in your site's own _data/locales/<lang>.yml (see "Overriding Theme
254
- # Locales" in docs/MULTILINGUAL_GUIDE.md) instead of a site-wide config key.
260
+ # Locales" in docs/explanation/multilingual-and-rtl-design.md) instead of a site-wide config key.
255
261
 
256
- # Disable remote Google Fonts fetching (useful for offline/intranet builds or strict GDPR compliance)
262
+ # Disable font stylesheet loading in the resume layout (including a custom locale font_url)
257
263
  # disable_google_fonts: true
258
264
 
259
265
  # Optional authors metadata
@@ -277,7 +283,7 @@ plugins:
277
283
  # Belt-and-suspenders: Jekyll auto-requires gems listed here (site.gems) regardless
278
284
  # of Bundler group, guarding against a Gemfile that forgets to put the theme gem in
279
285
  # the `:jekyll_plugins` group — without that, the build-time resume validator and
280
- # HTTP error page generator silently never run.
286
+ # page generators silently never run.
281
287
  - bilingual-jekyll-resume-theme
282
288
  - jekyll-feed
283
289
  - jekyll-seo-tag
@@ -305,3 +311,15 @@ exclude:
305
311
 
306
312
  # Front matter defaults (optional)
307
313
  defaults: []
314
+
315
+ # JSON Resume exports: /<lang>/resume.json and a default-language /resume.json.
316
+ # Details and field mappings: docs/reference/json-resume-fields.md in the theme repository.
317
+ json_resume:
318
+ enabled: true
319
+ root_export: true
320
+ languages: [] # Empty/missing: all configured languages
321
+ privacy:
322
+ export_contact_info: true # False removes email, phone, location, WhatsApp from JSON
323
+ # Optional; social_links values remain URL strings.
324
+ # social_usernames:
325
+ # github: octocat
data/_data/locales/ar.yml CHANGED
@@ -64,10 +64,6 @@ error_pages:
64
64
  "503":
65
65
  title: "الخدمة غير متوفرة مؤقتاً"
66
66
  message: "الخادم غير قادر على معالجة الطلب حالياً بسبب الصيانة أو زيادة الحمل."
67
- return_link: "العودة إلى السيرة الذاتية"
68
- search_label: "البحث في الموقع"
69
- search_placeholder: "البحث في الموقع..."
70
- search_button: "بحث"
71
67
  present_values:
72
68
  - "present"
73
69
  - "حتى الآن"
data/_data/locales/de.yml CHANGED
@@ -64,10 +64,6 @@ error_pages:
64
64
  "503":
65
65
  title: "Dienst Nicht Verfügbar"
66
66
  message: "Der Server kann die Anfrage derzeit aufgrund von Wartungsarbeiten oder Überlastung nicht bearbeiten."
67
- return_link: "Zurück zum Lebenslauf"
68
- search_label: "Website durchsuchen"
69
- search_placeholder: "Website durchsuchen..."
70
- search_button: "Suchen"
71
67
  present_values:
72
68
  - "present"
73
69
  - "heute"
data/_data/locales/en.yml CHANGED
@@ -64,10 +64,6 @@ error_pages:
64
64
  "503":
65
65
  title: "Service Unavailable"
66
66
  message: "The server is currently unable to handle the request due to maintenance or capacity overload."
67
- return_link: "Return to resume"
68
- search_label: "Search website"
69
- search_placeholder: "Search website..."
70
- search_button: "Search"
71
67
  present_values:
72
68
  - "present"
73
69
  - "current"
data/_data/locales/es.yml CHANGED
@@ -64,10 +64,6 @@ error_pages:
64
64
  "503":
65
65
  title: "Servicio No Disponible"
66
66
  message: "El servidor no puede procesar la solicitud actualmente debido a mantenimiento o sobrecarga."
67
- return_link: "Volver al currículum"
68
- search_label: "Buscar en el sitio"
69
- search_placeholder: "Buscar en el sitio..."
70
- search_button: "Buscar"
71
67
  present_values:
72
68
  - "present"
73
69
  - "actualidad"
data/_data/locales/fr.yml CHANGED
@@ -64,10 +64,6 @@ error_pages:
64
64
  "503":
65
65
  title: "Service Indisponible"
66
66
  message: "Le serveur est actuellement incapable de traiter la demande en raison d'une maintenance ou d'une surcharge."
67
- return_link: "Retour au CV"
68
- search_label: "Rechercher sur le site"
69
- search_placeholder: "Rechercher sur le site..."
70
- search_button: "Rechercher"
71
67
  present_values:
72
68
  - "present"
73
69
  - "actuel"
data/_data/locales/ur.yml CHANGED
@@ -64,10 +64,6 @@ error_pages:
64
64
  "503":
65
65
  title: "سروس عارضی طور پر دستیاب نہیں"
66
66
  message: "دیکھ بھال یا زیادہ لوڈ کی وجہ سے سرور فی الحال درخواست پر عمل کرنے سے قاصر ہے۔"
67
- return_link: "سی وی پر واپس جائیں"
68
- search_label: "ویب سائٹ تلاش کریں"
69
- search_placeholder: "ویب سائٹ تلاش کریں..."
70
- search_button: "تلاش"
71
67
  present_values:
72
68
  - "present"
73
69
  - "حال"
@@ -0,0 +1,83 @@
1
+ # Shared network list for _includes/social-links.html and
2
+ # _includes/print-social-links.html: one entry per site.social_links.<key>
3
+ # platform. Order here is the icon/print display order. To add a platform,
4
+ # add its SVG to _includes/vendors/svg-icons/ and an entry here.
5
+ #
6
+ # icon: filename (without .svg) under _includes/vendors/svg-icons/
7
+ # itemprop: schema.org microdata value social-links.html sets on the <a>
8
+ # label: English fallback for the icon's aria-label/title; each locale's
9
+ # ui.social_labels.<key> wins when present (print labels use it too)
10
+ - key: devto
11
+ icon: dev
12
+ itemprop: url
13
+ label: Dev.to
14
+
15
+ - key: dribbble
16
+ icon: dribbble-symbol
17
+ itemprop: sameAs
18
+ label: Dribbble
19
+
20
+ - key: email
21
+ icon: envelope
22
+ itemprop: email
23
+ label: Email
24
+
25
+ - key: facebook
26
+ icon: facebook
27
+ itemprop: sameAs
28
+ label: Facebook
29
+
30
+ - key: flickr
31
+ icon: flickr
32
+ itemprop: url
33
+ label: Flickr
34
+
35
+ - key: github
36
+ icon: github
37
+ itemprop: sameAs
38
+ label: GitHub
39
+
40
+ - key: instagram
41
+ icon: instagram
42
+ itemprop: sameAs
43
+ label: Instagram
44
+
45
+ - key: linkedin
46
+ icon: linkedin
47
+ itemprop: sameAs
48
+ label: LinkedIn
49
+
50
+ - key: medium
51
+ icon: medium
52
+ itemprop: url
53
+ label: Medium
54
+
55
+ - key: pinterest
56
+ icon: pinterest
57
+ itemprop: url
58
+ label: Pinterest
59
+
60
+ - key: telegram
61
+ icon: telegram
62
+ itemprop: url
63
+ label: Telegram
64
+
65
+ - key: twitter
66
+ icon: x
67
+ itemprop: sameAs
68
+ label: X (Twitter)
69
+
70
+ - key: website
71
+ icon: globe-1
72
+ itemprop: url
73
+ label: Website
74
+
75
+ - key: whatsapp
76
+ icon: whatsapp
77
+ itemprop: url
78
+ label: WhatsApp
79
+
80
+ - key: youtube
81
+ icon: youtube
82
+ itemprop: url
83
+ label: YouTube
@@ -34,7 +34,7 @@ OUTPUT:
34
34
  {%- assign data_path = include.path | default: default_lang_cfg.data_path -%}
35
35
  {%- assign resume_data = site.data -%}
36
36
 
37
- {%- if data_path != blank -%}
37
+ {%- if data_path.size > 0 -%}
38
38
  {%- assign path_parts = data_path | split: '.' -%}
39
39
  {%- for part in path_parts -%}
40
40
  {%- assign resume_data = resume_data[part] -%}
@@ -33,18 +33,31 @@
33
33
  {%- if is_present -%}
34
34
  {{ locale.ui.present }}
35
35
  {%- else -%}
36
- {%- assign month_index = include.date | date: "%m" | plus: 0 | minus: 1 -%}
37
- {%- assign month_name = locale.months[month_index] -%}
38
- {%- assign day = include.date | date: "%-d" -%}
39
- {%- assign year = include.date | date: "%Y" -%}
40
- {%- if month_name -%}
41
- {%- if style == "MDY" -%}
42
- {{ month_name }} {{ day }}, {{ year }}
43
- {%- else -%}
44
- {{ month_name }} {{ year }}
45
- {%- endif -%}
46
- {%- else -%}
36
+ {%- comment -%}
37
+ Split the ISO string ourselves: Liquid's `date` filter reads a bare year (2018) as a
38
+ Unix timestamp and cannot parse YYYY-MM. YAML Date objects stringify to YYYY-MM-DD.
39
+ Anything that is not YYYY, YYYY-MM or YYYY-MM-DD is printed verbatim.
40
+ {%- endcomment -%}
41
+ {%- assign date_parts = include.date | append: "" | slice: 0, 10 | split: "-" -%}
42
+ {%- assign year = date_parts[0] -%}
43
+ {%- assign year_check = year | plus: 0 | append: "" -%}
44
+ {%- assign month_num = date_parts[1] | plus: 0 -%}
45
+ {%- assign day = date_parts[2] | plus: 0 -%}
46
+ {%- assign month_name = nil -%}
47
+ {%- if date_parts[1].size == 2 and month_num >= 1 and month_num <= 12 -%}
48
+ {%- assign month_index = month_num | minus: 1 -%}
49
+ {%- assign month_name = locale.months[month_index] -%}
50
+ {%- endif -%}
51
+ {%- if year.size != 4 or year_check != year or date_parts.size > 3 -%}
47
52
  {{ include.date }}
53
+ {%- elsif date_parts.size == 1 -%}
54
+ {{ year }}
55
+ {%- elsif month_name == nil -%}
56
+ {{ include.date }}
57
+ {%- elsif style == "MDY" and date_parts.size == 3 and day > 0 -%}
58
+ {{ month_name }} {{ day }}, {{ year }}
59
+ {%- else -%}
60
+ {{ month_name }} {{ year }}
48
61
  {%- endif -%}
49
62
  {%- endif -%}
50
63
  {%- endif -%}