jekyll-theme-centos 2.52.0.beta.104 → 2.52.0.beta.106

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.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/_config.yml +2 -2
  3. data/_data/base/accordion_schema.yml +6 -0
  4. data/_data/base/announcement_schema.yml +1 -1
  5. data/_data/base/artwork_schema.yml +17 -3
  6. data/_data/base/bits_schema.yml +9 -4
  7. data/_data/base/breadcrumb_schema.yml +14 -0
  8. data/_data/base/breakingnews_schema.yml +1 -1
  9. data/_data/base/calendar_schema.yml +17 -2
  10. data/_data/base/card_schema.yml +2 -2
  11. data/_data/base/copyright_schema.yml +7 -17
  12. data/_data/base/copyvalue_schema.yml +4 -1
  13. data/_data/base/datatable_schema.yml +3 -3
  14. data/_data/base/download_schema.yml +42 -16
  15. data/_data/base/event_schema.yml +1 -1
  16. data/_data/base/footer_schema.yml +7 -6
  17. data/_data/base/highlight_schema.yml +7 -5
  18. data/_data/base/image_schema.yml +1 -1
  19. data/_data/base/link_schema.yml +13 -19
  20. data/_data/base/navbar_schema.yml +6 -0
  21. data/_data/base/preview_schema.yml +8 -4
  22. data/_data/base/project_schema.yml +4 -2
  23. data/_data/base/script_schema.yml +4 -4
  24. data/_data/base/shortcut_schema.yml +2 -2
  25. data/_data/base/social_schema.yml +2 -2
  26. data/_data/base/sponsors.yml +3 -2
  27. data/_data/base/sponsors_schema.yml +20 -0
  28. data/_data/base/title_schema.yml +14 -0
  29. data/_data/base/toc_schema.yml +16 -2
  30. data/_includes/base/accordion-item.html.liquid +11 -32
  31. data/_includes/base/accordion.html.liquid +3 -29
  32. data/_includes/base/announcement.html.liquid +8 -35
  33. data/_includes/base/artwork.html.liquid +5 -38
  34. data/_includes/base/backtotop.html.liquid +3 -42
  35. data/_includes/base/bits.html.liquid +26 -74
  36. data/_includes/base/breadcrumb.html.liquid +15 -49
  37. data/_includes/base/breakingnews.html.liquid +6 -43
  38. data/_includes/base/calendar-events.html.liquid +3 -37
  39. data/_includes/base/calendar-init.html.liquid +7 -63
  40. data/_includes/base/calendar.html.liquid +3 -34
  41. data/_includes/base/card.html.liquid +4 -44
  42. data/_includes/base/color-table.html.liquid +18 -4
  43. data/_includes/base/configuration_variables-default-cell.html.liquid +6 -50
  44. data/_includes/base/configuration_variables-nested.html.liquid +6 -7
  45. data/_includes/base/configuration_variables.html.liquid +9 -11
  46. data/_includes/base/content.html.liquid +7 -4
  47. data/_includes/base/copyright.html.liquid +8 -39
  48. data/_includes/base/copyvalue.html.liquid +3 -70
  49. data/_includes/base/datatable.html.liquid +4 -40
  50. data/_includes/base/download.html.liquid +12 -66
  51. data/_includes/base/download_architecture.html.liquid +29 -117
  52. data/_includes/base/download_commands.html.liquid +2 -14
  53. data/_includes/base/download_documentation.html.liquid +13 -47
  54. data/_includes/base/download_eol.html.liquid +5 -15
  55. data/_includes/base/download_filevalue.html.liquid +9 -49
  56. data/_includes/base/download_screenshots.html.liquid +10 -65
  57. data/_includes/base/download_sections.html.liquid +2 -19
  58. data/_includes/base/event.html.liquid +8 -63
  59. data/_includes/base/fontawesome.html.liquid +4 -38
  60. data/_includes/base/footer.html.liquid +9 -2
  61. data/_includes/base/head.html.liquid +6 -47
  62. data/_includes/base/highlight.html.liquid +4 -37
  63. data/_includes/base/image.html.liquid +5 -22
  64. data/_includes/base/link.html.liquid +38 -57
  65. data/_includes/base/locales.html.liquid +6 -26
  66. data/_includes/base/navbar.html.liquid +16 -45
  67. data/_includes/base/navindex.html.liquid +40 -111
  68. data/_includes/base/ogp.html.liquid +17 -83
  69. data/_includes/base/preview.html.liquid +18 -57
  70. data/_includes/base/project.html.liquid +4 -29
  71. data/_includes/base/shortcut.html.liquid +7 -37
  72. data/_includes/base/social.html.liquid +4 -42
  73. data/_includes/base/sponsors-cards.html.liquid +4 -55
  74. data/_includes/base/sponsors-carousel.html.liquid +11 -59
  75. data/_includes/base/sponsors-data.html.liquid +32 -0
  76. data/_includes/base/title.html.liquid +5 -42
  77. data/_includes/base/toc-generator.html.liquid +4 -0
  78. data/_includes/base/toc.html.liquid +28 -81
  79. data/_sass/base/_customization.scss +18 -0
  80. data/_sass/base/_preview.scss +5 -9
  81. data/assets/icons/favicon.ico +0 -0
  82. data/assets/js/base/backtotop.js +3 -3
  83. data/assets/js/base/copyvalue.js +15 -11
  84. data/assets/js/base/datatable.js +6 -13
  85. data/assets/js/base/highlight.js +46 -31
  86. metadata +2 -1
@@ -1,49 +1,7 @@
1
1
  {% comment %}
2
- ================================================================================
3
- Template: Open Graph & Twitter Meta Tags Component
4
- Purpose: Renders meta tags for Open Graph (OG) and Twitter Card protocols.
5
- Enables proper social media previews when sharing on social platforms.
6
- ================================================================================
7
-
8
- Design Logic:
9
- - Dual-protocol support: Open Graph (OG) and Twitter Card meta tags
10
- - Hierarchical fallback system for meta tag values
11
- - Per-property customization via page front matter
12
- - Conditional rendering of protocol-specific attributes
13
- - Image metadata with security URL and dimensions for OG
14
-
15
- Required Inputs:
16
- - page.title: Page title for social sharing preview
17
- - site.url: Full site URL (for absolute URLs)
18
- - site.baseurl: Base URL path prefix
19
-
20
- Optional Inputs:
21
- - with_ogp_data.og.*, with_ogp_data.twitter.*: OG/Twitter property overrides
22
- - page.excerpt, page.title_lead: Fallback for description
23
- - site.description: Site-level description fallback
24
- - page.locale: BCP 47 locale code set by jekyll-l10n on localized pages
25
-
26
- Data Source Hierarchy:
27
- - og:title, twitter:title: with_ogp_data[property].title (real string override)
28
- → page.title → schema default. `true` (this component's own previously
29
- documented convention) is treated the same as omitted, for backward
30
- compatibility; `false` or "" suppresses the tag entirely.
31
- - og:image:url, :secure_url (+ twitter): with_ogp_data[property].image.url/
32
- .secure_url (real string override) → schema default
33
- (/assets/img/centos-social-share.png). Same `true`-tolerance as
34
- title, for the same reason.
35
- - og:type: with_ogp_data.og.type → schema default → 'website'
36
- - og:site_name: with_ogp_data.og.site_name → site.title
37
- - og:logo: with_ogp_data.og.logo → schema default → '/assets/icons/apple-touch-icon.png'
38
- - og:locale: page.locale (jekyll-l10n) → with_ogp_data.locale → schema default → 'en_US'
39
- - og:image:type: with_ogp_data.og.image.type → schema default → 'image/png'
40
- - og:image:width: with_ogp_data.og.image.width → schema default → 1200
41
- - og:image:height: with_ogp_data.og.image.height → schema default → 630
42
- - og:image:alt: with_ogp_data[property].image.alt → schema default → 'The CentOS Project'
43
- - twitter:card: with_ogp_data.twitter.card → schema default → 'summary_large_image'
44
- - twitter:site: with_ogp_data.twitter.site → schema default → '@CentOS'
45
- - twitter:creator: with_ogp_data.twitter.creator → schema default → '@CentOS'
46
- ================================================================================
2
+ ogp: renders Open Graph and Twitter Card meta tags.
3
+ Data: include.data > page.with_ogp_data > site.data.ogp > site.data.base.ogp
4
+ Schema: src/YAML/ogp_schema.yml
47
5
  {% endcomment %}
48
6
 
49
7
  {%- assign with_ogp = include.with_ogp
@@ -59,43 +17,31 @@ Data Source Hierarchy:
59
17
  {%- assign with_ogp_schema = site.data.base.ogp_schema.properties.with_ogp_data.properties %}
60
18
 
61
19
  {%- if with_ogp %}
62
-
63
- {%- comment %} === Presentation === {% endcomment %}
64
- {%- comment %} --- Schema shorthands --- {% endcomment %}
65
20
  {%- assign with_ogp_og_image_schema = with_ogp_schema.og.properties.image.properties %}
66
21
  {%- assign with_ogp_twitter_schema = with_ogp_schema.twitter.properties %}
67
22
 
68
- {%- comment %} --- Shared image metadata (og and twitter use the same image) --- {% endcomment %}
69
- {%- assign ogp_image_type = with_ogp_data.og.image.type | default: with_ogp_og_image_schema.type.default | default: 'image/png' %}
70
- {%- assign ogp_image_width = with_ogp_data.og.image.width | default: with_ogp_og_image_schema.width.default | default: 1200 %}
71
- {%- assign ogp_image_height = with_ogp_data.og.image.height | default: with_ogp_og_image_schema.height.default | default: 630 %}
72
-
73
- {%- comment %} --- Defaults --- {% endcomment %}
23
+ {%- comment %} og and twitter share one image, so its metadata resolves once. {% endcomment %}
24
+ {%- assign ogp_image_type = with_ogp_data.og.image.type | default: with_ogp_og_image_schema.type.default %}
25
+ {%- assign ogp_image_width = with_ogp_data.og.image.width | default: with_ogp_og_image_schema.width.default %}
26
+ {%- assign ogp_image_height = with_ogp_data.og.image.height | default: with_ogp_og_image_schema.height.default %}
74
27
  {%- assign ogp_og_type = with_ogp_data.og.type | default: with_ogp_schema.og.properties.type.default %}
75
- {%- assign ogp_locale = page.locale | default: with_ogp_data.locale | default: with_ogp_schema.locale.default | default: 'en_US' %}
28
+ {%- assign ogp_locale = page.locale | default: with_ogp_data.locale | default: with_ogp_schema.locale.default %}
76
29
  {%- assign ogp_twitter_card = with_ogp_data.twitter.card
77
- | default: with_ogp_twitter_schema.card.default
78
- | default: 'summary_large_image' %}
30
+ | default: with_ogp_twitter_schema.card.default %}
79
31
  {%- assign ogp_twitter_site = with_ogp_data.twitter.site
80
- | default: with_ogp_twitter_schema.site.default
81
- | default: '@CentOS' %}
32
+ | default: with_ogp_twitter_schema.site.default %}
82
33
  {%- assign ogp_twitter_creator = with_ogp_data.twitter.creator
83
- | default: with_ogp_twitter_schema.creator.default
84
- | default: '@CentOS' %}
85
-
86
- {%- comment %} --- Common attributes for both `og` and `twitter` properties --- {% endcomment %}
34
+ | default: with_ogp_twitter_schema.creator.default %}
87
35
  {%- assign properties = "og,twitter" | split: "," %}
88
36
  {%- for property in properties %}
89
37
  {%- if property == "twitter" %}{%- assign meta_attr = "name" %}{%- else %}{%- assign meta_attr = "property" %}{%- endif %}
90
-
91
- {%- comment %} --- Twitter Card: required first --- {% endcomment %}
92
38
  {%- if property == "twitter" %}
93
39
  <meta name="twitter:card" content="{{ ogp_twitter_card }}" />
94
40
  <meta name="twitter:site" content="{{ ogp_twitter_site }}" />
95
41
  <meta name="twitter:creator" content="{{ ogp_twitter_creator }}" />
96
42
  {%- endif %}
97
43
 
98
- {%- comment %} --- Title --- {% endcomment %}
44
+ {%- comment %} A title of true counts as omitted, for backward compatibility; false or "" suppresses the tag. {% endcomment %}
99
45
  {%- assign ogp_title_raw = with_ogp_data[property].title %}
100
46
  {%- if ogp_title_raw == nil or ogp_title_raw == true %}
101
47
  {%- assign ogp_title = page.title | default: with_ogp_schema.og.properties.title.default %}
@@ -105,8 +51,6 @@ Data Source Hierarchy:
105
51
  {%- if ogp_title and ogp_title != empty %}
106
52
  <meta {{ meta_attr }}="{{ property }}:title" content="{{ ogp_title | escape }}" />
107
53
  {%- endif %}
108
-
109
- {%- comment %} --- OG type and logo (after title, before url) --- {% endcomment %}
110
54
  {%- if property == "og" %}
111
55
  <meta property="og:type" content="{{ ogp_og_type }}" />
112
56
  {%- assign ogp_logo = with_ogp_data.og.logo | default: with_ogp_schema.og.properties.logo.default %}
@@ -114,24 +58,16 @@ Data Source Hierarchy:
114
58
  <meta property="og:logo" content="{{ site.url }}{{ site.baseurl }}{{ ogp_logo }}" />
115
59
  {%- endif %}
116
60
  {%- endif %}
117
-
118
- {%- comment %} --- URL --- {% endcomment %}
119
61
  {%- if with_ogp_data[property].url %}
120
62
  <meta {{ meta_attr }}="{{ property }}:url" content="{{ site.url }}{{ site.baseurl }}{{ page.url }}" />
121
63
  {%- endif %}
122
-
123
- {%- comment %} --- Description --- {% endcomment %}
124
64
  {%- if with_ogp_data[property].description %}
125
- {%- if page.excerpt %}
126
- <meta {{ meta_attr }}="{{ property }}:description" content="{{ page.excerpt | strip_html | escape }}" />
127
- {%- elsif page.title_lead %}
128
- <meta {{ meta_attr }}="{{ property }}:description" content="{{ page.title_lead | escape }}" />
129
- {%- else %}
130
- <meta {{ meta_attr }}="{{ property }}:description" content="{{ site.description | escape }}" />
131
- {%- endif %}
65
+ {%- comment %} Same sources and filters as the description meta tag in head.html.liquid; markdownify runs first so strip_html keeps literal tags written as code. {% endcomment %}
66
+ {%- assign ogp_description = page.description | default: page.excerpt | default: page.title_lead | default: site.description | markdownify | strip_html | strip_newlines | strip %}
67
+ <meta {{ meta_attr }}="{{ property }}:description" content="{{ ogp_description | escape_once }}" />
132
68
  {%- endif %}
133
69
 
134
- {%- comment %} --- Image --- {% endcomment %}
70
+ {%- comment %} image.url and image.secure_url follow the same true-counts-as-omitted rule as the title. {% endcomment %}
135
71
  {%- assign ogp_image_url_raw = with_ogp_data[property].image.url %}
136
72
  {%- if ogp_image_url_raw == nil or ogp_image_url_raw == true %}
137
73
  {%- assign ogp_image_url = with_ogp_og_image_schema.url.default %}
@@ -154,10 +90,8 @@ Data Source Hierarchy:
154
90
  <meta {{ meta_attr }}="{{ property }}:image:width" content="{{ ogp_image_width }}" />
155
91
  <meta {{ meta_attr }}="{{ property }}:image:height" content="{{ ogp_image_height }}" />
156
92
  {%- endif %}
157
- <meta {{ meta_attr }}="{{ property }}:image:alt" content="{{ with_ogp_data[property].image.alt | default: with_ogp_og_image_schema.alt.default | default: 'The CentOS Project' | escape }}" />
93
+ <meta {{ meta_attr }}="{{ property }}:image:alt" content="{{ with_ogp_data[property].image.alt | default: with_ogp_og_image_schema.alt.default | escape }}" />
158
94
  {%- endif %}
159
-
160
- {%- comment %} --- OG site_name and locale (after image) --- {% endcomment %}
161
95
  {%- if property == "og" %}
162
96
  {%- assign ogp_site_name = with_ogp_data.og.site_name | default: site.title %}
163
97
  {%- if ogp_site_name %}
@@ -1,39 +1,6 @@
1
1
  {% comment %}
2
- ================================================================================
3
- Template: Preview Box Component
4
- Purpose: Puts a live demo, a toolbar, and a code sample in one bordered
5
- box, as up to three stacked rows.
6
-
7
- Behavior:
8
- - Pass `language` or `code`, and the template renders all three rows —
9
- demo (`.preview-content`), toolbar with a language label and copy
10
- button (`.preview-toolbar`), and code (`.preview-code`) — wrapped in
11
- `<div class="preview ...">`. A row with nothing to show is skipped.
12
- - Pass neither, and the template renders a single plain
13
- `<div class="{{ class }}">{{ content }}</div>`, so a caller that only
14
- needs a demo wrapper gets one without a toolbar or code row.
15
- - Each render mode has its own default outer-box styling (padded and
16
- tinted for the plain fallback, bordered and flush for the three-row
17
- box). A `class` the caller passes replaces that default entirely.
18
- - The copy button reuses the site-wide `.copy-btn` click handler
19
- (src/JS/copyvalue.js), loaded by copyvalue.html.liquid.
20
- - Highlight.js colors the code; this template only adds the
21
- `language-{{ language }}` class the highlighter reads. The toolbar
22
- label shows uppercase through `language_class`'s `text-uppercase`; the
23
- value passed in stays lowercase to match that class.
24
-
25
- Optional Inputs:
26
- - class: CSS classes for the outer `<div>`.
27
- - content / content_class: The demo row's HTML (a caller-built `capture`
28
- block) and its wrapper's classes.
29
- - language / language_class: The toolbar's language label and its
30
- classes. Also becomes the `language-{{ language }}` class on the code
31
- row's `<code>` tag.
32
- - copy_class: Extra classes on the copy button. Use `d-none` to hide it
33
- without removing `code`. Only shows when `code` is set.
34
- - code / code_class: The code row's raw text (HTML-escaped automatically)
35
- and its wrapper's classes.
36
- ================================================================================
2
+ preview: renders a demo, a toolbar, and an escaped code sample in one box, or only a plain demo wrapper when neither language nor code is set; the toolbar shows only when it holds a language label or a copy button, and the copy button only when page.with_copyvalue is on.
3
+ Schema: src/YAML/preview_schema.yml
37
4
  {% endcomment %}
38
5
 
39
6
  {%- assign with_preview_schema = site.data.base.preview_schema.properties %}
@@ -46,31 +13,30 @@ Optional Inputs:
46
13
  {%- assign preview_copy_class = include.copy_class | default: with_preview_schema.copy_class.default %}
47
14
  {%- assign preview_code = include.code | default: with_preview_schema.code.default %}
48
15
  {%- assign preview_code_class = include.code_class | default: with_preview_schema.code_class.default %}
49
-
50
- {%- comment %} === Presentation === {% endcomment %}
51
-
52
- {%- comment %} --- Row visibility --- {% endcomment %}
53
16
  {%- assign preview_show_code = false %}
54
17
  {%- if preview_code != "" %}
55
18
  {%- assign preview_show_code = true %}
56
19
  {%- endif %}
57
- {%- assign preview_show_toolbar = false %}
20
+ {%- assign preview_show_frame = false %}
58
21
  {%- if preview_language != "" or preview_show_code %}
59
- {%- assign preview_show_toolbar = true %}
22
+ {%- assign preview_show_frame = true %}
60
23
  {%- endif %}
61
- {%- assign preview_multirow = false %}
62
- {%- if preview_show_toolbar %}
63
- {%- assign preview_multirow = true %}
24
+ {%- comment %} Same gate as base/copyvalue.html.liquid, which head.html.liquid includes without parameters: no copy script means no copy button. {% endcomment %}
25
+ {%- assign preview_show_copy = false %}
26
+ {%- if preview_show_code and page.with_copyvalue %}
27
+ {%- assign preview_show_copy = true %}
28
+ {%- endif %}
29
+ {%- assign preview_show_toolbar = false %}
30
+ {%- if preview_language != "" or preview_show_copy %}
31
+ {%- assign preview_show_toolbar = true %}
64
32
  {%- endif %}
65
33
 
66
- {%- comment %} --- Outer container: use the default multirow look, unless the caller set their own `class` --- {% endcomment %}
67
- {%- if preview_multirow %}
34
+ {%- comment %} A caller's class replaces the framed layout's default; include.class, not preview_class, tells whether one was passed. {% endcomment %}
35
+ {%- if preview_show_frame %}
68
36
  {%- unless include.class %}
69
37
  {%- assign preview_class = "mb-3 border rounded overflow-hidden" %}
70
38
  {%- endunless %}
71
39
  {%- endif %}
72
-
73
- {%- comment %} --- Row 1: Live demo --- {% endcomment %}
74
40
  {%- capture html_preview_content %}
75
41
  {%- if preview_content != "" %}
76
42
  <div class="preview-content{% if preview_content_class != "" %} {{ preview_content_class }}{% endif %}">
@@ -78,14 +44,12 @@ Optional Inputs:
78
44
  </div>
79
45
  {%- endif %}
80
46
  {%- endcapture %}
81
-
82
- {%- comment %} --- Row 2: Toolbar (language label + copy button) --- {% endcomment %}
83
47
  {%- capture html_preview_toolbar %}
84
48
  {%- if preview_show_toolbar %}
85
49
  <div class="preview-toolbar m-0 p-2{% if preview_content != "" %} border-top{% endif %}{% if preview_show_code %} border-bottom{% endif %} border-centos-purple-100">
86
50
  {%- if preview_language != "" %}<span class="preview-language{% if preview_language_class != "" %} {{ preview_language_class }}{% endif %}">{{ preview_language }}</span>{%- endif %}
87
51
  <div class="preview-actions">
88
- {%- if preview_show_code %}
52
+ {%- if preview_show_copy %}
89
53
  <button type="button" class="copy-btn focus-ring preview-copy{% if preview_copy_class != "" %} {{ preview_copy_class }}{% endif %}" data-bs-toggle="tooltip" data-bs-title="Copy code" data-copy-value="{{ preview_code | escape }}" aria-label="Copy code">
90
54
  <i class="fa-regular fa-copy"></i>
91
55
  </button>
@@ -94,18 +58,15 @@ Optional Inputs:
94
58
  </div>
95
59
  {%- endif %}
96
60
  {%- endcapture %}
97
-
98
- {%- comment %} --- Row 3: Code sample --- {% endcomment %}
99
61
  {%- capture html_preview_code %}
100
62
  {%- if preview_show_code %}
101
- <div class="preview-code{% if preview_code_class != "" %} {{ preview_code_class }}{% endif %}">
63
+ {%- comment %} Without a toolbar, the code row takes over the divider line against the demo row above it. {% endcomment %}
64
+ <div class="preview-code{% if preview_code_class != "" %} {{ preview_code_class }}{% endif %}{% if preview_content != "" %}{% unless preview_show_toolbar %} border-top border-centos-purple-100{% endunless %}{% endif %}">
102
65
  <pre class="p-2"><code{% if preview_language != "" %} class="language-{{ preview_language }}"{% endif %}>{{ preview_code | escape }}</code></pre>
103
66
  </div>
104
67
  {%- endif %}
105
68
  {%- endcapture %}
106
-
107
- {%- comment %} --- HTML --- {% endcomment -%}
108
- {%- if preview_multirow %}
69
+ {%- if preview_show_frame %}
109
70
  <div class="preview {{ preview_class }}">
110
71
  {{- html_preview_content | strip -}}
111
72
  {{- html_preview_toolbar | strip -}}
@@ -1,30 +1,7 @@
1
1
  {% comment %}
2
- ================================================================================
3
- Template: Project Showcase Component
4
- Purpose: Renders a full-width project/product hero section with featured
5
- content and supplementary resource links.
6
- ================================================================================
7
-
8
- Design Logic:
9
- - Hero-style layout: full-width container with dark background
10
- - Wraps card component for flexible content presentation
11
- - Dark theme (text-bg-dark) for high contrast and visual prominence
12
- - Resource section for downloadable/related content links
13
- - Data source hierarchy enables both page-level and site-level config
14
- - Container-based layout for max-width constraint on large screens
15
- - Reuses link component for action and resource buttons
16
-
17
- Optional Inputs:
18
- - data: Project data object (overrides all fallbacks)
19
- - project.name, description, icon, image, screenshot: Content
20
- - project.actions, resources: Arrays of buttons [{name, url, icon}]
21
-
22
- Data Source Hierarchy (priority):
23
- 1. include.data
24
- 2. page.with_project_data
25
- 3. site.data.project
26
- 4. site.data.base.project
27
- ================================================================================
2
+ project: renders a full-width hero with a card and a row of resource buttons.
3
+ Data: include.data > page.with_project_data > site.data.project > site.data.base.project
4
+ Schema: src/YAML/project_schema.yml
28
5
  {% endcomment %}
29
6
 
30
7
  {%- assign with_project = include.with_project
@@ -71,7 +48,6 @@ Data Source Hierarchy (priority):
71
48
  <div class="container{% if with_navbar %} pt-2{% endif %}">
72
49
  {% include base/card.html.liquid
73
50
  class = project_content_class
74
- color = "primary"
75
51
  screenshot = project_screenshot
76
52
  screenshot_class = project_screenshot_class
77
53
  screenshot_alt = project_screenshot_alt
@@ -90,11 +66,10 @@ Data Source Hierarchy (priority):
90
66
  actions_class = project_actions_class
91
67
  %}
92
68
  {%- if project_resources.size > 0 %}
93
- <div class="d-grid{% if project_resources_class %} {{ project_resources_class }}{% endif %}">
69
+ <div class="d-grid{% if project_resources_class != "" %} {{ project_resources_class }}{% endif %}">
94
70
  {%- for resource in project_resources %}
95
71
  {% include base/link.html.liquid
96
72
  class = project_resources_btn_class
97
- role = "button"
98
73
  name = resource.name
99
74
  link = resource.link
100
75
  icon = resource.icon
@@ -1,38 +1,7 @@
1
1
  {% comment %}
2
- ================================================================================
3
- Template: Shortcuts Navigation Component
4
- Purpose: Renders footer navigation shortcuts grouped by category. Displays
5
- sections of related links in multi-column layout suitable for footer placement.
6
- ================================================================================
7
-
8
- Strategic Design Logic:
9
- - Grouped navigation: categories of related links
10
- - Column layout: multi-column footer display
11
- - Filtered items: only shows items with visible_on='footer', required
12
- explicitly — an item that omits visible_on is not shown here (it defaults
13
- to navbar-visible instead, per navbar.html.liquid)
14
- - Reusable link component: consistent styling
15
- - Empty state handling: no output if no items
16
- - Category headings: uppercase section titles
17
-
18
- Required Inputs (from data objects):
19
- - navitems[]: Array with visible_on='footer'
20
-
21
- Optional Inputs (from include):
22
- - data: Shortcuts configuration object
23
-
24
- Data Source Hierarchy (in priority order):
25
- 1. include.data - Explicitly passed configuration
26
- 2. page.with_shortcut_data - Page front matter
27
- 3. site.data.shortcut - Site configuration
28
- 4. site.data.base.shortcut - Theme defaults
29
-
30
- Conditional Logic:
31
- - shortcut_navitems.size > 0: Only render if items exist
32
- - Loop through sections and their menus
33
- - Each item rendered as link via link component
34
- - Color: "light" (suitable for dark footers)
35
- ================================================================================
2
+ shortcut: renders footer-visible navitems as grouped link lists.
3
+ Data: include.data > page.with_shortcut_data > page.with_navbar_data > site.data.shortcut > site.data.navbar > site.data.base.shortcut > site.data.base.navbar
4
+ Schema: src/YAML/shortcut_schema.yml
36
5
  {% endcomment %}
37
6
 
38
7
  {%- assign with_shortcut = include.with_shortcut
@@ -48,11 +17,10 @@ Conditional Logic:
48
17
  | default: site.data.base.navbar
49
18
  %}
50
19
 
20
+ {%- comment %} Unlike navbar, an item without visible_on is not shown here; footer visibility must be explicit. {% endcomment %}
51
21
  {%- assign shortcut_navitems = with_shortcut_data.navitems | where_exp: "item", "item.visible_on contains 'footer'" %}
52
22
 
53
- {%- if with_shortcut -%}
54
-
55
- {%- comment %} === Presentation === {% endcomment %}
23
+ {%- if with_shortcut %}
56
24
  {% if shortcut_navitems.size > 0 %}
57
25
  <div class="d-flex flex-wrap justify-content-evenly mb-4">
58
26
 
@@ -61,11 +29,13 @@ Conditional Logic:
61
29
  <p class="h6">{% if section.icon %}<i class="{{ section.icon }} me-1"></i>{% endif %}{{ section.name }}</p>
62
30
  <ul class="px-0 mb-4">
63
31
  {% for item in section.menu -%}
32
+ {%- comment %} The class has no link color, so the footer's dark color mode picks it; link-underline makes the underline match the text. {% endcomment %}
64
33
  {%- assign item_link = item.link | locale_url: page.locale %}
65
34
  <li class="list-unstyled my-1">
66
35
  {% include base/link.html.liquid
67
36
  name = item.name
68
37
  link = item_link
38
+ class = "link link-offset-2 link-offset-2-hover link-underline link-underline-opacity-0 link-underline-opacity-100-hover focus-ring"
69
39
  %}
70
40
  </li>
71
41
  {% endfor %}
@@ -1,41 +1,7 @@
1
1
  {% comment %}
2
- ================================================================================
3
- Template: Social Links Component
4
- Purpose: Renders a collection of social media and external links as styled
5
- buttons with icons, with an optional preamble line introducing them.
6
- ================================================================================
7
-
8
- Design Logic:
9
- - Multi-level data source hierarchy for flexible configuration
10
- - Optional preamble text and CSS class, and an optional CSS class on the
11
- container wrapping the icon row, for full presentational customization
12
- - Link rendering via reusable link component with icon support
13
- - Icon-based visual identification for different platforms
14
- - Accessibility-first approach with proper ARIA labels
15
- - Centered layout for prominent footer or banner placement
16
-
17
- Required Fields (per item in the media array):
18
- - link: URL for the social media or external platform
19
- - icon: Icon class for Font Awesome (e.g., 'fa-brands fa-github')
20
- - name: Platform name for accessibility label (e.g., 'GitHub')
21
-
22
- Optional Inputs (from include):
23
- - data: Array of social link objects (overrides all fallbacks)
24
-
25
- Data Source Hierarchy (in priority order):
26
- 1. include.data - Explicitly passed social link array
27
- 2. page.with_social_data - Page front matter configuration
28
- 3. site.data.social - Site-specific social configuration
29
- 4. site.data.base.social - Theme default social links
30
-
31
- Conditional Logic:
32
- - Preamble <p> falls back to the schema-documented default when omitted
33
- from the resolved data source; set it explicitly to `false` or an empty
34
- string to hide it entirely — no element is emitted in its place, so the
35
- icon row's own margin reclaims the vertical space
36
- - Loops through all social links in resolved data source
37
- - Each link rendered with consistent button styling
38
- ================================================================================
2
+ social: renders an optional preamble and one icon button per social link.
3
+ Data: include.data > page.with_social_data > site.data.social > site.data.base.social
4
+ Schema: src/YAML/social_schema.yml
39
5
  {% endcomment %}
40
6
 
41
7
  {%- assign with_social = include.with_social
@@ -54,14 +20,13 @@ Conditional Logic:
54
20
  {%- assign social_preamble_class = with_social_data.preamble_class | default: with_social_schema.preamble_class.default %}
55
21
  {%- assign social_media = with_social_data.media | default: with_social_schema.media.default %}
56
22
 
23
+ {%- comment %} == nil tells an omitted preamble apart from an explicit false or "", which hides it. {% endcomment %}
57
24
  {%- assign social_preamble = with_social_data.preamble %}
58
25
  {%- if with_social_data.preamble == nil %}
59
26
  {%- assign social_preamble = with_social_schema.preamble.default %}
60
27
  {%- endif %}
61
28
 
62
29
  {% if with_social %}
63
-
64
- {%- comment %} === Presentation (Begin) === {% endcomment %}
65
30
  {%- if social_preamble and social_preamble != empty %}
66
31
  <p class="{{ social_preamble_class }}">{{ social_preamble }}</p>
67
32
  {%- endif %}
@@ -71,13 +36,10 @@ Conditional Logic:
71
36
  {%- include base/link.html.liquid
72
37
  class = "btn btn-outline-primary m-1"
73
38
  link = item.link
74
- role = "button"
75
39
  icon = item.icon
76
40
  aria_label = item.name
77
- data_bs_title = item.name
78
41
  %}
79
42
  {%- endfor %}
80
43
  </div>
81
- {%- comment %} === Presentation (End) === {% endcomment %}
82
44
 
83
45
  {% endif %}
@@ -1,69 +1,18 @@
1
1
  {% comment %}
2
- ================================================================================
3
- Template: Sponsors Cards Component
4
- Purpose: Renders sponsor logos as a horizontal row of linked cards with
5
- border styling. Suitable for inline or content-area placement.
6
- ================================================================================
7
-
8
- Strategic Design Logic:
9
- - Multi-level data source hierarchy for flexible configuration
10
- - Card-based layout for content-area or inline sponsor display
11
- - Active-flag filtering to soft-delete without data removal
12
-
13
- Required Fields (per item in the members array):
14
- - name: Sponsor display name (used as alt text)
15
- - image: Logo source — bare filename (resolved via image_base_path) or absolute URL
16
- - url: Sponsor website URL
17
-
18
- Optional Data Fields:
19
- - image_base_path: Base path for bare filenames (default: /assets/img/components/sponsors/)
20
-
21
- Optional Inputs (from include):
22
- - data: Sponsors data object (overrides all fallbacks)
23
-
24
- Data Source Hierarchy (in priority order):
25
- 1. include.data - Explicitly passed sponsors data object
26
- 2. page.with_sponsors_data - Page front matter configuration
27
- 3. site.data.sponsors - Site-specific sponsors configuration
28
- 4. site.data.base.sponsors - Theme default sponsors data
29
-
30
- Conditional Logic:
31
- - Component renders only when page.with_sponsors is true
32
- - Members filtered by is_active != false
33
- ================================================================================
2
+ sponsors-cards: renders active sponsor logos as a row of linked cards.
3
+ Schema: src/YAML/sponsors_schema.yml
34
4
  {% endcomment %}
35
5
 
36
- {%- assign with_sponsors = include.with_sponsors
37
- | default: page.with_sponsors
38
- %}
39
-
40
- {%- assign with_sponsors_data = include.data
41
- | default: page.with_sponsors_data
42
- | default: site.data.sponsors
43
- | default: site.data.base.sponsors
44
- %}
6
+ {%- include base/sponsors-data.html.liquid with_sponsors=include.with_sponsors data=include.data -%}
45
7
 
46
8
  {%- if with_sponsors -%}
47
9
 
48
- {%- assign with_sponsors_schema = site.data.base.sponsors_schema.properties.with_sponsors_data.properties %}
49
-
50
- {%- assign sponsors_members = with_sponsors_data.members | default: with_sponsors_schema.members.default -%}
51
- {%- assign sponsors_image_base = with_sponsors_data.image_base_path | default: with_sponsors_schema.image_base_path.default -%}
52
-
53
10
  <div class="d-flex flex-wrap justify-content-between py-4 my-4 border-top border-bottom border-top-1 border-bottom-1">
54
- {%- comment %} === Presentation (Begin) === {% endcomment %}
55
11
  {%- for member in sponsors_members -%}
56
12
  {%- if member.is_active != false %}
57
- <div class="card border-light m-4" style="max-height: 60px; max-width: 242px">
58
- {%- if member.image contains "://" -%}
59
- <a href="{{ member.url }}"><img src="{{ member.image }}" class="card-img-top rounded" style="max-height: 60px; max-width: 242px" alt="{{ member.name }}"></a>
60
- {%- else -%}
61
- <a href="{{ member.url }}"><img src="{{ site.baseurl }}{{ sponsors_image_base }}{{ member.image }}" class="card-img-top rounded" style="max-height: 60px; max-width: 242px" alt="{{ member.name }}"></a>
62
- {%- endif -%}
63
- </div>
13
+ <div class="card border-light m-4 sponsors-logo"><a href="{{ member.url }}"><img src="{{ sponsors_member_srcs[forloop.index0] }}" class="card-img-top rounded sponsors-logo" alt="{{ member.name }}"></a></div>
64
14
  {%- endif -%}
65
15
  {%- endfor %}
66
- {%- comment %} === Presentation (End) === {% endcomment %}
67
16
  </div>
68
17
 
69
18
  {%- endif -%}
@@ -1,67 +1,20 @@
1
1
  {% comment %}
2
- ================================================================================
3
- Template: Sponsors Carousel Component
4
- Purpose: Renders sponsor logos as a Bootstrap carousel with optional title and
5
- message. Automatically cycles through active sponsors.
6
- ================================================================================
7
-
8
- Strategic Design Logic:
9
- - Multi-level data source hierarchy for flexible configuration
10
- - Carousel display with fade transition for visual polish
11
- - Markdown-enabled message for rich introductory text
12
- - Active-flag filtering to soft-delete without data removal
13
-
14
- Required Fields (per item in the members array):
15
- - name: Sponsor display name (used as alt text)
16
- - image: Logo source — bare filename (resolved via image_base_path) or absolute URL
17
- - url: Sponsor website URL
18
-
19
- Optional Data Fields:
20
- - image_base_path: Base path for bare filenames (default: /assets/img/components/sponsors/)
21
-
22
- Optional Inputs (from include):
23
- - data: Sponsors data object (overrides all fallbacks)
24
- - id: Carousel element ID (default: "sponsorsCarousel")
25
- - with_title: Set false to suppress title/message block
26
-
27
- Data Source Hierarchy (in priority order):
28
- 1. include.data - Explicitly passed sponsors data object
29
- 2. page.with_sponsors_data - Page front matter configuration
30
- 3. site.data.sponsors - Site-specific sponsors configuration
31
- 4. site.data.base.sponsors - Theme default sponsors data
32
-
33
- Conditional Logic:
34
- - Component renders only when page.with_sponsors is true
35
- - Title/message block suppressed when include.with_title is false
36
- - Members filtered by is_active != false
37
- ================================================================================
2
+ sponsors-carousel: renders an optional title and message, active sponsor logos as a fading carousel, then an optional closing message.
3
+ Schema: src/YAML/sponsors_schema.yml
38
4
  {% endcomment %}
39
5
 
40
- {%- assign with_sponsors = include.with_sponsors
41
- | default: page.with_sponsors
42
- %}
43
-
44
- {%- assign with_sponsors_data = include.data
45
- | default: page.with_sponsors_data
46
- | default: site.data.sponsors
47
- | default: site.data.base.sponsors
48
- %}
6
+ {%- include base/sponsors-data.html.liquid with_sponsors=include.with_sponsors data=include.data -%}
49
7
 
50
8
  {%- if with_sponsors -%}
51
9
 
52
- {%- assign with_sponsors_schema = site.data.base.sponsors_schema.properties.with_sponsors_data.properties %}
53
-
54
10
  {%- assign sponsors_title = with_sponsors_data.title | default: with_sponsors_schema.title.default -%}
55
11
  {%- assign sponsors_icon = with_sponsors_data.icon | default: with_sponsors_schema.icon.default -%}
56
12
  {%- assign sponsors_message = with_sponsors_data.message | default: with_sponsors_schema.message.default -%}
57
- {%- assign sponsors_members = with_sponsors_data.members | default: with_sponsors_schema.members.default -%}
58
- {%- assign sponsors_image_base = with_sponsors_data.image_base_path | default: with_sponsors_schema.image_base_path.default -%}
13
+ {%- assign sponsors_closing_message = with_sponsors_data.closing_message | default: with_sponsors_schema.closing_message.default -%}
59
14
 
60
15
  {%- assign carousel_id = include.id | default: "sponsorsCarousel" -%}
61
16
 
62
17
  <div id="{{ carousel_id }}" class="d-flex flex-wrap mb-5">
63
-
64
- {%- comment %} === Presentation (Begin) === {% endcomment %}
65
18
  {%- if include.with_title != false %}
66
19
  <p class="h6"><i class="{{ sponsors_icon }}"></i> {{ sponsors_title }}</p>
67
20
  {{ sponsors_message | markdownify | decorate_links }}
@@ -72,19 +25,18 @@ Conditional Logic:
72
25
  {%- for member in sponsors_members -%}
73
26
  {%- if member.is_active != false %}
74
27
  <div class="carousel-item{% if forloop.first %} active{% endif %}">
75
- <div class="w-100 align-middle" style="height: 80px; width: 262px">
76
- {%- if member.image contains "://" -%}
77
- <a href="{{ member.url }}"><img src="{{ member.image }}" class="rounded" style="max-height: 60px; max-width: 242px" alt="{{ member.name }}"></a>
78
- {%- else -%}
79
- <a href="{{ member.url }}"><img src="{{ site.baseurl }}{{ sponsors_image_base }}{{ member.image }}" class="rounded" style="max-height: 60px; max-width: 242px" alt="{{ member.name }}"></a>
80
- {%- endif -%}
81
- </div>
28
+ <div class="sponsors-carousel-slide"><a href="{{ member.url }}"><img src="{{ sponsors_member_srcs[forloop.index0] }}" class="rounded sponsors-logo" alt="{{ member.name }}"></a></div>
82
29
  </div>
83
30
  {%- endif -%}
84
31
  {%- endfor %}
85
32
  </div>
86
33
  </div>
87
- {%- comment %} === Presentation (End) === {% endcomment %}
34
+
35
+ {%- if sponsors_closing_message != "" %}
36
+ <div class="w-100">
37
+ {{ sponsors_closing_message | markdownify | decorate_links }}
38
+ </div>
39
+ {%- endif %}
88
40
 
89
41
  </div>
90
42