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

Potentially problematic release.


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

Files changed (149) hide show
  1. checksums.yaml +4 -4
  2. data/403.html +1 -1
  3. data/404.html +1 -1
  4. data/500.html +1 -1
  5. data/CHANGELOG.md +86 -0
  6. data/README.md +59 -38
  7. data/_data/locales/ar.yml +87 -0
  8. data/_data/locales/de.yml +88 -0
  9. data/_data/locales/en.yml +86 -0
  10. data/_data/locales/es.yml +88 -0
  11. data/_data/locales/fr.yml +88 -0
  12. data/_data/locales/ur.yml +88 -0
  13. data/_includes/analytics-head.html +11 -22
  14. data/_includes/avatar.html +9 -19
  15. data/_includes/dark-mode-toggle.html +10 -36
  16. data/_includes/data-loader.html +3 -2
  17. data/_includes/date-formatter.html +50 -0
  18. data/_includes/grouped-item-list.html +53 -0
  19. data/_includes/hreflang.html +3 -2
  20. data/_includes/language-switcher.html +47 -50
  21. data/_includes/print-social-links.html +22 -21
  22. data/_includes/{resume-section-en.html → resume-section.html} +73 -144
  23. data/_includes/shared-head.html +1 -1
  24. data/_includes/social-links.html +9 -1
  25. data/_includes/vendors/lineicons-v4.0/envelope.svg +1 -1
  26. data/_layouts/default.html +6 -5
  27. data/_layouts/error.html +88 -67
  28. data/_layouts/profile.html +64 -5
  29. data/_layouts/{resume-en.html → resume.html} +79 -48
  30. data/_plugins/error_pages_generator.rb +3 -4
  31. data/_plugins/resume_validator.rb +40 -0
  32. data/_sass/_all-pages.scss +5 -77
  33. data/_sass/_base.scss +1 -1
  34. data/_sass/{_resume.scss → _resume-ltr.scss} +23 -11
  35. data/_sass/_resume-rtl.scss +15 -39
  36. data/assets/css/{cv.scss → cv-ltr.scss} +5 -4
  37. data/assets/css/cv-rtl.scss +36 -0
  38. data/assets/css/profile.scss +1 -0
  39. data/bin/check-data-keys +66 -0
  40. data/bin/validate-resume +88 -0
  41. data/docs/ACCESSIBILITY_GUIDE.md +3 -7
  42. data/docs/COMPLETED_AUDIT.md +61 -19
  43. data/docs/CONFIG_GUIDE.md +138 -330
  44. data/docs/DATA_GUIDE.md +40 -99
  45. data/docs/INCLUDES_GUIDE.md +149 -231
  46. data/docs/LAYOUTS_GUIDE.md +95 -196
  47. data/docs/MULTILINGUAL_GUIDE.md +169 -0
  48. data/docs/PROJECT_OVERVIEW.md +116 -103
  49. data/docs/SASS_GUIDE.md +21 -17
  50. data/docs/VALIDATION_GUIDE.md +264 -0
  51. data/docs/_data/_config.demo.yml +62 -0
  52. data/docs/_data/_config.sample.yml +107 -44
  53. data/docs/_data/ar/associations.yml +13 -13
  54. data/docs/_data/ar/certifications.yml +27 -34
  55. data/docs/_data/ar/courses.yml +24 -25
  56. data/docs/_data/ar/education.yml +23 -26
  57. data/docs/_data/ar/experience.yml +33 -44
  58. data/docs/_data/ar/header.yml +2 -2
  59. data/docs/_data/ar/interests.yml +4 -4
  60. data/docs/_data/ar/languages.yml +9 -9
  61. data/docs/_data/ar/links.yml +8 -8
  62. data/docs/_data/ar/projects.yml +24 -17
  63. data/docs/_data/ar/recognitions.yml +23 -15
  64. data/docs/_data/ar/skills.yml +13 -8
  65. data/docs/_data/ar/volunteering.yml +23 -34
  66. data/docs/_data/de/associations.yml +36 -0
  67. data/docs/_data/de/certifications.yml +51 -0
  68. data/docs/_data/de/courses.yml +46 -0
  69. data/docs/_data/de/education.yml +48 -0
  70. data/docs/_data/de/experience.yml +55 -0
  71. data/docs/_data/de/header.yml +7 -0
  72. data/docs/_data/de/interests.yml +15 -0
  73. data/docs/_data/de/languages.yml +29 -0
  74. data/docs/_data/de/links.yml +24 -0
  75. data/docs/_data/de/projects.yml +44 -0
  76. data/docs/_data/de/recognitions.yml +42 -0
  77. data/docs/_data/de/skills.yml +33 -0
  78. data/docs/_data/de/volunteering.yml +44 -0
  79. data/docs/_data/en/associations.yml +15 -15
  80. data/docs/_data/en/certifications.yml +27 -34
  81. data/docs/_data/en/courses.yml +24 -25
  82. data/docs/_data/en/education.yml +23 -26
  83. data/docs/_data/en/experience.yml +32 -43
  84. data/docs/_data/en/header.yml +2 -2
  85. data/docs/_data/en/interests.yml +4 -4
  86. data/docs/_data/en/languages.yml +9 -9
  87. data/docs/_data/en/links.yml +8 -8
  88. data/docs/_data/en/projects.yml +24 -17
  89. data/docs/_data/en/recognitions.yml +23 -15
  90. data/docs/_data/en/skills.yml +13 -8
  91. data/docs/_data/en/volunteering.yml +22 -33
  92. data/docs/_data/es/associations.yml +36 -0
  93. data/docs/_data/es/certifications.yml +51 -0
  94. data/docs/_data/es/courses.yml +46 -0
  95. data/docs/_data/es/education.yml +48 -0
  96. data/docs/_data/es/experience.yml +55 -0
  97. data/docs/_data/es/header.yml +7 -0
  98. data/docs/_data/es/interests.yml +15 -0
  99. data/docs/_data/es/languages.yml +29 -0
  100. data/docs/_data/es/links.yml +24 -0
  101. data/docs/_data/es/projects.yml +44 -0
  102. data/docs/_data/es/recognitions.yml +42 -0
  103. data/docs/_data/es/skills.yml +33 -0
  104. data/docs/_data/es/volunteering.yml +44 -0
  105. data/docs/_data/fr/associations.yml +36 -0
  106. data/docs/_data/fr/certifications.yml +51 -0
  107. data/docs/_data/fr/courses.yml +46 -0
  108. data/docs/_data/fr/education.yml +48 -0
  109. data/docs/_data/fr/experience.yml +55 -0
  110. data/docs/_data/fr/header.yml +7 -0
  111. data/docs/_data/fr/interests.yml +15 -0
  112. data/docs/_data/fr/languages.yml +29 -0
  113. data/docs/_data/fr/links.yml +24 -0
  114. data/docs/_data/fr/projects.yml +44 -0
  115. data/docs/_data/fr/recognitions.yml +42 -0
  116. data/docs/_data/fr/skills.yml +33 -0
  117. data/docs/_data/fr/volunteering.yml +44 -0
  118. data/docs/_data/ur/associations.yml +36 -0
  119. data/docs/_data/ur/certifications.yml +51 -0
  120. data/docs/_data/ur/courses.yml +46 -0
  121. data/docs/_data/ur/education.yml +48 -0
  122. data/docs/_data/ur/experience.yml +55 -0
  123. data/docs/_data/ur/header.yml +7 -0
  124. data/docs/_data/ur/interests.yml +15 -0
  125. data/docs/_data/ur/languages.yml +29 -0
  126. data/docs/_data/ur/links.yml +24 -0
  127. data/docs/_data/ur/projects.yml +44 -0
  128. data/docs/_data/ur/recognitions.yml +42 -0
  129. data/docs/_data/ur/skills.yml +33 -0
  130. data/docs/_data/ur/volunteering.yml +44 -0
  131. data/docs/assets/images/sherlock-holmes.jpg +0 -0
  132. data/docs/demo/ar.md +5 -0
  133. data/docs/demo/de.md +5 -0
  134. data/docs/demo/en.md +5 -0
  135. data/docs/demo/es.md +5 -0
  136. data/docs/demo/fr.md +5 -0
  137. data/docs/demo/ur.md +5 -0
  138. data/lib/bilingual-jekyll-resume-theme/resume_validator.rb +752 -0
  139. data/lib/bilingual-jekyll-resume-theme/template_key_checker.rb +337 -0
  140. data/lib/bilingual-jekyll-resume-theme.rb +2 -1
  141. metadata +157 -20
  142. data/_data/ar/months.yml +0 -12
  143. data/_data/error_pages.yml +0 -33
  144. data/_includes/ar-date.html +0 -52
  145. data/_includes/resume-head-ar.html +0 -24
  146. data/_includes/resume-head-en.html +0 -15
  147. data/_includes/resume-section-ar.html +0 -554
  148. data/_layouts/resume-ar.html +0 -215
  149. data/assets/css/cv-ar.scss +0 -33
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0456f04d40f87607d0b9eea63b2fabbf1256e5ca0a7e6903ac1cd4fbb8465575
4
- data.tar.gz: 840d1d5addfdf72448dfd04765875ceed5c319ba8d3548b26ec89f1d82c34ec2
3
+ metadata.gz: 00d980490bbad955afa894d864e4379a65a6f39f371d97a6db9d1808785ccaed
4
+ data.tar.gz: b5c302a20cb5d88382151575fdb376b870969a4067d401da907cb2608f76ed3b
5
5
  SHA512:
6
- metadata.gz: 570f411c947a9cb26c2806580405b3503fcd5d4d513dc083dce5dec2c1930cd37c241a289ca4526bb5d2282e0efb79659302b9a4b9018b88413e0057a8432aa7
7
- data.tar.gz: e1d7b2184bdf67432c8edf765a18404c1590eae81b8e827da894aeee2e085843b3d37d3fffadf259e461d3d3f2e5bd8c5066fcb88e15cdca700b36a3187d72ed
6
+ metadata.gz: 35046ae1202cd6e65a03d90313cb6dbf2ebecff360f4d1f4183a413b02b7b0da17df223b8066133ea90f3e44d5596dfb9ea2f6834ab981afa73d2165c53f480d
7
+ data.tar.gz: ab8eb568a6ca00d51c040c2282efdfddb2dc3a29634f706e6b7d9cf96e08f49b069ceddb9c83d11f2582a5fcea9ca2d978674521aa866c9ed14281630c196135
data/403.html CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  layout: error
3
3
  code: "403"
4
- title: "403 - Access Forbidden / الوصول محظور"
4
+ title: "403 - Access Forbidden"
5
5
  permalink: /403.html
6
6
  ---
data/404.html CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  layout: error
3
3
  code: "404"
4
- title: "404 - Page Not Found / الصفحة غير موجودة"
4
+ title: "404 - Page Not Found"
5
5
  permalink: /404.html
6
6
  ---
data/500.html CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  layout: error
3
3
  code: "500"
4
- title: "500 - Internal Server Error / خطأ داخلي في الخادم"
4
+ title: "500 - Internal Server Error"
5
5
  permalink: /500.html
6
6
  ---
data/CHANGELOG.md CHANGED
@@ -4,6 +4,91 @@ 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.0.0] - 2026-09-24
8
+
9
+ ### Added
10
+ * Add Feature 4.9, auto-generate CV/profile pages per language ([`8b473b7`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/8b473b731b3c5ecf58576db9b014d389c0ab06e5))
11
+
12
+ * Add check-data-keys, a static checker for template-vs-data key mismatches ([`f4fcfcd`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/f4fcfcd7f8aaf2fbec08295a8029c0c5cfcfa6fe))
13
+
14
+ * Add client-side site search blueprint ([`ac7f7ef`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/ac7f7ef20fc3123bf28e79f390416d10ee7bcc5f))
15
+
16
+ * Add public-domain sherlock holmes avatar image ([`c73945b`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/c73945bbbc283acee174f70435fb3e5a0a8ca993))
17
+
18
+ * Add locale system reference guides ([`d4ebf9c`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/d4ebf9c236cc26b69c27a4e13588f919b6dfaf16))
19
+
20
+ * Add locale, parity, and schema test coverage ([`1314632`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/131463239e0bb9446430c7d4f0a2fb0bff034921))
21
+
22
+ * Add sherlock holmes demo resume in six languages ([`5194795`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/5194795f82c8ab2b0fbae721803efb5e59a9376e))
23
+
24
+ * Add locale-agnostic resume layout ([`28239ec`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/28239ecb2a4039f91c8be94bf78bac8a92a89a1e))
25
+
26
+ * Add unified section dispatcher for all locales ([`23cfc0d`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/23cfc0df8c4ee240d9298ee6a3f36dd4e572b99f))
27
+
28
+ * Add universal date formatter for all six locales ([`1a830bd`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/1a830bd52a44266a0145fb7ece5432f32ac9570e))
29
+
30
+ * Add native email support to social links ([`064e2e0`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/064e2e0ee7f4d5dac86911ee30becf32562d8aaa))
31
+
32
+ * Add canonical locale dictionaries for six languages ([`20973be`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/20973be336c3b871f1278e8be655ed0e7e547ab5))
33
+
34
+ * Add v1.0.0 multilingual implementation plan and align roadmap ([`9b71b02`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/9b71b02312a15dd002f28e899fc6fd315b3cf58c))
35
+
36
+
37
+ ### Changed
38
+ * Make profile layout multilingual and data-driven ([`87d4c46`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/87d4c4680dfd8510c9dc9add4ef68619e9ed24f7))
39
+
40
+ * Include base styles in profile page stylesheet ([`193f96b`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/193f96b41ccbc64938f8c54f6096c86fde69201d))
41
+
42
+ * Bump documented version to v1.0.0, reconcile roadmap ([`1c77680`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/1c77680bca4b648104495860a0481622b6ddbee8))
43
+
44
+ * Localize error-page search box to the visitor's browser language ([`256dbb3`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/256dbb3a4239d60cb1848f6db53d97e1b15780b2))
45
+
46
+ * Extract shared grouped-item-list renderer ([`1b5a0a4`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/1b5a0a46d30f3fdc355d24ca05b7dca53d4870f4))
47
+
48
+ * Bump actions/checkout in the github-actions group ([`0809e9c`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/0809e9cda99a6dd18e1daa3a83cdee1b2da26501))
49
+
50
+ * Update minitest requirement from ~> 5.25 to ~> 6.0 ([`7fa8a8e`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/7fa8a8e8cc7ad5983394c72346ac3a8b6380b4cc))
51
+
52
+ * Record PR #220's live CI verification for Feature 3.2 ([`00e8fdf`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/00e8fdffd6ed9f43dd7586ff44bda74104e138af))
53
+
54
+ * Update agent guidance and roadmap for v1.0.0; retire implementation plan ([`0579aa3`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/0579aa3fb4bb27ad221b6f13430500bfcb3692de))
55
+
56
+ * Wire build/proof tooling to the locale-driven demo overlay ([`4f27143`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/4f2714381205c1133372aa3f3ec093eed10be0de))
57
+
58
+ * Import and adapt locale-aware resume data validator ([`834969a`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/834969a7c2e2fb2e263687b81ccf60500b0e4bca))
59
+
60
+ * Make every remaining EN/AR consumer locale-driven ([`faa5d7e`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/faa5d7e503ac0dfc63fa1cd781430334f61be465))
61
+
62
+ * Purge deprecated site.avatar, analytics.ga, and resume_dark_mode fallbacks ([`e565de0`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/e565de054705c01cf572893c1ec35470f6f46dc0))
63
+
64
+ * Align Arabic header contact icons icon-first ([`ed3e655`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/ed3e655c7d6a413c87f5efd164bb06e22346383e))
65
+
66
+ * Split resume stylesheet into locale-driven LTR/RTL layers ([`807b4e2`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/807b4e240ba83e98fb0b61e3657667ec3b729450))
67
+
68
+
69
+ ### Fixed
70
+ * Resolve 404 language and Home button from the requested URL ([`8616bb2`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/8616bb201a4246cd2dee0f5b862f39d08f7a635b))
71
+
72
+ * Require "date" so YAML.safe_load_file's permitted_classes resolves on Ruby 3.3 ([`ad4a1cd`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/ad4a1cde235784d7e9e8c0fbc17741d1b959541a))
73
+
74
+ * Render single-language error pages via remembered language preference ([`7105376`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/7105376c57763e98c977685c1a96c645bbb84505))
75
+
76
+ * Tighten URL/section/language checks, require education year ([`86b8212`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/86b82122925fbb8557d0e7e4bb763730605558f6))
77
+
78
+ * Use locale-driven font variable instead of undefined RTL tokens ([`2a08333`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/2a08333e35e1770adeb256a4844e071f3d360283))
79
+
80
+ * Fall back to standard contact info when live fields are partial ([`dbd5e00`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/dbd5e001b43ef6688aab7a0d25c883a72d378ee6))
81
+
82
+ * Declare minitest as a development dependency ([`3b51fd4`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/3b51fd4d2711de4c08ffb5b98e31f1e84a3b345e))
83
+
84
+ * Use lang_cfg.name for creator microdata ([`83c97d9`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/83c97d9b99974f8860c514840c3b8682ada3c8df))
85
+
86
+ * Update actions/checkout and action-gh-release versions for compatibility ([`d807bc3`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/d807bc3f36a30e64bad2b2e1ba2169c9990114d2))
87
+
88
+
89
+ ### Removed
90
+ * Remove non-functional error-page search form ([`73e1ac5`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/73e1ac5515b548a245fd8443078909a265a6dfb3))
91
+
7
92
  ## [0.9.0] - 2026-09-21
8
93
 
9
94
  ### Added
@@ -265,6 +350,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
265
350
 
266
351
  * Initial commit (New Theme Template) ([`00af662`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/00af6628dfec7aefe0ef7d7083bf98c9713a5ffd))
267
352
 
353
+ [1.0.0]: https://github.com/kmutahar/bilingual-jekyll-resume-theme/compare/v0.9.0...v1.0.0
268
354
  [0.9.0]: https://github.com/kmutahar/bilingual-jekyll-resume-theme/compare/v0.8.0...v0.9.0
269
355
  [0.8.0]: https://github.com/kmutahar/bilingual-jekyll-resume-theme/compare/v0.7.0...v0.8.0
270
356
  [0.7.0]: https://github.com/kmutahar/bilingual-jekyll-resume-theme/compare/v0.6.1...v0.7.0
data/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # bilingual-jekyll-resume-theme
2
2
 
3
- [![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)
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
- A flexible Jekyll theme for creating clean, data-driven, bilingual (English & Arabic) resume/CV websites. Created and maintained by Khaldoon Mutahar. See the latest version on the [Releases page](https://github.com/kmutahar/bilingual-jekyll-resume-theme/releases).
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
6
  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
7
 
8
8
  ## Features
9
9
 
10
- - **Bilingual support**: Separate layouts for English (`resume-en.html`) and Arabic (`resume-ar.html`) with full RTL support and Cairo typography
10
+ - **Multilingual support**: One layout (`resume.html`) renders every language, LTR or RTL, from per-language locale files (`_data/locales/<lang>.yml`) with localized UI strings, month names, and fonts (Cairo for Arabic, Noto Nastaliq Urdu for Urdu)
11
11
  - **Dark mode**: System preference detection (`prefers-color-scheme`) with optional interactive toggle, `localStorage` persistence, and zero-FOUC inline script
12
12
  - **Data-driven architecture**: All resume content stored in YAML files, supporting multiple data paths and versioning
13
13
  - **12 resume sections**: Experience, Education, Certifications, Courses, Volunteering, Projects, Skills, Recognition, Associations, Languages, Links, Interests
@@ -15,15 +15,17 @@ Inspired by and originally forked from [Joel Glovier’s resume template](https:
15
15
  - **Modern favicon suite**: High-resolution favicons (Apple touch icon, 32x32, 16x16, webmanifest) with subpath-safe URLs and `_config.yml` override support
16
16
  - **Print-friendly**: Optimized for PDF generation and printing with bidirectional text isolation (`dir="ltr"`) for URLs
17
17
  - **SEO ready**: Built-in support for multilingual SEO, standardized canonical tags via `jekyll-seo-tag`, sitemaps, and feeds
18
- - **Arabic month support**: Arabic date formatting included out of the box (`_data/ar/months.yml`)
18
+ - **Data validation**: `validate-resume` CLI and build-time checks for schemas, dates, URLs, and parity across every configured language
19
19
 
20
20
  ## Quick Start
21
21
 
22
22
  ### Installation
23
23
 
24
- 1. Add to your Jekyll site's `Gemfile`:
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:
25
25
  ```ruby
26
- gem "bilingual-jekyll-resume-theme"
26
+ group :jekyll_plugins do
27
+ gem "bilingual-jekyll-resume-theme"
28
+ end
27
29
  ```
28
30
 
29
31
  2. Add to your `_config.yml`:
@@ -36,20 +38,20 @@ theme: bilingual-jekyll-resume-theme
36
38
  bundle install
37
39
  ```
38
40
 
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
+
39
43
  ### Basic Setup
40
44
 
41
- 1. **Copy sample configuration**: Use `docs/_data/_config.sample.yml` as a starting point for your `_config.yml`
45
+ 1. **Copy sample configuration**: Use `docs/_data/_config.sample.yml` as a starting point for your `_config.yml`. Keep a `languages.<lang>` entry for each language you publish and delete the rest.
42
46
 
43
- 2. **Copy sample data files**:
44
- - English data: Copy files from `docs/_data/en/` to your `_data/en/` directory (includes `header.yml` for the intro paragraph)
45
- - Arabic data: Copy files from `docs/_data/ar/` to your `_data/ar/` directory (includes `header.yml` for the Arabic intro paragraph)
47
+ 2. **Copy sample data files**: Copy each language folder you need from `docs/_data/` (`en`, `ar`, `es`, `fr`, `de`, `ur`) to your site's `_data/`. Each holds 13 files, including `header.yml` for the intro paragraph.
46
48
 
47
- 3. **Create resume pages**: Create pages using the `resume-en` and `resume-ar` layouts:
49
+ 3. **Create resume pages**: One page per language, all using the `resume` layout:
48
50
  ```yaml
49
51
  ---
50
- layout: resume-en
51
- permalink: /resume/en/
52
+ layout: resume
52
53
  lang: en
54
+ permalink: /en/cv/
53
55
  t_id: resume
54
56
  ---
55
57
  ```
@@ -68,6 +70,12 @@ This theme is fully documented. Choose the guide that fits your needs:
68
70
  ### 📘 [Configuration Guide](docs/CONFIG_GUIDE.md)
69
71
  Complete guide to `_config.yml` settings. Learn how to configure sections, contact info, social links, analytics, and more. **Start here for beginners.**
70
72
 
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**.
75
+
76
+ ### ✅ [Validation Guide](docs/VALIDATION_GUIDE.md)
77
+ The `validate-resume` CLI, build-time validation, rules per section, and CI setup.
78
+
71
79
  ### 📊 [Data Structure Guide](docs/DATA_GUIDE.md)
72
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.
73
81
 
@@ -90,15 +98,16 @@ Permanent engineering record of historical bug fixes, security hardening, and ar
90
98
 
91
99
  ```text
92
100
  bilingual-jekyll-resume-theme/
93
- ├── _layouts/ # HTML templates (default, resume-en, resume-ar, profile, error)
94
- ├── _includes/ # Reusable components (sections, headers, analytics, avatar, toggle)
95
- ├── _sass/ # SCSS stylesheets (RTL support, dark mode tokens, print styles)
96
- ├── _plugins/ # Dynamic generators (error_pages_generator.rb)
97
- ├── lib/ # Gem entrypoint and runtime extensions
98
- ├── _data/ # Theme data (includes ar/months.yml, error_pages.yml)
99
- ├── assets/ # CSS, images, favicons
100
- └── docs/ # Documentation and sample files
101
- ├── _data/ # Sample data files (copy to your site's _data/)
101
+ ├── _layouts/ # HTML templates (default, resume, profile, error)
102
+ ├── _includes/ # Reusable components (section dispatcher, date formatter, avatar, toggles)
103
+ ├── _sass/ # SCSS (LTR main styles, RTL overrides, dark mode tokens, print styles)
104
+ ├── _plugins/ # Error page generator and build-time resume validator
105
+ ├── _data/locales/ # Locale dictionaries: en, ar, es, fr, de, ur
106
+ ├── lib/ # Gem entrypoint and validator engine
107
+ ├── bin/ # validate-resume CLI
108
+ ├── 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/)
102
111
  └── *.md # Documentation guides
103
112
  ```
104
113
 
@@ -106,26 +115,26 @@ bilingual-jekyll-resume-theme/
106
115
 
107
116
  ### Data Paths
108
117
 
109
- **Recommended approach (for beginners):** Use language-specific folders. The theme supports separate data paths for English and Arabic:
118
+ Each language reads its data from the folder named by `languages.<lang>.data_path`:
110
119
  ```yaml
111
- active_resume_path_en: "en" # Uses _data/en/* (recommended)
112
- active_resume_path_ar: "ar" # Uses _data/ar/* (recommended)
120
+ languages:
121
+ en:
122
+ data_path: en # _data/en/*
123
+ ar:
124
+ data_path: ar # _data/ar/*
113
125
  ```
114
126
 
115
- This is the recommended approach even if you're only using one language, as it keeps your data organized and makes it easy to add more languages later. **Advanced users:** You can place files directly in `_data/` (root) by setting these to empty strings, but this is not recommended for beginners.
127
+ 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.
116
128
 
117
- See the [Configuration Guide](docs/CONFIG_GUIDE.md#7-resume-display--behavior-controls) for details.
129
+ See the [Configuration Guide](docs/CONFIG_GUIDE.md#3-languages) for every per-language key.
118
130
 
119
131
  ### Sample Files
120
132
 
121
- The theme includes sample data files in `docs/_data/en/` and `docs/_data/ar/` that you can copy to your site. These files contain:
122
- - Commented examples for all 12 section types
123
- - Required vs optional field explanations
124
- - Multiple examples per section
133
+ `docs/_data/{en,ar,es,fr,de,ur}/` hold a complete Sherlock Holmes demo resume in six languages, covering all 12 section types. Copy the folders you need to your site.
125
134
 
126
- ### Arabic Month Support
135
+ ### Locales
127
136
 
128
- The theme includes `_data/ar/months.yml` with Arabic month names already configured. You don't need to create this file manually—it's included in the theme.
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).
129
138
 
130
139
  ## Development
131
140
 
@@ -135,20 +144,32 @@ To develop this theme locally:
135
144
  # Install dependencies
136
145
  bundle install
137
146
 
138
- # Run development server in this repo (uses sample config to activate required plugins)
139
- bundle exec jekyll serve --config docs/_data/_config.sample.yml
147
+ # Serve the six-language demo (sample config + demo overlay pointing data_dir at docs/_data)
148
+ bundle exec jekyll serve --config docs/_data/_config.sample.yml,docs/_data/_config.demo.yml
140
149
 
141
150
  # Build static output
142
- bundle exec jekyll build --config docs/_data/_config.sample.yml
151
+ bundle exec jekyll build --config docs/_data/_config.sample.yml,docs/_data/_config.demo.yml
152
+
153
+ # Validate resume data schemas and parity (CLI or Rake)
154
+ ./bin/validate-resume docs/_data
155
+ bundle exec rake validate
156
+
157
+ # Check that the theme's own templates only reference real data keys (CLI or Rake)
158
+ ./bin/check-data-keys docs/_data
159
+ bundle exec rake check_data_keys
160
+
161
+ # Validators, RuboCop, and tests together
162
+ bundle exec rake
143
163
 
144
164
  # Build the gem
145
165
  gem build bilingual-jekyll-resume-theme.gemspec
146
166
  ```
147
167
 
148
- For more details, see [WARP.md](WARP.md) or the [Development section](#development) below.
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).
149
169
 
150
170
  ## Requirements
151
171
 
172
+ - Ruby 3.3+ (standard support on Ruby 3.3, 3.4, 4.0+; Ruby <= 3.2 is EOL)
152
173
  - Jekyll 4.4+ (specified in `bilingual-jekyll-resume-theme.gemspec`)
153
174
  - Required plugins (automatically included):
154
175
  - `jekyll-feed`
@@ -173,5 +194,5 @@ The theme is available as open source under the terms of the [MIT License](LICEN
173
194
 
174
195
  ---
175
196
 
176
- **Created by Khaldoon Mutahar** | Version 0.8.0 | MIT License
197
+ **Created by Khaldoon Mutahar** | MIT License
177
198
 
@@ -0,0 +1,87 @@
1
+ direction: "rtl"
2
+ font_family: "'Cairo', sans-serif"
3
+ font_url: "https://fonts.googleapis.com/css2?family=Cairo:wght@300;400;600;700;900&display=swap"
4
+ line_height: 1.6
5
+ ui:
6
+ home: "الرئيسية"
7
+ skip_to_content: "الانتقال إلى المحتوى الرئيسي"
8
+ photo_alt: "الصورة الشخصية"
9
+ present: "حتى الآن"
10
+ date_of_birth: "تاريخ الميلاد:"
11
+ languages: "اللغات:"
12
+ contact_me: "تواصل معي"
13
+ cv_button: "السيرة الذاتية"
14
+ not_looking_for_work: "لستُ باحثاً عن عمل حالياً."
15
+ social_links: "روابط التواصل"
16
+ page_last_generated_on: "تم إنشاء هذه الصفحة بتاريخ"
17
+ cv_last_generated_on: "تم إنشاء هذه السيرة الذاتية بتاريخ"
18
+ at: "في"
19
+ credential_id: "معرّف الاعتماد:"
20
+ list_separator: "، "
21
+ dark_mode_toggle: "تبديل إلى الوضع الداكن"
22
+ language_switcher: "محدد اللغة"
23
+ language_name: "العربية"
24
+ reload_page: "إعادة تحميل الصفحة"
25
+ section_titles:
26
+ experience: "الخبرات العملية"
27
+ education: "التعليم"
28
+ certifications: "التراخيص والشهادات"
29
+ courses: "الدورات"
30
+ volunteering: "الأعمال التطوعية"
31
+ projects: "المشاريع"
32
+ skills: "المهارات"
33
+ recognitions: "الجوائز والتكريم"
34
+ associations: "العضويات"
35
+ interests: "الاهتمامات الخارجية"
36
+ languages: "اللغات"
37
+ links: "روابط إضافية"
38
+ social_labels:
39
+ email: "البريد الإلكتروني"
40
+ github: "جيت هاب"
41
+ twitter: "إكس (تويتر)"
42
+ medium: "ميديام"
43
+ dribbble: "دريبل"
44
+ facebook: "فيسبوك"
45
+ linkedin: "لينكد إن"
46
+ instagram: "إنستغرام"
47
+ website: "الموقع الشخصي"
48
+ whatsapp: "واتساب"
49
+ devto: "ديف تو"
50
+ flickr: "فليكر"
51
+ pinterest: "بينتيريست"
52
+ telegram: "تيليجرام"
53
+ youtube: "يوتيوب"
54
+ error_pages:
55
+ "404":
56
+ title: "الصفحة غير موجودة"
57
+ message: "ربما تمت إزالة الصفحة التي تبحث عنها، أو تم تغيير اسمها، أو أنها غير متوفرة مؤقتاً."
58
+ "403":
59
+ title: "الوصول محظور"
60
+ message: "ليس لديك الصلاحية اللازمة للوصول إلى هذا المورد أو الدليل المطلوب."
61
+ "500":
62
+ title: "خطأ داخلي في الخادم"
63
+ message: "واجه الخادم ظرفاً غير متوقع منعه من إكمال الطلب. يرجى المحاولة مرة أخرى لاحقاً."
64
+ "503":
65
+ title: "الخدمة غير متوفرة مؤقتاً"
66
+ message: "الخادم غير قادر على معالجة الطلب حالياً بسبب الصيانة أو زيادة الحمل."
67
+ return_link: "العودة إلى السيرة الذاتية"
68
+ search_label: "البحث في الموقع"
69
+ search_placeholder: "البحث في الموقع..."
70
+ search_button: "بحث"
71
+ present_values:
72
+ - "present"
73
+ - "حتى الآن"
74
+ - "حاليًا"
75
+ months:
76
+ - "يناير"
77
+ - "فبراير"
78
+ - "مارس"
79
+ - "أبريل"
80
+ - "مايو"
81
+ - "يونيو"
82
+ - "يوليو"
83
+ - "أغسطس"
84
+ - "سبتمبر"
85
+ - "أكتوبر"
86
+ - "نوفمبر"
87
+ - "ديسمبر"
@@ -0,0 +1,88 @@
1
+ direction: "ltr"
2
+ font_family: ""
3
+ font_url: ""
4
+ line_height: 1.5
5
+ ui:
6
+ home: "Startseite"
7
+ skip_to_content: "Zum Hauptinhalt springen"
8
+ photo_alt: "Profilfoto"
9
+ present: "Heute"
10
+ date_of_birth: "Geburtsdatum:"
11
+ languages: "Sprachen:"
12
+ contact_me: "Kontaktieren Sie mich"
13
+ cv_button: "Lebenslauf"
14
+ not_looking_for_work: "Ich bin derzeit nicht auf Jobsuche."
15
+ social_links: "Soziale Links"
16
+ page_last_generated_on: "Diese Seite wurde zuletzt generiert am"
17
+ cv_last_generated_on: "Dieser Lebenslauf wurde zuletzt generiert am"
18
+ at: "um"
19
+ credential_id: "Zertifikats-ID:"
20
+ list_separator: ", "
21
+ dark_mode_toggle: "Zum Dunkelmodus wechseln"
22
+ language_switcher: "Sprachauswahl"
23
+ language_name: "Deutsch"
24
+ reload_page: "Seite neu laden"
25
+ section_titles:
26
+ experience: "Berufserfahrung"
27
+ education: "Ausbildung"
28
+ certifications: "Lizenzen & Zertifizierungen"
29
+ courses: "Kurse"
30
+ volunteering: "Ehrenamt"
31
+ projects: "Projekte"
32
+ skills: "Fähigkeiten"
33
+ recognitions: "Auszeichnungen"
34
+ associations: "Mitgliedschaften"
35
+ interests: "Interessen"
36
+ languages: "Sprachen"
37
+ links: "Weitere Links"
38
+ social_labels:
39
+ email: "E-Mail"
40
+ github: "GitHub"
41
+ twitter: "X (Twitter)"
42
+ medium: "Medium"
43
+ dribbble: "Dribbble"
44
+ facebook: "Facebook"
45
+ linkedin: "LinkedIn"
46
+ instagram: "Instagram"
47
+ website: "Webseite"
48
+ whatsapp: "WhatsApp"
49
+ devto: "Dev.to"
50
+ flickr: "Flickr"
51
+ pinterest: "Pinterest"
52
+ telegram: "Telegram"
53
+ youtube: "YouTube"
54
+ error_pages:
55
+ "404":
56
+ title: "Seite Nicht Gefunden"
57
+ message: "Die gesuchte Seite wurde möglicherweise entfernt, umbenannt oder ist vorübergehend nicht verfügbar."
58
+ "403":
59
+ title: "Zugriff Verweigert"
60
+ message: "Sie haben keine Berechtigung, auf die angeforderte Ressource oder das Verzeichnis zuzugreifen."
61
+ "500":
62
+ title: "Interner Serverfehler"
63
+ message: "Der Server hat einen unerwarteten Zustand festgestellt, der die Bearbeitung der Anfrage verhindert hat. Bitte versuchen Sie es später erneut."
64
+ "503":
65
+ title: "Dienst Nicht Verfügbar"
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
+ present_values:
72
+ - "present"
73
+ - "heute"
74
+ - "aktuell"
75
+ - "gegenwärtig"
76
+ months:
77
+ - "Januar"
78
+ - "Februar"
79
+ - "März"
80
+ - "April"
81
+ - "Mai"
82
+ - "Juni"
83
+ - "Juli"
84
+ - "August"
85
+ - "September"
86
+ - "Oktober"
87
+ - "November"
88
+ - "Dezember"
@@ -0,0 +1,86 @@
1
+ direction: "ltr"
2
+ font_family: ""
3
+ font_url: ""
4
+ line_height: 1.5
5
+ ui:
6
+ home: "Home"
7
+ skip_to_content: "Skip to main content"
8
+ photo_alt: "Profile photo"
9
+ present: "Present"
10
+ date_of_birth: "DoB:"
11
+ languages: "Languages:"
12
+ contact_me: "Contact me"
13
+ cv_button: "Curriculum Vitae"
14
+ not_looking_for_work: "I'm not looking for work right now."
15
+ social_links: "Social Links"
16
+ page_last_generated_on: "This page was last generated on"
17
+ cv_last_generated_on: "This CV was last generated on"
18
+ at: "at"
19
+ credential_id: "Credential ID:"
20
+ list_separator: ", "
21
+ dark_mode_toggle: "Switch to dark mode"
22
+ language_switcher: "Language Selector"
23
+ language_name: "English"
24
+ reload_page: "Reload Page"
25
+ section_titles:
26
+ experience: "Experience"
27
+ education: "Education"
28
+ certifications: "Licenses & Certifications"
29
+ courses: "Courses"
30
+ volunteering: "Volunteering"
31
+ projects: "Projects"
32
+ skills: "Skills"
33
+ recognitions: "Recognition"
34
+ associations: "Associations"
35
+ interests: "Outside Interests"
36
+ languages: "Languages"
37
+ links: "Additional Links"
38
+ social_labels:
39
+ email: "Email"
40
+ github: "GitHub"
41
+ twitter: "X (Twitter)"
42
+ medium: "Medium"
43
+ dribbble: "Dribbble"
44
+ facebook: "Facebook"
45
+ linkedin: "LinkedIn"
46
+ instagram: "Instagram"
47
+ website: "Website"
48
+ whatsapp: "WhatsApp"
49
+ devto: "Dev.to"
50
+ flickr: "Flickr"
51
+ pinterest: "Pinterest"
52
+ telegram: "Telegram"
53
+ youtube: "YouTube"
54
+ error_pages:
55
+ "404":
56
+ title: "Page Not Found"
57
+ message: "The page you are looking for might have been removed, had its name changed, or is temporarily unavailable."
58
+ "403":
59
+ title: "Access Forbidden"
60
+ message: "You do not have permission to access the requested resource or directory."
61
+ "500":
62
+ title: "Internal Server Error"
63
+ message: "The server encountered an unexpected condition that prevented it from fulfilling the request. Please try again later."
64
+ "503":
65
+ title: "Service Unavailable"
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
+ present_values:
72
+ - "present"
73
+ - "current"
74
+ months:
75
+ - "January"
76
+ - "February"
77
+ - "March"
78
+ - "April"
79
+ - "May"
80
+ - "June"
81
+ - "July"
82
+ - "August"
83
+ - "September"
84
+ - "October"
85
+ - "November"
86
+ - "December"